Spring过滤器将角色添加到来自令牌的请求

Posted

技术标签:

【中文标题】Spring过滤器将角色添加到来自令牌的请求【英文标题】:Spring Filter to add roles to a request from token 【发布时间】:2017-11-12 02:40:06 【问题描述】:

我正在寻找添加基于角色的身份验证的正确方法,我从 JWT 中提取角色。

理想情况下,我想在进行身份验证后从 JWT 中提取角色。这将通过检查 Web 令牌中与我们从身份验证系统 keycloak 获得的角色相关的一些字段来工作。

我的问题是:是否可以将角色附加到请求中,然后使用 http 配置来要求这些提取的角色之一?

下面是一些相关的代码,可以帮助解释我在做什么。

在我的WebSecurityConfigurer 中,我使访问令牌可用,按请求限定。

@Bean
@Scope(scopeName = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public AccessToken accessToken() 
    try 
        HttpServletRequest request =
            ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
                .getRequest();
        return ((KeycloakSecurityContext) ((KeycloakAuthenticationToken) request
            .getUserPrincipal())
            .getCredentials()).getToken();
     catch (Exception exc) 
        return null;
    

然后我覆盖了configure方法中http的一些配置。

http
// Disable session management
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
// Allow calls to OPTIONS
.authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.and()
// Authenticate every other call
.authorizeRequests().anyRequest().authenticated()
.and()
.csrf().disable();

理想情况下,我想要实现的是:

http.antMatchers("/foo").hasRole("jwt_extracted_role")

我目前正在创建自定义过滤器,从令牌中提取角色,然后检查正确的角色,但这可能比它需要的更麻烦。

关于我应该覆盖哪些配置类的哪些方法以从请求中提取角色并将它们添加到请求中的任何指针?

【问题讨论】:

【参考方案1】:

我最终通过覆盖 KeycloakAuthenticationProvider 并将我的覆盖类作为 WebSecurityConfig 中的 bean 来解决这个问题。我的课在下面:

public class ResourceAwareAuthenticationProvider extends KeycloakAuthenticationProvider 
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException 
          ... here I add granted authorities from the token's credentials ...
    

然后在我的class WebSecurityConfigurer extends KeycloakWebSecurityConfigurerAdapter 中覆盖 AuthenticationProvider:

@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception 
    return new ProviderManager(Lists.newArrayList(new ResourceAwareAuthenticationProvider()));

这允许我进行如下配置:

http.authorizeRequests()
    .antMatchers("/**").hasAuthority("my-resource-authority")

【讨论】:

出于好奇,您错过了 Keycloak Spring Security Adapter 的哪些内容?开箱即用你已经可以做到.antMatchers("/products*").hasRole("user") Spring 抢到的角色不完整。在我的ResourceAwareAuthenticationProvider 课程中,我添加了比框架提供的更多的角色。

以上是关于Spring过滤器将角色添加到来自令牌的请求的主要内容,如果未能解决你的问题,请参考以下文章

Spring oauth2令牌请求中未实际使用的基本身份验证过滤器和身份验证入口点

spring security CORS 过滤器允许没有“Origin”标头的请求

使用 Java Config 的 Spring Security 自定义身份验证过滤器

每个响应中的 CSRF Token

为啥这个基于令牌的 Spring Security 过滤器没有被调用?

如何在所有请求标头中传递授权令牌 - Spring Boot java