如何解决带有 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 举报,一经查实,本站将立刻删除。