解析SpringSecurity自定义登录验证成功与失败的结果处理问题

网友投稿 855 2023-07-10

解析SpringSecurity自定义登录验证成功与失败的结果处理问题

解析SpringSecurity自定义登录验证成功与失败的结果处理问题

一、需要自定义登录结果的场景

在我之前的文章中,做过登录验证流程的源码解析。其中比较重要的就是

当我们登录成功的时候,是由AuthenticationSuccessHandler进行登录结果处理,默认跳转到defaultSuccessUrl配置的路径对应的资源页面(一般是首页index.html)。

当我们登录失败的时候,是由AuthenticationfailureHandler进行登录结果处理,默认跳转到failureUrl配置的路径对应的资源页面(一般是登录页login.html)。

但是在web应用开发过程中需求是千变万化的,有时需要我们针对登录结果做个性化处理,比如:

我们希望不同的人登陆之后,看到不同的首页

我们应用是前后端分离的,验证响应结果是jsON格式数据,而不是页面跳转

以上的这些情况,使用Spring Security作为安全框架的时候,都需要我们使用本节学到的知识进行自定义的登录验证结果处理。

二、自定义登陆成功的结果处理

为了满足上面的需求,我们该如何去做呢?下面一小节我们来说明一下。AuthenticationSuccessHandler接口是Security提供的认证成功处理器接口,我们只需要去实现它即可。但是通常来说,我们不会直接去实现AuthenticationSuccessHandler接口,而是继承SavedRequestAwareAuthenticationSuccessHandler 类,这个类会记住用户上一次请求的资源路径,比如:用户请求books.html,没有登陆所以被拦截到了登录页,当你万成登陆之后会自动跳转到books.html,而不是主页面。

@Component

public class MyAuthenticationSuccessHandler

extends SavedRequestAwareAuthenticationSuccessHandler {

//在application配置文件中配置登陆的类型是JSON数据响应还是做页面响应

@Value("${spring.security.logintype}")

private String loginType;

private static ObjectMapper objectMapper = new ObjectMapper();

@Override

public void onAuthenticationSuccess(HttpServletRequest request,

HttpServletResponse response,

Authentication authentication)

throws ServletException, IOException {

if (loginType.equalsIgnoreCase("JSON")) {

response.setContentType("application/json;charset=UTF-8");

response.getWriter().write(objectMapper.writeValueAsString(AjaxResponse.success()));

} else {

// 会帮我们跳转到上一次请求的页面上

super.onAuthenticationSuccess(request, response, authentication);

}

}

}

在上面的自定义登陆成功处理中,既适应JSON前后端分离的应用登录结果处理,也适用于模板页面跳转应用的登录结果处理

ObjectMapper 是Spring Boot默认集成的JSON数据处理类库Jackson中的类。

AjaxResponse是一个自定义的通用的JSON数据接口响应类。

三、自定义登录失败的结果处理

这里我们同样没有直接实现AuthenticationFailureHandler接口,而是继承SimpleUrlAuthenticationFailureHandler 类。该类中默认实现了登录验证失败的跳转逻辑,即登陆失败之后回到登录页面。我们可以利用这一点简化我们的代码。

@Component

public class MyAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {

//在application配置文件中配置登陆的类型是JSON数据响应还是做页面响应

@Value("${spring.security.logintype}")

private String loginType;

private static ObjectMapper objectMapper = new ObjectMapper();

@Override

public void onAuthenticationFailure(HttpServletRequest request,

HttpServletResponse response,

AuthenticationException exception)

throws IOException, ServletException {

if (loginType.equalsIgnoreCase("JSON")) {

response.setContentType("application/json;charset=UTF-8");

response.getWriter().write(

objectMapper.writeValueAsString(

AjaxResponse.error(

new CustomException(

CustomExceptionType.USER_INPUT_ERROR,

"用户名或密码存在错误,请检查后再次登录"))));

} else {

response.setContentType("text/html;charset=UTF-8");

super.onAuthenticationFailure(SJUdTjQmWtrequest, response, exception);

}

}

}

在上面的自定义登陆失败处理中,既适应JSON前后端分离的应用登录失败结果处理,也适用于模板页面跳转应用的登录失败结果处理

登陆失败之后,将默认跳转到默认的failureUrl,即登录界面。

四、配置SecurityConfig

@Configuration

public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Resource

private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;

@Resource

private MyAuthenticationFailureHandler myAuthenticationFailureHandler;

@Override

protected void configure(HttpSecurity http) throws Exception {

http.csrf().disable() //禁用跨站csrf攻击防御,后面的章节会专门讲解

.formLogin()

.successHandler(myAuthenticationSuccessHandler)

.failureHandler(myAuthenticationFailureHandler)

.defaultSuccessUrl("/index")//登录认证成功后默认转跳的路径

.failureUrl("/login.html") //登录认证是被跳转页面

}

将自定义的AuthenticationSuccessHandler和AuthenticationFailureHandler注入到Spring Security配置类中

使用fromlogin模式,配置successHandler和failureHandler。

并且配置defaultSuccessUrl和failureUrl

总结

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Spring实战之注入集合值操作示例
下一篇:简单了解Spring Bean常用注解的装配
相关文章

 发表评论

暂时没有评论,来抢沙发吧~