繁体   English   中英

Spring Security 6 CustomAuthenticationFilter(打算替换 UsernamePasswordAuthenticationFilter)不起作用

[英]Spring Security 6 CustomAuthenticationFilter(intend to replace the UsernamePasswordAuthenticationFilter) does not work

通过引用https://www.baeldung.com/spring-security-extra-login-fields

我打算自定义 Spring 安全身份验证 UsernamePasswordAuthenticationFilter 的功能以获取额外的自定义“loginForm”字段。

我创建了一个自定义过滤器

CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter

和一个定制的身份验证令牌

public class CustomAuthenticationToken extends UsernamePasswordAuthenticationToken

通过使用以下配置:

@EnableWebSecurity
@Configuration(proxyBeanMethods = false)
public class AuthenticationSecurityConfig extends AbstractHttpConfigurer<AuthenticationSecurityConfig, HttpSecurity> {


@Override
public void configure(HttpSecurity http) throws Exception {
    AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class);
    http.addFilterBefore(authenticationFilter(authenticationManager), UsernamePasswordAuthenticationFilter.class);
}

@Bean
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
    
    http.authorizeHttpRequests()
            .requestMatchers("/css/**", "/login")
            .permitAll()
            .requestMatchers("/resources/**")
            .permitAll()
            .and()
            .formLogin(form -> form
                    .loginPage("/login")
                    .permitAll()
            )
            .logout()
            .logoutUrl("/logout")
            .and()
            .authorizeHttpRequests(
                    auth -> auth.anyRequest().authenticated()
            )
            .apply(securityConfig());
    return http.build();

}

}

我可以成功地使我的 AuthenticationProvider 的

authenticate

要执行的方法,并且它可以成功返回一个“已验证”

Authentication object.

但是它不会重定向到 OAuth2 客户端的重定向页面(我将我的项目设置为一个 OIDC 授权服务器),它会停留在登录页面,日志如下所示:

.HttpSessionRequestCache: 保存的请求http://192.168.0.107:9000/oauth2/authorize?client_id=messaging-client&redirect_uri=http%3A%2F%2F192.168.0.107%3A8080%2Fauth%2Fsigninwin%2_fmain&response=opentype&response %20message.read&state=802af0dcd82a483eb726c1dffff0867d&code_challenge=t_tfBjZPRd228uEZuQJ56clfXokGYqiwkudQqKhWQqo&code_challenge_method=S256&prompt=login&response_mode=query&continue&continue to session 2022-11-30T19:48:05.063+08:00 DEBUG 63801 --- [nio-9000-exec-5] ossweb.DefaultRedirectStrategy: Redirecting to http ://192.168.0.107:9000/login 2022-11-30T19:48:05.078+08:00 DEBUG 63801 --- [nio-9000-exec-6] osssecurity.web.FilterChainProxy:保护 GET /login 2022-11 -30T19:48:05.078+08:00 DEBUG 63801 --- [nio-9000-exec-6] osssecurity.web.FilterChainProxy: 安全 GET /login 2022-11-30T19:48:05.084+08:00 DEBUG 63801 - -- [nio-9000-exec-6] osswaAnonymousAuthenticationFilter:将 SecurityContextHolder 设置为匿名 S 安全上下文

如果我不使用自定义过滤器 CustomAuthenticationFilter,一切都会好起来的(但我当然无法获得额外的 LoginForm 文件)。

我的 build.gradle

plugins {
    id "org.springframework.boot" version "3.0.0-RC2"
    id "io.spring.dependency-management" version "1.0.11.RELEASE"
    id "java"
}
implementation "org.springframework.security:spring-security-oauth2-authorization-server:1.0.0"

有任何想法吗?

我怀疑CustomAuthenticationFilter(使用new创建对象)的属性与spring安全框架将初始化的UsernamePasswordAuthenticationFilter的属性不一样,需要进一步检查差异。

有两种解决方案,与之前版本的不同是因为这个改动:https://github.com/spring-projects/spring-security/issues/11110

***第一个解决方案***

您可以使用旧策略(已弃用)自动保存 SecurityContextHolder 设置:

http.securityContext((securityContext) -> securityContext.requireExplicitSave(false))

*** 第二种解决方案 ***

定义一个 HttpSessionSecurityContextRepository:

@Bean
public HttpSessionSecurityContextRepository securityContextRepository() {
    return new HttpSessionSecurityContextRepository();
}

设置为http配置:

http.securityContext().securityContextRepository(securityContextRepository())

最后将上下文存储库设置为您的自定义过滤器:

filter.setSecurityContextRepository(securityContextRepository());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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