SpringSecurity使用JWT

9w11ddsr  于 12个月前  发布在  Spring
关注(0)|答案(1)|浏览(183)

我正在使用Java,Spring,SpringBoot,Spring-Webflux开发一个应用程序。该应用程序有一个REST接口,我想使用提供的JWT令牌来验证用户。我不太擅长安全性,但我已经设法使用以下代码片段使其工作。

public class WebSecurityConfig {
    @Getter
    @Setter
    private List<String> claimRoles; //from properties

    @Bean
    public SecurityWebFilterChain filterChain(final ServerHttpSecurity http, ReactiveAuthenticationManager am) {
        return http
                .cors(Customizer.withDefaults())
                .httpBasic(ServerHttpSecurity.HttpBasicSpec::disable)
                .formLogin(ServerHttpSecurity.FormLoginSpec::disable)
                .csrf(ServerHttpSecurity.CsrfSpec::disable)
                .authenticationManager(am)
                .securityContextRepository(tt(am))
                .authorizeExchange(e -> {
                    e.pathMatchers("/api/v3/protected/**").hasAuthority("MY_CLAIMS")
                            .pathMatchers("/api/**").permitAll()
                            .pathMatchers("/docs/**").permitAll()
                            .pathMatchers("/actuator/**").permitAll();
                })
                .oauth2ResourceServer(oauth2ResourceServer -> oauth2ResourceServer.jwt(
                                jwt -> jwt.jwtAuthenticationConverter(getJwtAuthenticationConverter())))
                .build();
    }

    private Converter<Jwt, ? extends Mono<? extends AbstractAuthenticationToken>> getJwtAuthenticationConverter() {
        final ReactiveJwtAuthenticationConverter jwtAuthenticationConverter = new ReactiveJwtAuthenticationConverter();
        final Converter<Jwt, Flux<GrantedAuthority>> jwtGrantedAuthoritiesConverterAdapter =
                new ReactiveJwtGrantedAuthoritiesConverterAdapter(new CustomJwtGrantedAuthoritiesConverter(claimRoles));
        jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(jwtGrantedAuthoritiesConverterAdapter);
        return jwtAuthenticationConverter;
    }
}

字符串

public class CustomJwtGrantedAuthoritiesConverter implements Converter<Jwt, Collection<GrantedAuthority>> {
    private final List<String> authoritiesClaimNames;

    public CustomJwtGrantedAuthoritiesConverter(final List<String> authoritiesClaimNames) {
        this.authoritiesClaimNames = authoritiesClaimNames;
    }

    @SuppressWarnings("unchecked")
    public Collection<GrantedAuthority> convert(final Jwt jwt) {
        return this.authoritiesClaimNames.stream().map(claimName -> {
            final var claims = jwt.getClaim(claimName);
            if (claims instanceof String) {
                return List.of((String) claims);
            } else if (claims instanceof ArrayList) {
                return ((ArrayList<String>) claims);
            } else {
                return Collections.<String>emptyList();
            }
        }).flatMap(Collection::stream).map(authority -> (GrantedAuthority) new SimpleGrantedAuthority(authority)).toList();
    }
}


应用程序工作,但我希望能够在业务代码中获得用户,特别是用户JWT。我需要在代码中添加什么,以便能够成功地从SecurityContextHolder(当前为null)获得SecurityContext?

SecurityContext ctx = SecurityContextHolder.getContext();


互联网上充满了例子,但我还没有设法适应我的需要。
有人能帮帮我吗?BR

fcwjkofz

fcwjkofz1#

例如,您可以通过请求它来获得令牌,并且它将神奇地被注入。

@RestController
public class MainController {

    @GetMapping("/token")
    public Token getToken(JwtAuthenticationToken jwtToken) {
        return new Token(
                     jwtToken.getToken(),
                     jwtToken.getAuthorities()
        );
    }    

    public record Token(Jwt token, Collection<GrantedAuthority> authorities){}
}

字符串
here是将spring服务器设置为资源服务器的完整教程

相关问题