java自定义密码或用户名错误异常,解析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(request, 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

总结

以上所述是小编给大家介绍的SpringSecurity自定义登录验证成功与失败的结果处理,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要重写`AuthenticationProvider`类的`authenticate()`方法以接收JSON格式的登录请求,你需要执行以下步骤: 1. 创建一个自定义的`AuthenticationProvider`类并实现`authenticate()`方法。 2. 在`authenticate()`方法中,解析JSON格式的登录请求,并将用户名密码提取出来。 3. 通过这些提取出来的用户名密码创建一个`UsernamePasswordAuthenticationToken`对象。 4. 将这个`UsernamePasswordAuthenticationToken`对象传递给`AuthenticationManager`的`authenticate()`方法进行验证。 5. 如果验证成功,`authenticate()`方法应该返回一个`Authentication`对象,其中包含已验证的用户信息和权限。 6. 如果验证失败,`authenticate()`方法应该抛出一个`AuthenticationException`异常。 以下是一个简单的示例: ```java @Component public class CustomAuthenticationProvider implements AuthenticationProvider { @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { String json = authentication.getPrincipal().toString(); ObjectMapper objectMapper = new ObjectMapper(); try { JsonNode jsonNode = objectMapper.readTree(json); String username = jsonNode.get("username").asText(); String password = jsonNode.get("password").asText(); UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password); return AuthenticationManager.authenticate(token); } catch (IOException e) { throw new BadCredentialsException("Invalid JSON credentials", e); } } @Override public boolean supports(Class<?> authentication) { return authentication.equals(UsernamePasswordAuthenticationToken.class); } } ``` 在这个例子中,我们将JSON格式的登录请求作为`Authentication`对象的主体传递给`authenticate()`方法。然后我们使用`ObjectMapper`解析JSON,并提取用户名密码。最后,我们创建一个`UsernamePasswordAuthenticationToken`对象,将其传递给`AuthenticationManager`进行验证。如果验证通过,`authenticate()`方法将返回一个`Authentication`对象,其中包含已验证的用户信息和权限。如果验证失败,`authenticate()`方法将抛出一个`BadCredentialsException`异常

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值