[英]How to get spring security context in reactive webflux
I have a problem with my spring boot application (version 2.6.3).我的 spring 启动应用程序(版本 2.6.3)有问题。 I have configured reactive spring security like there:
我已经像那里那样配置了反应式 spring 安全性:
MyApplication.java:我的应用程序.java:
@SpringBootApplication
@EnableWebFlux
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class);
}
@Bean
public SecurityWebFilterChain springSecurityFilterChain(final ServerHttpSecurity http, final ReactiveOpaqueTokenIntrospector reactiveOpaqueTokenIntrospector) {
return http.authorizeExchange()
.anyExchange().authenticated()
.and()
.httpBasic().disable()
.cors().and()
.logout().disable()
.formLogin().disable()
.oauth2ResourceServer()
.opaqueToken()
.introspector(reactiveOpaqueTokenIntrospector)
.and().and()
.csrf()
.disable()
.build();
}
}
And this is my web resource (controller):这是我的 web 资源(控制器):
MyWebResource.java:我的网络资源.java:
@RestController
public class MyWebResource implements MyWebResourceApi {
@PreAuthorize("hasRole('ROLE_USER')")
@Override
public Mono<String> details(String userId, ServerWebExchange exchange) {
return exchange.getPrincipal().map(Principal::getName);
}
}
It's work fine, when my access token is expired or incorrect the request should be denied.它工作正常,当我的访问令牌过期或不正确时,应该拒绝请求。 However when PreAuthorized allow request, my user principal will be never resolved in my exchange...
但是,当 PreAuthorized 允许请求时,我的用户主体将永远不会在我的交换中得到解决...
In reactive application authentication information is stored in the Reactive flow and accessible from Mono
/ Flux
.在反应式应用程序中,身份验证信息存储在反应式流程中,可以从
Mono
/ Flux
访问。 You could use ReactiveSecurityContextHolder
to obtain the currently authenticated principal, or an authentication request token.您可以使用
ReactiveSecurityContextHolder
获取当前经过身份验证的主体或身份验证请求令牌。
@PreAuthorize("hasRole('ROLE_USER')")
public Mono<String> details() {
return ReactiveSecurityContextHolder.getContext()
.map(ctx -> ((Principal) ctx.getAuthentication().getPrincipal()).getName());
}
I found this answer looking for a way to add the access token to my webclient requests.我找到了这个答案,寻找一种将访问令牌添加到我的网络客户端请求的方法。 If we are using OAuth2 or OpenID Connect and want to access the token instead of the principal's name, then this is not possible via the principal in the security context.
如果我们使用 OAuth2 或 OpenID Connect 并且想要访问令牌而不是委托人的名称,那么通过安全上下文中的委托人这是不可能的。
Instead we need to create a ServerOAuth2AuthorizedClientExchangeFilterFunction
and register it as a filter function to the WebClient:相反,我们需要创建一个
ServerOAuth2AuthorizedClientExchangeFilterFunction
并将其注册为 WebClient 的过滤器 function:
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth =
new ServerOAuth2AuthorizedClientExchangeFilterFunction(
clientRegistrations,
authorizedClients);
oauth.setDefaultOAuth2AuthorizedClient(true);
where clientRegistrations
is an injectabile bean of type ReactiveClientRegistrationRepository
and authorizedClients
is an injectable bean of type ServerOAuth2AuthorizedClientRepository
.其中
clientRegistrations
是ReactiveClientRegistrationRepository
类型的可注入 bean, authorizedClients
是ServerOAuth2AuthorizedClientRepository
类型的可注入 bean。
We can then use the filters
method for the builder to add our filter function to the exchangeFilterFunctions
:然后我们可以使用构建器的
filters
方法将我们的过滤器 function 添加到exchangeFilterFunctions
:
WebClient.builder()
.filters(exchangeFilterFunctions -> {
exchangeFilterFunctions.add(oauth);
})
.build();
Baeldung has a nice background article about this, which explains it in more detail: https://www.baeldung.com/spring-webclient-oauth2 Baeldung 有一篇关于此的很好的背景文章,更详细地解释了它: https://www.baeldung.com/spring-webclient-oauth2
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.