我有两个springboot应用程序,一个springboot rsocket客户端应用程序和一个springboot rsocket服务器应用程序。我正试图通过使用key斗篷来增加oauth2和oidc的安全性。从我读到的内容来看,客户机凭证流似乎是服务对服务通信的最佳选择,所以这就是我一直在研究的内容。
到目前为止,我通过rsocket客户端应用程序上的以下代码实现了这一点:
@EnableWebFluxSecurity
public class WebFluxSecurityConfiguration {
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
return http
.csrf().disable()
.authorizeExchange()
.pathMatchers("/api/v1/**").permitAll()
.and().oauth2Client()
.and().oauth2ResourceServer().jwt()
.and().and()
.build();
}
}
@Component
@RequiredArgsConstructor
public class OAuth2 {
private final ReactiveClientRegistrationRepository clientRepository;
@Value("${oauth2.client.registration-id}")
private String clientRegistrationId;
public Mono<String> getAccessToken() {
var client = new WebClientReactiveClientCredentialsTokenResponseClient();
return clientRepository
.findByRegistrationId(clientRegistrationId)
.map(OAuth2ClientCredentialsGrantRequest::new)
.flatMap(client::getTokenResponse)
.map(OAuth2AccessTokenResponse::getAccessToken)
.map(OAuth2AccessToken::getTokenValue);
}
public Consumer<RSocketRequester.MetadataSpec<?>> addTokenToMetadata(String token) {
var mimeType = MimeTypeUtils.parseMimeType(WellKnownMimeType.MESSAGE_RSOCKET_AUTHENTICATION.getString());
var bearerTokenMetadata = new BearerTokenMetadata(token);
return spec -> spec.metadata(bearerTokenMetadata, mimeType);
}
}
@Component
public class FooClientImpl implements FooClient {
private final Mono<RSocketRequester> rsocketRequester;
private final OAuth2 oAuth2;
public FooClientImpl(RSocketRequester.Builder requesterBuilder,
OAuth2 oAuth2,
@Value("${routes.foo-service.host}") String host,
@Value("${routes.foo-service.port}") Integer port) {
this.rsocketRequester = requesterBuilder
.rsocketStrategies(configurer -> configurer.encoder(new BearerTokenAuthenticationEncoder()))
.dataMimeType(MediaType.APPLICATION_CBOR)
.connectTcp(host, port);
this.oAuth2 = oAuth2;
}
@Override
public Publisher<Foo> findFoos(FooRequest request) {
return oAuth2.getAccessToken()
.flatMapMany(accessToken -> rsocketRequester
.flatMapMany(req -> req
.route("find.foos")
.metadata(oAuth2.addTokenToMetadata(accessToken))
.data(request)
.retrieveFlux(Foo.class)));
}
}
my application.yml配置文件:
server:
port: 9000
logging:
level:
root: info
---
spring:
profiles: local
security:
oauth2:
client:
provider:
keycloak:
issuer-uri: http://localhost:8080/auth/realms/foo
registration:
keycloak:
client-id: foo-service
client-secret: 81196896-80bd-41e3-97e6-3556feeef577
authorization-grant-type: client_credentials
resourceserver:
jwt:
issuer-uri: http://localhost:8080/auth/realms/foo
routes:
foo-service:
host: localhost
port: 7000
oauth2:
client:
registration-id: keycloak
尽管例如,如果我使用http而不是rsocket,我还是可以像这样利用spring的webclient:
@Bean
WebClient webClient(ReactiveClientRegistrationRepository clientRegistrations,
ServerOAuth2AuthorizedClientRepository authorizedClients) {
var oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrations, authorizedClients);
oauth.setDefaultClientRegistrationId("keycloak");
return WebClient
.builder()
.filter(oauth)
.build();
}
有没有更好的方法来实现这一点?有没有一种方法可以通过过滤函数(或类似的函数)用访问令牌调用rsocket服务器(通过rsocketrequester),就像我对webclient所做的那样?spring security rsocket中是否支持oauth2客户端?我已经查阅了springrsocket文档,但是它们只提到了一般的jwt支持,我没有找到任何关于oauth2支持的内容。
暂无答案!
目前还没有任何答案,快来回答吧!