简体   繁体   English

如何在反应式 webflux 中获取 spring 安全上下文

[英]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 .其中clientRegistrationsReactiveClientRegistrationRepository类型的可注入 bean, authorizedClientsServerOAuth2AuthorizedClientRepository类型的可注入 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM