​SpringSecurity-5-自定义登录验证

简介: ​SpringSecurity-5-自定义登录验证

SpringSecurity-5-自定义登录验证



  • 默认登录成功失败跳转页
  • 为什么自定义登录验证结果处理场景
  • 自定义登录成功的结果处理
  • 自定义登录失败的结果处理
  • 自定义权限访问异常结果处理


默认登录成功失败跳转页


如果我们 登录成功,由接口AuthenticationSuccessHandler进行登录结果处理,默认会使用SimpleUrlAuthenticationSuccessHandler,是AuthenticationSuccessHandler的实现类,SimpleUrlAuthenticationSuccessHandler核心代码如下

public class SimpleUrlAuthenticationSuccessHandler extends AbstractAuthenticationTargetUrlRequestHandler
  implements AuthenticationSuccessHandler {
 @Override
 public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
   Authentication authentication) throws IOException, ServletException {
  handle(request, response, authentication);
  clearAuthenticationAttributes(request);
 }
}


在抽象类AbstractAuthenticationTargetUrlRequestHandler,我们可以发现,其默认**defaultTargetUrl = /**,核心代码如下


在本例子中我们的**/页面为inxde.html**,实现代码如下

 // 首页
 @RequestMapping({"/index", "/", ""})
 public String index() {
 return "index";
 }


因此登录成功后跳转到http://localhost:8080/,**如果我们不想默认跳转页面为/**,我们可以进行设置,如下图所示


03cc28cb2ee0c082b8f8ef2c314c8612.png


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


为什么自定义登录验证结果处理场景


  • 前后端分离,后端返回结果应该是JSON
  • 实现千人千面(不同的人,登录后向不同的页面跳转)


自定义登录成功的结果处理


AuthenticationSuccessHandler完成登录成功处理

  • 创建MyAuthenticationSuccessHandler类直接实现AuthenticationSuccessHandler接口

注意:实现类上不要少了注解 @Component注解

@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
    private  static ObjectMapper objectMapper = new ObjectMapper();
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
                                        HttpServletResponse response,
                                        Authentication authentication) throws IOException, ServletException {
        // 当认证成功后,响应 JSON 数据给前端
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(objectMapper.writeValueAsString("test登录成功"));
    }
}



在 LearnSrpingSecurity中注入 和 引用自定义认证成功处理器 MyAuthenticationSuccessHandler,实现代码如下

  • 测试


重启项目,访问http://localhost:8080跳转到登录页面,登录成功后结果为

继承SavedRequestAwareAuthenticationSuccessHandler实现登录成功处理


继承SavedRequestAwareAuthenticationSuccessHandler 类的话,他会记住我们上一次请求的资源路径,比如:用户请求syslog.html,没有登录所以被拦截到了登录页,当你登录成功之后会自动跳转到syslog.html,而不是主页面。代码实现如下

@Component
public class MySavedRequestAwareAuthenticationSuccessHandler  extends SavedRequestAwareAuthenticationSuccessHandler {
    //在application配置文件中配置登录的类型是JSON数据响应还是做页面响应
    @Value("${login.success.type}")
    private String loginType;
    //Jackson JSON数据处理类
    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("test Saved 登录成功"));
        } else {
            // 会帮我们跳转到上一次请求的页面上
            super.onAuthenticationSuccess(request, response, authentication);
        }
    }
}


在application.properties中配置login.success.type

login.success.type=HTML #设置为html或者json,如果为json返回json


  • 测试

使用浏览器访问http://localhost:8080/sysuser,登录成功后,页面显示为

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

AuthenticationFailureHandler实现登录失败验证

  • 创建MyAuthenticationFailureHandler类实现AuthenticationFailureHandler接口

注意:实现类上不要少了注解 @Component注解

@Component
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {
    private  static ObjectMapper objectMapper = new ObjectMapper();
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        // 当认证失败后,响应 JSON 数据给前端
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(objectMapper.writeValueAsString("test登录失败"));
    }
}



  • 在 LearnSrpingSecurity中注入 和 引用自定义认证成功处理器 MyAuthenticationFailureHandler,实现代码如下

  • 测试


访问http://localhost:8080/login/form,输入错误的用户名和密码,结果如下

SimpleUrlAuthenticationFailureHandler 实现登录失败处理


