当前位置: 首页 > 知识库问答 >
问题:

基于JWT索赔的Spring Security 5填充权限

昌勇锐
2023-03-14

正如我所看到的,Spring Security OAuth2.x项目被移到了Spring Security 5.2.x。我尝试用一种新的方式来实现授权和资源服务器。Everythin工作正常,除了一件事--@preauthorize注释。当我尝试将其与标准@preauthorize(“hasrole('role_user')”)一起使用时,我总是被禁止。我看到的是principal对象的类型为org.springframework.security.oauth2.jwt.jwt不能解析权限,我不知道为什么。

org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken@44915f5f: Principal: org.springframework.security.oauth2.jwt.Jwt@2cfdbd3; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@ffffa64e: RemoteIpAddress: 172.19.0.1; SessionId: null; Granted Authorities: SCOPE_read, SCOPE_write

并在将其强制转换为jwt后声明

{user_name=user, scope=["read","write"], exp=2019-12-18T13:19:29Z, iat=2019-12-18T13:19:28Z, authorities=["ROLE_USER","READ_ONLY"], client_id=sampleClientId}
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

  @Autowired
  private DataSource dataSource;

  @Autowired
  private AuthenticationManager authenticationManager;

  @Bean
  public KeyPair keyPair() {
    ClassPathResource ksFile = new ClassPathResource("mytest.jks");
    KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(ksFile, "mypass".toCharArray());
    return keyStoreKeyFactory.getKeyPair("mytest");
  }

  @Bean
  public JwtAccessTokenConverter accessTokenConverter() {
    JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
    converter.setKeyPair(keyPair());
    return converter;
  }

  @Bean
  public JWKSet jwkSet() {
    RSAKey key = new Builder((RSAPublicKey) keyPair().getPublic()).build();
    return new JWKSet(key);
  }

  @Bean
  public TokenStore tokenStore() {
    return new JwtTokenStore(accessTokenConverter());
  }

  @Override
  public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    clients.jdbc(dataSource);
  }

  @Override
  public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
    endpoints.tokenStore(tokenStore())
        .accessTokenConverter(accessTokenConverter())
        .authenticationManager(authenticationManager);
  }

  @Override
  public void configure(AuthorizationServerSecurityConfigurer security) {
    security.tokenKeyAccess("permitAll()")
        .checkTokenAccess("isAuthenticated()");
  }
}

@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

  private UserDetailsService userDetailsService;

  public SecurityConfiguration(UserDetailsService userDetailsService) {
    this.userDetailsService = userDetailsService;
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
            .mvcMatchers("/.well-known/jwks.json")
            .permitAll()
            .anyRequest()
            .authenticated();
  }

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

  @Bean
  @Override
  public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
  }

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
  }
}

资源服务器配置

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ResuorceServerConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .oauth2ResourceServer()
                .jwt();
    }
}

也许有人也有类似的问题?

共有1个答案

仲君昊
2023-03-14

默认情况下,资源服务器根据“scope”声明填充权限。
如果JWT包含名称为“scope”“scp”的声明,则Spring Security将使用该声明中的值通过在每个值前缀“scope_”来构造权限。

在您的示例中,其中一个声明是scope=[“read”,“write”]
这意味着授权列表将由“scope_read”“scope_write”组成。

通过在安全配置中提供自定义身份验证转换器,可以修改默认权限映射行为。

http
    .authorizeRequests()
        .anyRequest().authenticated()
        .and()
    .oauth2ResourceServer()
        .jwt()
            .jwtAuthenticationConverter(getJwtAuthenticationConverter());

然后,在GetJWTAuthEnticationConverter的实现中,您可以配置JWT如何映射到权限列表。

Converter<Jwt, AbstractAuthenticationToken> getJwtAuthenticationConverter() {
    JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
    converter.setJwtGrantedAuthoritiesConverter(jwt -> {
        // custom logic
    });
    return converter;
}
 类似资料:
  • 我有一个数据网格,其中组合框是从Db填充的。 我试图实现的是,当我在“Esercizio”列中选择一些内容时,“Video”列的单元格会自动填充Db的“link_video”列中的相应值。 因此,如果我选择“回扣”,我需要在文本框单元格中看到来自db的回扣链接视频。 这是我用来在表单加载时填充组合框的代码: private void Myform_Load(对象发送方,EventArgs e) {

  • 本文向大家介绍基于jQuery的表单填充实例,包括了基于jQuery的表单填充实例的使用技巧和注意事项,需要的朋友参考一下 如下所示: 以上这篇基于jQuery的表单填充实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持呐喊教程。

  • 我有以下服务器.js获取路由 这是我的客户端js,我用jQuery获取完全相同的get 当我打开index.html时,它会正确显示用户交互界面,并在我的终端中执行我的server.js它会正确显示url。我无法完成的是如何使用我的jQuery接收到的数据来填充我的html中的表。我的表将填充从我的endpoint获取的url。 我有一些nodejs的背景,但我不能总结这个。

  • 根据和的公共列在中使用填充列的最佳方法是什么? 得到: 编辑:我还想将列名更改为,这样预期的输出如下所示: 尝试过: 它发现了错误: 更新2: : :

  • 如何创建包含以下值f(0),f(1),…,f(N-1)的const std::数组,其中f是任何函数:静态constexpr size_t f(int index)?当我确切地知道N时,我显然可以写

  • 我有以下问题,因为我是pyspark的新手。基于来自两列的值的条件,我想填充第三列。条件是: < li >如果分号包含在col2中,请检查col1 < ul > < li >如果col1 == 1,则取分号前的值 < li >如果col1 == 2,则取分号后的值 这就是数据帧的样子。 我创建了下面的udf,它给出了错误“不能将列转换为布尔值:请使用” 我通过谷歌搜索各种功能构建了这个udf,所以