zoukankan      html  css  js  c++  java
  • SpringSecurity5 (2) ——自定义登录页面

    一、自定义登录页面

    在实际项目开发中,根据需求设计业务系统的登录界面,不会使用security提供的默认登录页面,本文使用SpringBoot集成thymeleaf开发前端页面。

    (一)开发登录页面

    在resources目录下新建目录templates,存放模板文件,按照实际需求开发login.html,登录页面的用户名和密码的登录框name需要使用usernamepassword,如果需要改动,需要修改配置类。

    <div><label> 用户名 : <input type="text" name="username"/> </label></div>
    <div><label> 密码: <input type="password" name="password"/> </label></div>
    

    (二)引入依赖

    引入thymeleaf模板引擎依赖

        <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-thymeleaf</artifactId>
       </dependency>
    

    (三)开发Controller

    新建一个LoginController,跳转到login.html页面

    @Controller
    public class LoginController {
        @GetMapping("/login")
        public  String  skipLogin(){
            return "login";
        }
    
    }
    

    (四)修改配置类

    在Java配置文件中修改以下方法,新增login()配置和defaultSuccessUrl()配置

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .authorizeRequests()
                    .antMatchers("/hello/admin").hasRole("ROOT")
                    .antMatchers("/hello").hasRole("USER").anyRequest().permitAll()
                    .and()
                    .csrf().disable().
                    formLogin().loginPage("/login")  //自定义登录页面跳转
                    .defaultSuccessUrl("/hello")//登录成功后跳转
                    .and().httpBasic().disable()
                    .sessionManagement().disable()
                    .cors()
                    .and()
                    .logout();
        }
    
    /***
    defaultSuccessUrl 就是说,它会默认跳转到 Referer 来源页面,如果 Referer 为空,没有来源页,则跳转到默认设置的页面。如果有Referer则跳转到referer页面
    
    successForwardUrl 表示不管你是从哪里来的,登录后一律跳转到 successForwardUrl 指定的地址。例如 successForwardUrl 指定的地址为 /index ,
    **/
    

    二、自定义登录成功、失败及退出逻辑

    未登录时,我们访问后台接口服务/hello或者/hello/admin时,security会重定向到登录页面,当我们登录成功后,页面会重定向到登录前访问的url,可以查看上面defaultSuccessUrl和successForwardUrl的区别。

    目前很多系统使用前后端分离方案,登录成功后,前端要求返回JSON字符串并把相应的信息存储到localStorage中,后续直接从取本地取出使用。

    (一)开发登录成功逻辑

    实现AuthenticationSuccessHandler接口,重写onAuthenticationSuccess方法,登录成功后不再重定向到/hello接口,直接往前台返回相应JSON字符串

    @Component
    public class AuthSuccessHandler implements AuthenticationSuccessHandler {
    
        @Override
        public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
                throws IOException, ServletException {
                //处理登录成功逻辑
            response.setHeader("Content-Type", "application/json;charset=utf-8");
            String jsonStr = "{username:"张三",token:"avasdaeawaweqwe123123asdad1231dasdasd"}";
                        response.getWriter().print(jsonStr);
                        response.getWriter().flush();
        }
    }
    

    登录成功后如下图所示

    image-20200701170057728

    (二)开发登录失败逻辑

    实现AuthenticationFailureHandler接口,重写onAuthenticationFailure方法,认证失败不在返回到登录页面(/login?error)直接往前台返回相应JSON字符串

    @Component
    public class AuthFailureHandler implements AuthenticationFailureHandler {
        @Override
        public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
                throws IOException, ServletException {
            //处理认证失败逻辑
            response.setHeader("Content-Type", "application/json;charset=utf-8");
            String jsonStr = "{code:"400",message:"认证失败"}";
            response.getWriter().print(jsonStr);
            response.getWriter().flush();
        }
    }
    

    (三)开发退出逻辑

    @Component
    public class AuthLogoutHandler implements LogoutHandler {
        @Override
        public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
        {
            /**
            	根据实际需求编写实际代码,可以是删除缓存中用户信息返回登录页面,或者是重定向到其他页面等
            	等,在此为了简便,后台打印一句话,向浏览器输出字符串。
            **/
            
            UserDetails user = (UserDetails) authentication.getPrincipal();
            System.out.println("删除用户信息"+user.getUsername());
            response.setHeader("Content-Type", "application/json;charset=utf-8");
            try {
                response.getWriter().print("缓存中用户信息已删除");
                response.getWriter().flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    (四)修改配置类

    注入上面登录成功及失败的逻辑类

    @Autowired
    private AuthSuccessHandler  authSuccessHandler;
    
    @Autowired
    private AuthFailureHandler  authFailureHandler;
    
    @Autowired
    private AuthLogoutHandler authLogoutHandler;
    

    增加successHandlerfailureHandler配置

       @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .authorizeRequests()
                    .antMatchers("/hello/admin").hasRole("ROOT")
                    .antMatchers("/hello").hasRole("USER").anyRequest().permitAll()
                    .and()
                    .csrf().disable().
                    formLogin().loginPage("/login")  //自定义登录页面跳转
                    .defaultSuccessUrl("/hello")
                    .successForwardUrl("/hello/admin")//登录成功后跳转
                    .successHandler(authSuccessHandler)
                    .failureHandler(authFailureHandler)
                    .and().httpBasic().disable()
                    .sessionManagement().disable()
                    .cors()
                    .and() //退出的路径及退出后的逻辑操作
                    .logout().logoutUrl("/logout").addLogoutHandler(authLogoutHandler);
        }
    

    (五)验证效果

    登录成功后效果:

    登录失败后效果:

    退出效果:
    因没有开发退出按钮,从登录页面登录成功后,在浏览器上访问/logout接口,看下退出效果,已经在页面上显示

  • 相关阅读:
    动态代理:JDK动态代理和CGLIB代理的区别
    spring启动component-scan类扫描加载,以及@Resource,postConstruct等等注解的解析生效源码
    spring启动component-scan类扫描加载过程---源码分析
    spring源码分析之spring-core asm概述
    Spring组件扫描 <context:component-scan/>
    【OSGI】1.初识OSGI-到底什么是OSGI
    superrvisor application config ini
    doris 0.9.0版本docker镜像制作与使用
    Docker系列09:搭建Harbor本地镜像仓库
    Docker系列08:容器监控
  • 原文地址:https://www.cnblogs.com/quartz/p/13228212.html
Copyright © 2011-2022 走看看