【问题标题】:ReactiveSecurityContextHolder does not return Authenticated UserReactiveSecurityContextHolder 不返回经过身份验证的用户
【发布时间】:2018-02-06 23:00:15
【问题描述】:

我正在尝试在反应式 Spring Boot 应用程序中配置 Spring Security,并包含依赖于新 Spring-Security 版本的父项目5.0.0.RC1

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.0.M6</version>
</parent>

我将 Spring WebSecurity 配置为使用自定义 AuthenticationFilter 来检索我的身份验证信息以及使用我自己的 Providers 的自定义 AuthenticationManager。

配置:

@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class WebSecurityConfig {

    private ServerAuthenticationEntryPoint entryPoint = new CustomServerAuthenticationEntryPoint();

    @Bean
    SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) throws Exception {
        return http
            // we rely on method security
            .authorizeExchange()
                .anyExchange().permitAll()
            .and()
                .logout().disable()
                .authenticationManager(authenticationManager())
                //Override BasicAuthenticationEntryPoint
                .exceptionHandling().serverAuthenticationEntryPoint(this.entryPoint)
            .and()
                .addFilterAt(upmAuthenticationWebFilter(), SecurityWebFiltersOrder.AUTHENTICATION)
            .build();
    }


    private ReactiveAuthenticationManager authenticationManager() {
        return new CustomReactiveAuthenticationManager()
            .authenticationProvider(new CustomAuthenticationProvider());
    }

    private AuthenticationWebFilter upmAuthenticationWebFilter() {
        try {
            AuthenticationWebFilter authenticationFilter = new AuthenticationWebFilter(authenticationManager());
            authenticationFilter.setServerAuthenticationFailureHandler(new ServerAuthenticationEntryPointFailureHandler(this.entryPoint));
            authenticationFilter.setAuthenticationConverter(new CustomAuthenticationConverter(););

            return authenticationFilter;
        } catch (Exception e) {
            throw new BeanInitializationException("Could not initialize AuthenticationWebFilter.", e);
        }
    }
}

ReactiveAuthenticationManager:

public class CustomReactiveAuthenticationManager implements ReactiveAuthenticationManager {

    private List<AuthenticationProvider> authenticationProvider = new ArrayList<>();

    public CustomReactiveAuthenticationManager customAuthenticationProvider(
        final AuthenticationProvider customAuthenticationProvider) {
        this.authenticationProvider.add(customAuthenticationProvider);
        return this;
    }

    @Override
    public Mono<Authentication> authenticate(final Authentication authentication) {
        Class<? extends Authentication> toTest = authentication.getClass();
        for(AuthenticationProvider provider: authenticationProvider) {
            if (provider.supports(toTest)) {
                try {

                    //The provider returns a full authenticated Authentication object.
                    //With authentication.setAuthenticated(true);
                    return Mono.just(provider.authenticate(authentication));
                } catch (Exception e) {
                    return Mono.error(new BadCredentialsException("Invalid Credentials"));
                }
            }
        }
        return Mono.error(new ProviderNotFoundException("Unsupported Credentials"));
    }
}

当我现在在需要经过身份验证的用户的端点上执行调用时。如:

public interface HelloService {
    /**
     * This method returns just 'Hello, world!'.
     *
     * @return Return 'Hello, world!'.
     */
    @PreAuthorize("isAuthenticated()")
    Mono<String> getHelloWorld();
}

我总是收到 401 AccessDenied 异常。

在 PrePostAdviceReactiveMethodInterceptor 第 75 行调试后

 auth -> this.preInvocationAdvice.before(auth, invocation, preAttr)

我看到传递的Authentication对象是匿名用户。

现在我的问题是: 我是否忘记为 ReactiveSecurityContext 的使用配置一些东西?

上周我仍然使用以前的 MilestoneRelease M5,其中反应式 Spring-Security 包仍然位于额外的 Spring-Security-Reactive 下。在这种情况下,已检索到身份验证对象,并且可以完成我的请求。

【问题讨论】:

    标签: spring authentication spring-boot spring-security reactive


    【解决方案1】:

    如果有人对此问题感兴趣。

    我没有在 AuthenticationWebFilter 中设置 serverSecurityContextRepository

    所以设置这个解决了问题。

    private AuthenticationWebFilter upmAuthenticationWebFilter() {
        try {
            AuthenticationWebFilter authenticationFilter = new AuthenticationWebFilter(authenticationManager());
            authenticationFilter.setServerAuthenticationFailureHandler(new ServerAuthenticationEntryPointFailureHandler(this.entryPoint));
            authenticationFilter.setAuthenticationConverter(new CustomAuthenticationConverter(););
    
            //Setting the Context Repo helped
            authenticationFilter.setServerSecurityContextRepository(new WebSessionServerSecurityContextRepository());
    
            return authenticationFilter;
        } catch (Exception e) {
            throw new BeanInitializationException("Could not initialize AuthenticationWebFilter.", e);
        }
    }
    

    【讨论】:

      【解决方案2】:

      由于设置存储库对我不起作用,我只是将主体添加到我的 REST 函数中:

      @GetMapping("/select")
      public Mono<String> select(java.security.Principal principal) {
           log.debug("Authorities: {}", ((Authentication) principal).getAuthorities());
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-15
        • 2016-01-17
        • 2018-01-07
        • 1970-01-01
        • 2020-06-23
        • 2015-06-15
        相关资源
        最近更新 更多