自学内容网 自学内容网

Spring Security添加权限认证

刚刚开通了一个公众号,会分享一些技术博客和自己觉得比较好的项目,同时会更新一些自己使用的工具和图书资料,后面会整理一些面试资料进行分享,觉得有兴趣的可以关注一下。
在这里插入图片描述


前言

最近开发的新需求中需要给前端的权限做验证,由于项目中统一引用的spring security,那么直接使用就好了。


问题

1.权限的配置是统一的,权限的配置不是使用的spring security提供的方式,而是结合了oauth2jwt的方式,解析到用户名之后再发送请求获取的。

2.azure提供的jwttoken解析的用户名不是我们需要的,而是azure生成的自己系统的用户id

解决

1.先看第二个问题,比较简单

经过debug发现,解析用户名的其实是JwtAuthenticationConverter,查看其方法,他默认是将sub作为了用户名。具体代码如下:

private String principalClaimName = JwtClaimNames.SUB;

@Override
public final AbstractAuthenticationToken convert(Jwt jwt) {
Collection<GrantedAuthority> authorities = extractAuthorities(jwt);

String principalClaimValue = jwt.getClaimAsString(this.principalClaimName);
return new JwtAuthenticationToken(jwt, authorities, principalClaimValue);
}

那么需要找到这个bean是怎么配置的,设置一下这个principalClaimName 就OK了。

这个是在OAuth2ResourceServerConfigurer里面配置的,他先看容器里面有没有,没有的话自己new一个。具体代码如下:

Converter<Jwt, ? extends AbstractAuthenticationToken> getJwtAuthenticationConverter() {
if (this.jwtAuthenticationConverter == null) {
if (this.context.getBeanNamesForType(JwtAuthenticationConverter.class).length > 0) {
this.jwtAuthenticationConverter = this.context.getBean(JwtAuthenticationConverter.class);
}
else {
this.jwtAuthenticationConverter = new JwtAuthenticationConverter();
}
}
return this.jwtAuthenticationConverter;
}

那就简单了,直接生命一个Bean放容器里就好了。

@Bean
    public JwtAuthenticationConverter jwtAuthenticationConverter() {
        JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
        converter.setPrincipalClaimName("username");
        return converter;
    }

2.再来看第一个问题

一般来说,权限信息不会变更那么频繁,也不可能每次请求我都去重新查一下权限,那么就必须缓存下来,能增加请求速度。
但是由于这是jwtspring security,仅缓存时不够的,必须写入spring security认证的数据当中。就是JwtAuthenticationToken。请求还得存储,本来想的是通过一个请求,在service中存储并写权限,那这样的话请求其他接口就不会生效,
所以必须放在spring security的请求链里面。

配置如下:

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http, WebSecurityResponseExceptionHandler webSecurityResponseExceptionHandler) throws Exception {
        http
                .exceptionHandling()
                .authenticationEntryPoint(webSecurityResponseExceptionHandler).accessDeniedHandler(webSecurityResponseExceptionHandler)
                .and()
                .anyRequest().authenticated().and().sessionManagement()
                .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
                .addFilterAfter(new PermissionProviderFilter(), BearerTokenAuthenticationFilter.class);
        return http.build();
    }

filter代码如下,其实就是照着葫芦画瓢:

    private class PermissionProviderFilter implements Filter {
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            String requestURI = ((HttpServletRequest) request).getRequestURI();
            if (requestURI.startsWith(CConstant.API_BACKEND_URL)) {
                chain.doFilter(request, response);
                return;
            }
            JwtAuthenticationToken oldAuthentication= (JwtAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
            if (Objects.isNull(oldAuthentication)) {
                chain.doFilter(request, response);
                return;
            }
            String username = ((Jwt) oldAuthentication.getPrincipal()).getClaim("username");

            List<GrantedAuthority> authorities = CacheUtils.getCache(username);
            if (Objects.isNull(authorities)) {
                List<GrantedAuthority> authorities = userService.userDetail(username);
                CacheUtils.setCache(username, authorities);
            }
            JwtAuthenticationToken jwtAuthenticationToken = new JwtAuthenticationToken(oldAuthentication.getToken(), authorities, username);
            jwtAuthenticationToken.setDetails(oldAuthentication.getDetails());
            jwtAuthenticationToken.eraseCredentials();
            SecurityContextHolder.getContext().setAuthentication(jwtAuthenticationToken);
            chain.doFilter(request, response);
        }
    }

打完收工!


原文地址:https://blog.csdn.net/qq_37759895/article/details/140607892

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!