SpringSecurity(三)认证

基于内存验证

首先我们来看看最简单的基于内存的配置,也就是说我们直接以代码的形式配置我们网站的用户和密码,配置方式非常简单,只需要在Security配置类中注册一个Bean即可:

```Plain Text @Configuration @EnableWebSecurity public class SecurityConfiguration {

@Bean   //UserDetailsService就是获取用户信息的服务
public UserDetailsService userDetailsService() {
      //每一个UserDetails就代表一个用户信息,其中包含用户的用户名和密码以及角色
    UserDetails user = User.withDefaultPasswordEncoder()
            .username("user")
            .password("password")
            .roles("USER")  //角色目前我们不需要关心,随便写就行,后面会专门讲解
            .build();
    UserDetails admin = User.withDefaultPasswordEncoder()
            .username("admin")
            .password("password")
            .roles("ADMIN", "USER")
            .build();
    return new InMemoryUserDetailsManager(user, admin); 
      //创建一个基于内存的用户信息管理器作为UserDetailsService
}

}

在配置用户信息的时候,可以使用官方提供的BCrypt加密工具:

Java @Configuration @EnableWebSecurity public class SecurityConfiguration {

  //这里将BCryptPasswordEncoder直接注册为Bean,Security会自动进行选择
@Bean
public PasswordEncoder passwordEncoder(){
    return new BCryptPasswordEncoder();
}

@Bean
public UserDetailsService userDetailsService(PasswordEncoder encoder) {
    UserDetails user = User
            .withUsername("user")
            .password(encoder.encode("password"))   //这里将密码进行加密后存储
            .roles("USER")
            .build();
      System.out.println(encoder.encode("password"));  //一会观察一下加密出来之后的密码长啥样
    UserDetails admin = User
            .withUsername("admin")
            .password(encoder.encode("password"))   //这里将密码进行加密后存储
            .roles("ADMIN", "USER")
            .build();
    return new InMemoryUserDetailsManager(user, admin);
}

}

此时会报错403,因为SpringSecurity自带了csrf防护,需求我们在POST请求中携带页面中的csrfToken才可以,否则一律进行拦截操作,这里我们可以将其嵌入到页面中,随便找一个地方添加以下内容:

Plain Text

接着在axios发起请求时,携带这个input的value值:

Plain Text function pay() { const account = document.getElementById("account").value const csrf = document.getElementById("_csrf").value axios.post('/mvc/pay', { account: account, _csrf: csrf //携带此信息即可,否则会被拦截 }, { …

---

## 基于数据库验证

官方默认提供了可以直接使用的用户和权限表设计,根本不需要我们来建表,直接在Navicat中执行以下查询:

Plain Text create table users(username varchar(50) not null primary key,password varchar(500) not null,enabled boolean not null); create table authorities (username varchar(50) not null,authority varchar(50) not null,constraint fkauthoritiesusers foreign key(username) references users(username)); create unique index ixauthusername on authorities (username,authority);

配置类中设置数据源和加密:

Java @Configuration @EnableWebSecurity public class SecurityConfiguration {

@Bean PasswordEncoder passwordEncoder(){
    return new BCryptPasswordEncoder();
}

@Bean
public DataSource dataSource(){
      //数据源配置
    return new PooledDataSource("com.mysql.cj.jdbc.Driver",
            "jdbc:mysql://localhost:3306/test", "root", "123456");
}

@Bean
public UserDetailsService userDetailsService(DataSource dataSource,
                                             PasswordEncoder encoder) {
    JdbcUserDetailsManager manager = new JdbcUserDetailsManager(dataSource);
      //仅首次启动时创建一个新的用户用于测试,后续无需创建
           manager.createUser(User.withUsername("user")
                  .password(encoder.encode("password")).roles("USER").build());
    return manager;
}

}

---

## 自定义验证

既然需要自定义,那么我们就需要自行实现UserDetailsService或是功能更完善的UserDetailsManager接口,这里为了简单,我们直接选择前者进行实现:

Java @Service public class AuthorizeService implements UserDetailsService {

@Resource
UserMapper mapper;

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    Account account = mapper.findUserByName(username);
    if(account == null)
        throw new UsernameNotFoundException("用户名或密码错误");
    return User
            .withUsername(username)
            .password(account.getPassword())
            .build();
}

} ```


其他配置

自定义登陆界面

在编写项目过程中发现有302的情况,一定要先检查是否因为没有放行导致被SpringSecurity给拦截了。

记住我功能

也就是说我们可以在登陆之后的一段时间内,无需再次输入账号和密码进行登陆,相当于服务端已经记住当前用户,再次访问时就可以免登陆进入,这是一个非常常用的功能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

湿物男

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值