Spring security Jwt 承载令牌编码/解码错误

问题描述 投票:0回答:1

当尝试验证用户的 jwt 不记名令牌时,我收到 403 错误,并且标头告诉我我的令牌范围不足。我想知道在对范围进行编码的过程中哪里出了问题,或者如果我解码令牌的方式不正确。

安全配置

@Configuration
public class SecurityConfiguration {
    private final RSAKeyConfig keys;
    public SecurityConfiguration(RSAKeyConfig keys) {
        this.keys = keys;
    }
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    @Bean
    public AuthenticationManager authManager(UserDetailsService detailsService) {
        DaoAuthenticationProvider daoProvider = new DaoAuthenticationProvider();
        daoProvider.setUserDetailsService(detailsService);
        daoProvider.setPasswordEncoder(passwordEncoder());
        return new ProviderManager(daoProvider);
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                .csrf(csrf -> csrf.disable())
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/auth/**").permitAll()
                        .requestMatchers("/admin/**").hasRole("ADMIN")
                        .requestMatchers("/user/**").hasAnyRole("ADMIN", "USER")
                        .anyRequest().authenticated());



        http
                .oauth2ResourceServer(oauth2 -> oauth2
                        .jwt(jwt -> jwt.jwtAuthenticationConverter(jwtConverter())));


        http
                .sessionManagement(session -> session
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS));



        return http.build();


    }

    @Bean
    public JwtDecoder jwtDecoder() {
        System.out.print("decoder");
        return NimbusJwtDecoder.withPublicKey(keys.getPublicKey()).build();
    }

    @Bean
    public JwtEncoder jwtEncoder() {
        JWK jwk = new RSAKey.Builder(keys.getPublicKey())
                .privateKey(keys.getPrivateKey()).build();
        JWKSource<SecurityContext> jwks = new ImmutableJWKSet<>(new JWKSet(jwk));

        return new NimbusJwtEncoder(jwks);

    }

    @Bean
    public JwtAuthenticationConverter jwtConverter() {
        System.out.println("jwt converter");
        JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
        jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName("roles");
        jwtGrantedAuthoritiesConverter.setAuthorityPrefix("Roles_");
        JwtAuthenticationConverter jwtconverter = new JwtAuthenticationConverter();
        jwtconverter.setJwtGrantedAuthoritiesConverter(jwtGrantedAuthoritiesConverter);

        return jwtconverter;

    }


}

代币服务

@Service
public class TokenService {

    @Autowired
    private JwtEncoder jwtEncoder;

    @Autowired
    private JwtDecoder jwtDecoder;

    public String generateJwt(Authentication auth) {

        Instant now = Instant.now();

        String scope = auth.getAuthorities().stream()
                .map(GrantedAuthority::getAuthority)
                .collect(Collectors.joining(" "));

        JwtClaimsSet claims = JwtClaimsSet.builder()
                .issuer("self")
                .issuedAt(now)
                .subject(auth.getName())
                .claim("roles", scope)
                .build();

        System.out.print(claims);

        return jwtEncoder.encode(JwtEncoderParameters.from(claims))
.getTokenValue();

    }
}

按键配置

@Component
@Data
public class RSAKeyConfig {

    private RSAPublicKey publicKey;

    private RSAPrivateKey privateKey;

    public RSAKeyConfig(){
        KeyPair pair = KeyGenerator.generateRsaKey();
        this.publicKey = (RSAPublicKey) pair.getPublic();
        this.privateKey = (RSAPrivateKey) pair.getPrivate();
    }
}

密钥生成器

public class KeyGenerator {

    public static KeyPair generateRsaKey(){


        KeyPair keyPair;

        try{
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(2048);
            keyPair = keyPairGenerator.generateKeyPair();
        }catch(Exception e){
            throw new IllegalStateException();
        }

        return keyPair;

    }
}

我尝试过修改安全过滤器链,但这似乎是徒劳的。 我使用的相关依赖项 1 2

java spring spring-security jwt bearer-token
1个回答
0
投票

据我所知,您的 JWT 已定义范围,而不是角色 - 授权过程期望进行范围检查(作为权限),而不是角色检查?

.requestMatchers("/admin/**").hasRole("ADMIN")

尝试将此行更改为:

.requestMatchers("/admin/**").hasAuthority("SCOPE_ADMIN")
© www.soinside.com 2019 - 2024. All rights reserved.