继承SimpleUrlAuthenticationFailureHandler 类。该类中默认实现了登录验证失败的跳转逻辑,即登录失败之后回到登录页面。我们可以利用这一点简化我们的代码。实现代码如下

@Component
public class MySimpleUrlAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
    //在application配置文件中配置登录的类型是JSON数据响应还是做页面响应
    @Value("${login.success.type}")
    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("用户名或密码存在错误,请检查后再次登录"));
        } else {
            response.setContentType("text/html;charset=UTF-8");
            super.onAuthenticationFailure(request, response, exception);
        }
    }
}


其他步骤和AuthenticationFailureHandler实现登录失败验证的步骤一致。

自定义权限访问异常结果处理


除了登录成功、登录失败的结果处理,Spring Security还为我们提供了其他的结果处理类。比如用户未登录就访问系统资源

AuthenticationEntryPoint 用来解决匿名用户访问无权限资源时的异常

  • 代码实现如下

注意:实现类上不要少了注解 @Component注解

@Component
public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint {
    //Jackson JSON数据处理类
    private  static ObjectMapper objectMapper = new ObjectMapper();
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response,
                         AuthenticationException authException) throws IOException, ServletException {
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/javascript;charset=utf-8");
        response.getWriter().print(objectMapper.writeValueAsString("没有访问权限!"));
    }
}


AccessDeniedHandler解决认证用户没有访问权限

注意:实现类上不要少了注解 @Component注解

@Component
public class MyAccessDeineHandler implements AccessDeniedHandler {
    //Jackson JSON数据处理类
    private  static ObjectMapper objectMapper = new ObjectMapper();
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/javascript;charset=utf-8");
        response.getWriter().print(objectMapper.writeValueAsString("认证用户没有访问权限!"));
    }
}



在 LearnSrpingSecurity中注入MyAccessDeineHandler和MyAuthenticationEntryPoint实现如下

如果您觉得本文不错,欢迎关注,点赞,收藏支持,您的关注是我坚持的动力!

目录
相关文章
|
6月前
|
前端开发 安全 Java
SpringBoot 实现登录验证码(附集成SpringSecurity)
SpringBoot 实现登录验证码(附集成SpringSecurity)
405 0
|
安全 NoSQL Java
SpringBoot3整合SpringSecurity,实现自定义接口权限过滤(二)
SpringBoot3整合SpringSecurity,实现自定义接口权限过滤
979 0
|
5月前
|
前端开发 Java
SpringSecurity6从入门到实战之默认登录页面的生成
本文介绍了SpringSecurity在SpringBoot项目中如何自动生成默认登录页面的过程。当访问如`/hello`的受保护路由时,请求会经过多个过滤器。在AuthorizationFilter中,未认证的请求会被拦截并抛出AccessDeniedException。接着,ExceptionTranslationFilter捕获此异常并启动身份验证,调用LoginUrlAuthenticationEntryPoint的commence方法,重定向到/login。DefaultLoginPageGeneratingFilter拦截/login请求,生成并返回默认的登录页面。
|
安全 Java 数据库连接
四.SpringSecurity基础-自定义登录流程
SpringSecurity基础-自定义登录流程
|
6月前
【SpringSecurity 】SpringSecurity 自定义登录页面
【SpringSecurity 】SpringSecurity 自定义登录页面
105 0
|
6月前
|
存储 Java Maven
springboot项目中使用shiro 自定义过滤器和token的方式
springboot项目中使用shiro 自定义过滤器和token的方式
140 1
|
存储 前端开发 Java
SpringBoot实现简单的登录验证码
SpringBoot实现简单的登录验证码
371 0
|
存储 NoSQL Java
SpringBoot自定义实现类似jwt权限验证效果
SpringBoot自定义实现类似jwt权限验证效果
85 0
|
SQL 安全 Java
SpringBoot 整合SpringSecurity示例实现前后分离权限注解+JWT登录认证
SpringSecurity是一个用于Java 企业级应用程序的安全框架,主要包含用户认证和用户授权两个方面.相比较Shiro而言,Security功能更加的强大,它可以很容易地扩展以满足更多安全控制方面的需求,但也相对它的学习成本会更高,两种框架各有利弊.实际开发中还是要根据业务和项目的需求来决定使用哪一种.
SpringBoot 整合SpringSecurity示例实现前后分离权限注解+JWT登录认证
|
存储 安全 Java
二.SpringSecurity基础-简单登录实现
SpringSecurity基础-简单登录实现