首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RSocket Java Spring @AuthenticationPrincipal with JWT

RSocket Java Spring @AuthenticationPrincipal with JWT
EN

Stack Overflow用户
提问于 2021-01-21 02:33:30
回答 1查看 493关注 0票数 1

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

代码语言:javascript
复制
    public Mono<String> uppercase(String s, @AuthenticationPrincipal Mono<JwtAuthenticationToken> token) { 
        //Token is always null 
        return Mono.just(s.toUpperCase());
    }

我创建了一个RSocketSecurityConfiguration类:

代码语言:javascript
复制
@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;
}

完整的UpperCaseController:

代码语言:javascript
复制
@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());
    }
}

完整的ConnectController:

代码语言:javascript
复制
@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();
    }
}

RSocket客户端:

代码语言:javascript
复制
@Component
@Slf4j
public class RSocketClient {

    private static final MimeType SIMPLE_AUTH = MimeTypeUtils.parseMimeType(WellKnownMimeType.MESSAGE_RSOCKET_AUTHENTICATION.getString());
    MimeType BEARER_AUTH =
            MimeTypeUtils.parseMimeType(WellKnownMimeType.MESSAGE_RSOCKET_AUTHENTICATION.getString());

    private static final String BEARER_TOKEN = "....";
    private final RSocketRequester requester;
    private RSocketStrategies rsocketStrategies;

    public RSocketClient(RSocketRequester.Builder requesterBuilder,
                         @Qualifier("rSocketStrategies") RSocketStrategies strategies) {
        this.rsocketStrategies = strategies;
        SocketAcceptor responder = RSocketMessageHandler.responder(rsocketStrategies, new RSocketClientHandler());
            requester = requesterBuilder
                .setupRoute("connect")
                .setupData("MyTestClient")
                                .setupMetadata(new BearerTokenMetadata(BEARER_TOKEN), BEARER_AUTH)
                .rsocketStrategies(builder ->
                        builder.encoder(new BearerTokenAuthenticationEncoder()))
                .rsocketConnector(connector -> connector.acceptor(responder))
                .connectTcp("localhost", 7000)
                .block();

        requester.rsocket()
                .onClose()
                .doOnError(error -> log.warn("Connection CLOSED"))
                .doFinally(consumer -> log.info("Client DISCONNECTED"))
                .subscribe();
    }
    public void uppercase() {
               String response = requester
                .route("uppercase")
                .metadata(BEARER_TOKEN, BEARER_AUTH)
                .data("Hello")
                .retrieveMono(String.class).block();
        log.info(response);
    }
}

我已经为Spring REST做了一些非常类似的事情,它工作得很好,但是对于RSocket,标记总是空的。

EN

回答 1

Stack Overflow用户

发布于 2021-01-21 04:02:13

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

我能够使用@Payload之外的不同类型在我的代码库中实现这一点

代码语言:javascript
复制
  @ConnectMapping
  fun handle(requester: RSocketRequester, @AuthenticationPrincipal jwt: String) {
    logger.debug("connected $jwt")
  }
代码语言:javascript
复制
  @MessageMapping("runCommand")
  suspend fun runCommand(request: CommandRequest, rSocketRequester: RSocketRequester, @AuthenticationPrincipal jwt: String): Flow<CommandResponse> {
...
  }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65815542

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档