代码之家  ›  专栏  ›  技术社区  ›  user3139545

从自定义WebFlux loginForm传递其他登录参数

  •  0
  • user3139545  · 技术社区  · 7 年前

    ReactiveAuthenticationManager 和我的朋友一起工作 formLogin

    @Bean
    public ReactiveAuthenticationManager reactiveAuthenticationManager() {
        return new ReactiveAuthenticationManagerAdapter(this::authenticate);
    }
    
    private Authentication authenticate(Authentication authentication) throws AuthenticationException {
    
        return new UsernamePasswordAuthenticationToken(
                userId, password, authorities);
    

    }

    这个很好用 authenticate 函数在正确的时间被调用。不过,我现在必须从登录表单中发送一个附加参数。我已经能够创建一个自定义的登录表单,将额外的参数发送到端点,但是如何将其包含在 Authentication 我进去的对象 验证

    我发现 this 这个例子在实现中很直接,但它是针对springmvc的,我需要在WebFlux中完成它。

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        http.csrf()
                .disable()
                .authorizeExchange()
                .pathMatchers("/login/**")
                .permitAll()
                .pathMatchers("/**")
                .authenticated()
                .and()
                .formLogin()
                .loginPage("/login")
                .authenticationSuccessHandler(new RedirectServerAuthenticationSuccessHandler("/"))
                .authenticationFailureHandler(this::onAuthenticationFailure)
                .and()
                .logout()
                .logoutUrl("/logout")
                .logoutSuccessHandler(logoutSuccessHandler("/bye"));
    
        return http.build();
    }
    

    我现在有些进步了。不使用默认值 窗体登录 ServerHttpSecurity 而是用我自己的 WebFilter 延伸 AuthenticationWebFilter 服务器HttpSecurity 上课对我有好处。

    1 回复  |  直到 7 年前
        1
  •  1
  •   piotr szybicki    7 年前

    我试着把它做得更优雅些,但那会是更多的工作。所以我接受了这一点。你必须像你一样构建你的SecurityWebFiler链。但在你创造它之后,你必须找到这个 AuthenticationWebFilter 它是一个web过滤器,负责创建 authentication

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
           http.authorizeExchange()
               .anyExchange().authenticated()
               .and()
               .formLogin()
           ;
    
        final SecurityWebFilterChain build = http.build();
    
        build.getWebFilters().collectList().subscribe(
                webFilters -> {
                    for (WebFilter filter : webFilters){
                        if(filter instanceof AuthenticationWebFilter){
                            AuthenticationWebFilter awf = (AuthenticationWebFilter) filter;
                            awf.setAuthenticationConverter(new CustomHttpBasicAuthenticationConverter());
                        }
                    }
                }
        );
    
        return build;
    }
    

    示例 HttpBasicAuthenticationConverter

    import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
    import org.springframework.security.core.Authentication;
    import org.springframework.util.Assert;
    import org.springframework.util.MultiValueMap;
    import org.springframework.web.server.ServerWebExchange;
    import reactor.core.publisher.Mono;
    
    import java.util.function.Function;
    
    public class CustomHttpBasicAuthenticationConverter implements Function<ServerWebExchange, Mono<Authentication>> {
    
    private String usernameParameter = "username";
    private String passwordParameter = "password";
    
    @Override
    public Mono<Authentication> apply(ServerWebExchange exchange) {
        return exchange.getFormData()
                .map( data -> createAuthentication(data));
    }
    
    private UsernamePasswordAuthenticationToken createAuthentication(
            MultiValueMap<String, String> data) {
        String username = data.getFirst(this.usernameParameter);
        String password = data.getFirst(this.passwordParameter);
        return new UsernamePasswordAuthenticationToken(username, password);
    }
    
    public void setUsernameParameter(String usernameParameter) {
        Assert.notNull(usernameParameter, "usernameParameter cannot be null");
        this.usernameParameter = usernameParameter;
    }
    
    public void setPasswordParameter(String passwordParameter) {
        Assert.notNull(passwordParameter, "passwordParameter cannot be null");
        this.passwordParameter = passwordParameter;
    }
    }