微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

带有 JWT 的 RSocket Java Spring @AuthenticationPrincipal

如何解决带有 JWT 的 RSocket Java Spring @AuthenticationPrincipal

我们如何将@AuthenticationPrincipal 与 RSocket 方法一起使用 @AuthenticationPrincipal Mono 令牌

# no pip install manually
# without --no-build flag
func azure functionapp publish [functionapp name]

我创建了一个 RSocketSecurityConfiguration 类:

    public Mono<String> uppercase(String s,@AuthenticationPrincipal Mono<JwtAuthenticationToken> token) { 
        //Token is always null 
        return Mono.just(s.toupperCase());
    }

完整的大写控制器:

@Configuration
@EnableRSocketSecurity
@EnableReactiveMethodSecurity
@Slf4j
public class RSocketSecurityConfiguration {

    @Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
    private String issuerUri;

    @Bean
    PayloadSocketAcceptorInterceptor rsocketInterceptor(RSocketSecurity rsocket) {
        rsocket
                .authorizePayload(authorize ->
                        authorize
                                .anyRequest().authenticated()
                                .anyExchange().permitAll()
                )
                .jwt(jwtSpec -> {
                    jwtSpec.authenticationManager(jwtReactiveAuthenticationManager(reactiveJwtDecoder()));
                });
        return rsocket.build();
    }
   @Bean
ReactiveJwtDecoder reactiveJwtDecoder() {

    NimbusReactiveJwtDecoder decoder = (NimbusReactiveJwtDecoder)
            ReactiveJwtDecoders.fromOidcIssuerLocation(issuerUri);
    return decoder;
}

   @Bean
    public JwtReactiveAuthenticationManager jwtReactiveAuthenticationManager(ReactiveJwtDecoder reactiveJwtDecoder) {
        JwtReactiveAuthenticationManager jwtReactiveAuthenticationManager = new JwtReactiveAuthenticationManager(reactiveJwtDecoder);

        JwtAuthenticationConverter authenticationConverter = new JwtAuthenticationConverter();
        JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
        jwtGrantedAuthoritiesConverter.setAuthorityPrefix("ROLE_");
        authenticationConverter.setJwtGrantedAuthoritiesConverter(jwtGrantedAuthoritiesConverter);
        jwtReactiveAuthenticationManager.setJwtAuthenticationConverter( new ReactiveJwtAuthenticationConverteradapter(authenticationConverter));

        return jwtReactiveAuthenticationManager;
    }
@Bean
RSocketMessageHandler messageHandler(RSocketStrategies strategies) {
    RSocketMessageHandler mh = new RSocketMessageHandler();
    mh.getArgumentResolverConfigurer().addCustomresolver(new AuthenticationPrincipalArgumentResolver());
    mh.setRSocketStrategies(strategies);

    return mh;
}

完整的连接控制器:

@Slf4j
@Controller
public class UpperCaseController {

    @MessageMapping("uppercase")
    public Mono<String> uppercase(String s,@AuthenticationPrincipal Mono<JwtAuthenticationToken> token) {
        JwtAuthenticationToken currentToken = token.block();
        if ( currentToken == null ) {
            log.info("token is null");
        }
        return Mono.just(s.toupperCase());
    }
}

RSocket 客户端:

@Slf4j
@Controller
public class ConnectController {

    @ConnectMapping("connect")
    void connectShellClientAndaskForTelemetry(RSocketRequester requester,@Payload String client) {

        requester.rsocket()
                .onClose()
                .doFirst(() -> {
                    // Add all new clients to a client list
                    log.info("Client: {} CONNECTED.",client);
                })
                .doOnError(error -> {
                    // Warn when channels are closed by clients
                    log.warn("Channel to client {} CLOSED",client);
                })
                .doFinally(consumer -> {
                    // Remove disconnected clients from the client list

                    log.info("Client {} disCONNECTED",client);
                })
                .subscribe();
    }
}

我为 Spring REST 做了一些非常类似的事情,它工作正常,但对于 RSocket,令牌始终为空。

解决方法

我假设您已经开始使用 https://spring.io/blog/2020/06/17/getting-started-with-rsocket-spring-security

我能够使用与@Payload 不同的类型为我的代码库工作

  @ConnectMapping
  fun handle(requester: RSocketRequester,@AuthenticationPrincipal jwt: String) {
    logger.debug("connected $jwt")
  }
  @MessageMapping("runCommand")
  suspend fun runCommand(request: CommandRequest,rSocketRequester: RSocketRequester,@AuthenticationPrincipal jwt: String): Flow<CommandResponse> {
...
  }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。