天天看点

SpringSecurity安全框架学习二、用户认证

作者:想要瘦下去的老胖墩

自定义登录的用户名密码

第一种方式:通过配置文件application.properties设置

spring.security.user.name=superadmin

spring.security.user.password=superadmin

第二种方式:通过配置类

新建配置类SecurityConfig继承WebSecurityConfigurerAdapter重写configure(AuthenticationManagerBuilder auth)方法在里面进行账户密码角色的设置

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String password = bCryptPasswordEncoder.encode("123456");
        auth.inMemoryAuthentication().withUser("superadmin").password(password).roles("admin");
    }
    @Bean
    PasswordEncoder password(){
        return new BCryptPasswordEncoder();
    }
}           

另外要提的一点是WebSecurityConfigurerAdapter类在5.7版本被@Deprecated所标记了

第三种方式:自定义编写实现类,实现UserDetailsService接口,将用户认证提取到业务层进一步实现个性化

第一步 创建配置类,设置使用哪个userDetailsService实现类

@Configuration
public class SecurityConfigTest extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
      auth.userDetailsService(userDetailsService).passwordEncoder(password());
    }
    

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

第二步 编写实现类,返回User对象,User对象有用户名密码和操作权限

@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("role");

        return new User("admin",new BCryptPasswordEncoder().encode("123456"),auths);
    }
}           

运行登录验证没问题

查询数据库完成认证

进一步抽离,将用户信息存储到数据库中,更符合实际应用,例子使用了mybatis-plus

第一步 准备库表,基础类

CREATE TABLE users (

id int NOT NULL,

username varchar(45) DEFAULT NULL,

password varchar(45) DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert into security_demo.users values(1,'admin','123456');

@Data
@TableName("users")
public class UsersEntity {
    private Integer id;
    private String username;
    private String password;
}           
@Repository
public interface UsersMapper extends BaseMapper<UsersEntity> {

}           

第二步 实现登录验证

在loadUserByUsername方法中编写登录验证过程

@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {
    @Autowired
    private UsersMapper usersMapper;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        QueryWrapper<UsersEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("username",username);
        wrapper.last(" limit 1");
        UsersEntity user =  usersMapper.selectOne(wrapper);
        if(user ==null || user.getId() == null){
            throw new UsernameNotFoundException("用户名或密码错误");
        }

        List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("role");

        return new User("admin",new BCryptPasswordEncoder().encode("123456"),auths);
    }


}           

验证,使用数据库中的数据可以登录

自定义登录页面

在配置类SecurityConfigTest重写protected void configure(HttpSecurity http)方法实现相关配置

@Override
protected void configure(HttpSecurity http) throws Exception {

    http.formLogin()
            //登录页面设置
            .loginPage("/login.html")
            //登录访问路径
            .loginProcessingUrl("/user/login")
            //登录成功后跳转的页面
            .defaultSuccessUrl("/test/index").permitAll()
            //设置白名单
            .and().authorizeRequests()
            .antMatchers("/test/hello","/user/login").permitAll()
            //关闭ssrf防护
            .anyRequest().authenticated()
            .and().csrf().disable();

}           

编写配置类中相关页面与接口

在resources.static文件夹中创建login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/user/login" method="post">
    用户名:<input type="text" name="username">
    <br/>
    密  码:<input type="text" name="password">
    <br/>
    <input type="submit" value="login">
</form>
</body>
</html>           

TestController中添加index方法

@RestController
@RequestMapping("/test")
public class TestController {

    @GetMapping("/hello")
    public String hello(){
        return "hello";
    }

    @GetMapping("/index")
    public String index(){
        return "index";
    }

}           

运行跳转页面,登录功能正常

SpringSecurity安全框架学习二、用户认证

继续阅读