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接口,看下退出效果,已經在頁面上顯示


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM