自定义Spring Security的身份验证失败处理
1.概述
在本快速教程中,我们将演示如何在Spring Boot应用程序中自定义Spring Security的身份验证失败处理。目标是使用表单登录方法对用户进行身份验证。
2.认证和授权(Authentication and Authorization)
身份验证和授权通常结合使用,因为它们在授予系统访问权限时起着重要且同样重要的作用。
但是,它们具有不同的含义,并在验证请求时应用不同的约束:
- 身份验证 – 在授权之前;它是关于验证收到的凭证;我们验证用户名和密码是否与我们的应用程序识别的用户名和密码相匹配
- 授权 – 用于验证成功通过身份验证的用户是否有权访问应用程序的某个功能
我们可以自定义身份验证和授权失败处理,但是,在此应用程序中,我们将专注于身份验证失败。
3. Spring Security的AuthenticationFailureHandler
Spring Security提供了一个默认处理身份验证失败的组件。
但是,我们发现于默认行为不足以满足实际要求的情况是很常见的。
如果是这种情况,我们可以创建自己的组件并通过实现AuthenticationFailureHandler接口提供我们想要的自定义行为:
public class CustomAuthenticationFailureHandler
implements AuthenticationFailureHandler {
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public void onAuthenticationFailure(
HttpServletRequest request,
HttpServletResponse response,
AuthenticationException exception)
throws IOException, ServletException {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
Map<String, Object> data = new HashMap<>();
data.put(
"timestamp",
Calendar.getInstance().getTime());
data.put(
"exception",
exception.getMessage());
response.getOutputStream()
.println(objectMapper.writeValueAsString(data));
}
}
默认情况下,Spring使用包含错误信息的请求参数将用户重定向回登录页面。
在此应用程序中,我们将返回401响应,其中包含有关错误的信息以及错误发生的时间戳。
- DelegatingAuthenticationFailureHandler将AuthenticationException子类委托给不同的AuthenticationFailureHandler,这意味着我们可以为AuthenticationException的不同实例创建不同的行为
- ExceptionMappingAuthenticationFailureHandler根据AuthenticationException的完整类名将用户重定向到特定的URL
- 无论AuthenticationException的类型如何,ForwardAuthenticationFailureHandler都会将用户转发到指定的URL
- SimpleUrlAuthenticationFailureHandler是默认使用的组件,如果指定,它会将用户重定向到failureUrl;否则,它只会返回401响应
现在我们已经创建了自定义AuthenticationFailureHandler,让我们配置我们的应用程序并覆盖Spring的默认处理程序:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration
extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth
.inMemoryAuthentication()
.withUser("baeldung")
.password("baeldung")
.roles("USER");
}
@Override
protected void configure(HttpSecurity http)
throws Exception {
http
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.formLogin()
.failureHandler(customAuthenticationFailureHandler());
}
@Bean
public AuthenticationFailureHandler customAuthenticationFailureHandler() {
return new CustomAuthenticationFailureHandler();
}
}
注意failureHandler()调用,我们可以告诉Spring使用我们的自定义组件而不是使用默认组件。
4.结论
在此示例中,我们使用Spring的AuthenticationFailureHandler接口自定义了应用程序的身份验证失败处理程序。
可以在Github项目中找到此示例的实现。
在本地运行时,您可以在localhost:8080上访问和测试应用程序.