spring-security 简单纪要

1.配置访问安全规则

  1. 创建WebSecurityConfigurerAdapter 继承类,并注入
    org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
  2. 创建ResourceServerConfigurerAdapter继承类,并注入
    org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter
  3. 两者的对比总结
    WebSecurityConfigurerAdapter 和 ResourceServerConfigurerAdapter 是 Spring Security 中用于配置安全规则的两个核心类,但它们的应用场景和功能有本质区别。以下是两者的对比总结
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述
  4. 新版本中的替代方案
    从 Spring Security 5.x 开始,两者均被弃用,推荐使用 SecurityFilterChain 进行配置:
    (1) 替代 WebSecurityConfigurerAdapter
@Configuration
public class WebSecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeHttpRequests(authorize -> authorize
                .requestMatchers("/login", "/css/**").permitAll()
                .anyRequest().authenticated()
            )
            .formLogin(form -> form
                .loginPage("/login")
                .defaultSuccessUrl("/home")
            );
        return http.build();
    }
}

(2) 替代 ResourceServerConfigurerAdapter

@Configuration
public class ResourceServerConfig {

    @Bean
    public SecurityFilterChain resourceServerFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeHttpRequests(authorize -> authorize
                .requestMatchers("/api/public/**").permitAll()
                .requestMatchers("/api/admin/**").hasAuthority("ROLE_ADMIN")
                .anyRequest().authenticated()
            )
            .oauth2ResourceServer(oauth2 -> oauth2
                .jwt(jwt -> jwt.decoder(jwtDecoder()))  // 使用 JWT 验证
            );
        return http.build();
    }

    @Bean
    public JwtDecoder jwtDecoder() {
        return NimbusJwtDecoder.withJwkSetUri("http://auth-server/.well-known/jwks.json").build();
    }
}
  1. 如何选择?
    在这里插入图片描述

2.用户信息处理

包括用户名密码、用户角色权限等

  1. 实现UserDetailsService接口,注入类UserDetailsService
    实现用户信息的查找方法,根据系统业务进行封装对象,主要包括:用户名、密码、权限集合等
  2. 新增和修改用户信息业务实现
    2.1 实现密码编码类
     @Bean
    public PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }

2.2 用户信息编辑的时候,密码先进行加密,然后保存

	sysUser.setPassword(ENCODER.encode(userDto.getNewPassword()));

	this.baseMapper.insert(sysUser);
  1. 用户登录校验

3.1 登录uri
String OAUTH_TOKEN_URL = “/oauth/token”;
3.2 校验前,前端输入的密码处理
一般前端会对密码加密处理,这里要先对应解密

decrypt(String pwd, String passKey)

3.3 创建AuthorizationServerConfigurerAdapter 继承类,并注入
org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter
a.自定义token返回对象属性,例如,用户详细信息

 @Bean
    public TokenEnhancer tokenEnhancer() {
        return (accessToken, authentication) -> {
            final Map<String, Object> additionalInfo = new HashMap<>(4);
            additionalInfo.put(SecurityConstants.DETAILS_LICENSE, SecurityConstants.PROJECT_LICENSE);
            String clientId = authentication.getOAuth2Request().getClientId();
            additionalInfo.put(SecurityConstants.CLIENT_ID, clientId);

            // 客户端模式不返回具体用户信息
            if (SecurityConstants.CLIENT_CREDENTIALS.equals(authentication.getOAuth2Request().getGrantType())) {
                ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
                return accessToken;
            }

            UserDetails user = (UserDetails) authentication.getUserAuthentication().getPrincipal();
            additionalInfo.put(SecurityConstants.DETAILS_USER, user);
            ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
            return accessToken;
        };
    }

b.可以将token放入缓存

private final RedisConnectionFactory redisConnectionFactory;
		
	    @Bean
    public TokenStore tokenStore() {
        RedisTokenStore tokenStore = new RedisTokenStore(redisConnectionFactory);
        tokenStore.setPrefix( "sys_oauth:access:");
        return tokenStore;
    }

3.4 添加UserDetailsService类引用

3.5 这样,在登录的时候,就会从数据库里查询数据,进行用户信息密码校验,校验成功,就会返回token,供业务调用处理

3.6 校验失败,可以针对异常进行自定义返回的数据格式,实现接口org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator

  1. 获取当前登录用户信息
    public static ActualUser getCurrentUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Object principal = authentication.getPrincipal();
        return principal instanceof ActualUser ? (ActualUser) principal : null;);
    }
    	
    public static List<String> getRoles() {
        Authentication authentication = getAuthentication();
        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        List<String> roleIds = new ArrayList();
        authorities.stream().filter((granted) -> {
            return StrUtil.startWith(granted.getAuthority(), "ROLE_");
        }).forEach((granted) -> {
            String id = StrUtil.removePrefix(granted.getAuthority(), "ROLE_");
            roleIds.add(id);
        });
        return roleIds;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值