Spring Security 6自定义验证过滤器(打算替换用户名密码验证过滤器)不起作用

mum43rcc  于 2023-01-08  发布在  Spring
关注(0)|答案(1)|浏览(432)

通过参考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

方法,并且它可以成功返回一个"authenticated"

Authentication object.

然而,它不会重定向到OAuth2客户端的重定向页面(我将我的项目设置为一个OIDC授权服务器),它将停留在登录页面,日志如下所示:
. Http会话请求缓存:已将请求http://192.168.0.107:9000/oauth2/authorize?client_id=messaging-client&redirect_uri=http%3A%2F%2F192.168.0.107%3A8080%2Fauth%2Fsigninwin%2Fmain&response_type=code&scope=openid%20profile%20message.read&state=802af0dcd82a483eb726c1dffff0867d&code_challenge=t_tfBjZPRd228uEZuQJ56clfXokGYqiwkudQqKhWQqo&code_challenge_method=S256&prompt=login&response_mode=query&continue&continue保存到会话2022 - 11 - 30T19:48:05.063 + 08:00调试63801---[nio-9000-exec-5] o.s.s. web。默认重定向策略:正在重定向至http://192.168.0.107:9000/login 2022 - 11 - 30T19:48:05.078 + 08:00调试63801---[nio-9000-exec-6]操作系统安全性. web.过滤器链代理:安全获取/登录2022 - 11 - 30T19:48:05.078 + 08:00调试63801---[nio-9000-exec-6]操作系统安全. web.过滤器链代理:安全获取/登录2022 - 11 - 30T19:48:05.084 + 08:00调试63801---[nio-9000-exec-6]匿名身份验证过滤器:将SecurityContextHolder设置为匿名SecurityContext
如果我不使用自定义的过滤器CustomAuthenticationFilter,一切都会很好(但当然我不能得到额外的LoginForm文件)。
我的身材。格雷德

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的属性不相同,需要进一步检查差异。

xwbd5t1u

xwbd5t1u1#

有两种解决方案,与先前版本的差异是由于此变更: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());

相关问题