Loading

Spring Security5使用

概述

SpringSecurity 是基于 Spring AOP 和 Servlet 过滤器的安全框架,提供全面的安全性解决方案。

Spring Security核心功能包括 用户认证(Authentication) 、用户授权(Authorization) 和 攻击防护 3 个部分:

  • 用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程
  • 用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限
  • 攻击防护即防止伪造身份

基本配置

1、添加依赖

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-security</artifactId>
</dependency>

2、web安全配置

通过重写WebSecurityConfigurerAdapter抽象类,并使用@EnableWebSecurity注解标注,进行web安全配置

WebSecurityConfigurerAdapter抽象类有3个重载方法:

protected void configure(AuthenticationManagerBuilder auth) throws Exception方法同认证相关,比如验证用户的账号密码

protected void configure(HttpSecurity http) throws Exception方法同授权相关,配置资源(URL)访问权限

public void configure(WebSecurity web) throws Exception主要用户全局请求忽略规则配置、HttpFirewall配置、debug配置、全局SecurityFilterChain配置

内存认证

Spring Security5.x默认BCrypt加密,加密后的格式为“{加密编码}加密后的密码”

下述代码是明文密码实现方式:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
   @Override
   protected void configure(AuthenticationManagerBuilder auth) throws Exception {
   	// 明文密码
       auth.inMemoryAuthentication().withUser("user").password("{noop}123456").roles();
   }
}

BCrypt加密:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 明文密码
        //auth.inMemoryAuthentication().withUser("user").password("{noop}123456").roles();
        auth.inMemoryAuthentication().withUser("admin").password(passwordEncoder().encode("123456")).roles();
    }


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

数据库认证

当Spring Security处理认证时,前台提交的账号密码会被封装为Authentication对象,并与UserDetails对象比较。

UserDetails对象储存用户正确的认证信息,该对象通过UserDetailsService接口的loadUserByUsername方法加载相关信息

如果用户密码储存在数据库,则要实现UserDetailsService接口:

@Service
public class CustomUserDetailService implements UserDetailsService {
    @Autowired
    private UserInfoService userInfoService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserInfo userInfo = userInfoService.findByUsername(username);
        if (userInfo == null) {
            throw new UsernameNotFoundException("not found");
        }

        // 定义权限列表
        List<GrantedAuthority> authorities = new ArrayList<>();
        // 用户所拥有的权限 必须以 ROLE_ 开头
        authorities.add(new SimpleGrantedAuthority("ROLE_" + userInfo.getRole()));

        
        User userDetails = new User(userInfo.getUsername(), userInfo.getPassword(), authorities);
        return userDetails;
    }
}
posted @ 2020-12-11 21:11  未夏  阅读(2426)  评论(0编辑  收藏  举报