1. 程式人生 > 程式設計 >springboot整合security和vue的實踐

springboot整合security和vue的實踐

目錄
  • 環境
  • 1.security參考資料
    • 認證流程原理:
  • 2.springboot整合security要點
    • 2.1獲取登入使用者資訊
    • 2.2自定義登入登出url
    • 2.3自定義Handler返回on
    • 2.4記住我功能
    • 2.5驗證碼功能
    • 2.6限制登入次數
    • 2.7密碼加密
    • 2.8後臺提供介面,返回前端json,整合做前端登入登出
  • 3.測試

    環境

    springboot1.5.9

    完整程式碼,內有sql,先建庫,在執行sql建表,sql中已插入測試的資料。

    https://.com/2010yhh/springBoot-demos/tree/master/springboot-security

    在這裡插入圖片描述

    訪問首頁:http://localhost:8080

    1.security參考資料

    Spring Security參考文件:https://docs.spring.io/spring-security/site/docs/4.1.0.RELEASE/reference/htmlsingle/#what-is-acegi-security

    spring-security原始碼:https://github.com/spring-projects/spring-security/

    主要功能:認證和授權

    ConfigurerFilter功能說明

    CorsConfigurerCorsFilter提供跨域訪問配置支援的Filter

    SessionManagementConfigurerSessionManagementFilter會話管理Filter

    RememberMeConfigurerRememberMeAuthenticationFilter記住使用者名稱及密碼功能支援
    ExpressionUrlAuthorizationConfigurer

    CsrfConfigurerCsrfFilter跨站請求偽造保護Filter;

    LogoutConfigurerLogoutFilter退出登入請求處理Filter

    FormLoginConfigurerUsernamePasswordAuthenticationFilter表單登入請求處理Filter

    OAuth2LoginConfigurerOAuth2AuthorizationRequestRedirectFilterOAuth2請求許可權控制處理Filter,為其它提供本網站Oauth2方式登入,即其它網站通過本網站的賬戶密碼進行登入授權

    HttpBasicConfigurerBasicAuthenticationFilterSecurity基礎登入授權Filter,將其結果儲存在SecurityContextHolder中

    認證流程原理:

    參考:https://www.processon.com/view/link/5ac1e565e4b00dc8a026ab46

    2.springboot整合security要點

    主要是class WebSecurityConfig extends WebSecurityConfigurerAdapter

    SecurityConfig配置資訊,參考程式碼中的WebSecurityConfig類

    2.1獲取登入使用者資訊

     UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext()
                    .getAuthentication()
                    .getPrincipal();
    

    2.2自定義登入登出url

    1)SecurityConfig配置中配置:

      .and()
                    .formLogin()
                    //指定url,可由相應的controller處理跳轉到登入頁如login_page.html
                    .loginPage("/mylogin")//自定義登入url
                    //指定自定義form表單請求的路徑
                    .loginProcessingUrl("/myloginForm").usernameParameter("userName").passwordParameter("passWord")
                    //.defaultSuccessUrl("/success")
                    .successForwardUrl("/success")//設定了登入登出的Handler,優先響應Handler
                    .failureUrl("/fail")//設定了登入登出的Handler,優先響應Handler
    
     .and()
                    .logout()
                    .logoutUrl("/mylogout")//自定義退出url
                    .logoutSuccessUrl("/mylogin")
                    .logoutSuccessHandler(myLogoutSuccessHandle)//設定了登入登出的Handler,優先響應Handler
                    .invalidateHttpSession(true)
                    .permitAll()
    

    2)前端請求中改寫請求的url

    如vue請求:

    export const login = data => {
      return http.post(`/myloginForm?userName=${data.userName}&passWord=${data.passWord}&rememberMe=${data.rememberMe}&imageCode=${data.imageCode}`)
    }
    export const logout = data => {
      return http.post(`/mylogout`)
    }
    

    如一般html表單請求:

    <!--要與.loginProcessingUrl("/myloginForm")相對應-->
    <form name="f" action="/myloginForm" method="post">
        <br/>
        使用者名稱:
        <input type="text" n客棧ame="userName" placeholder="name"><br/>
        密碼:
        <input type="password" name="passWord" placeholder="password"><br/>
        <input type="text" name="imageCode">
        <img src="/createImageCode"><br/>
        <input type="checkbox" name="rememberMe"/>下次自動登入<br/>
        <input name="submit" type="submit" value="提交">
    </form>
    <form action="/mylogout" method="post">
        <input type="submit" class="btn btn-primary" value="登出"/><!-- 5 -->
    </form>
    

    2.3自定義Handler返回json

    1)重寫AuthenticationSuccessHandler、AuthenticationFailureHandler、LogoutSuccessHandler、AccessDeniedHandler、AuthenticationEntryPoint 這5個類,分別是登入成功、登入失敗、退出成功、許可權不足、尚未登入,在這幾個重寫類中自定義返回json格式

    2)SecurityConfig配置中配置;

    //自定義認證成功或者失敗的返回json
                    .successHandler(myAuthenticationSuccessHandler)
                    .failureHandler(myAuthenticationFailureHandler)
      www.cppcns.com              
    .logoutSuccessHandler(myLogoutSuccessHandle)//設定了登入登出的Handler,優先響應Handler
                   
    
      http.exceptionHandling().authenticationEntryPoint(myAuthenticationEntryPoint);//未登入
            http.exceptionHandling().accessDeniedHandler(myAccessDeniedHandler); // 無權訪問
    

    2.4記住我功能

    關掉瀏覽器,重新開啟登入url,無需登入直接跳轉到首頁或其他頁面

    1)SecurityConfig配置中配置

    .and()
                    .rememberMe()// 記住我
                    .rememberMeParameter("rememberMe")
                    .tokenRepository(persistentTokenRepository())
                    .userDetailsService(myUserDetailsService).tokenValiditySeconds(60 * 60 * 24);
    

    2)SecurityConfig配置中配置寫token入的bean

    /**
         * springSecurity會根據情況自動將token插入persistent_logins
         *
         * @return
         */
        @Bean
        public PersistentTokenRepository persistentTokenRepository() {
            JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
            tokenRepository.setDataSource(dataSource);
            return tokenRepository;
        }
    

    2.5驗證碼功能

    1)自定義驗證碼過濾器,在其中驗證輸入的驗證碼和儲存在session中的驗證碼是否一致

    2)SecurityConfig配置中配置

    //將我們自定義的驗證碼過濾器,配置
    //UsernamePasswordAuthenticationFilter之前http.addFilterBefore(validateCodeFilter,UsernamePasswordAuthenticationFilter.class)
    

    2.6限制登入次數

    1)自定義登入成功、登入失敗的事件監聽器

    public class AuthenticationSuccessEventListener implements ApplicationListener<AuthenticationSuccessEvent>
    {}
    public class AuthenticationFailureListener implements ApplicationListener<AuthenticationFailureBadCredentialsEvent> {}
    

    2)可以利用資料庫或者redis或者換成來儲存登入失敗次數進行判斷鎖定賬號

    3)實際專案管理員角色應該有解鎖賬號的功能

    2.7密碼加密

    1)新建使用者時,儲存密碼為加密後的,本文使用BCryptPasswordEncoder

    2)執行登入的過程中:security內部會對輸入的密碼加密和查詢得到的使用者的密碼進行校驗

    2.8後臺提供介面,返回前端json,整合vue做前端登入登出

    這也是前後端分離的模式。

    前端可以先獲取當前登入使用者的所有角色及所有許可權(許可權可以細化到選單、按鈕和介面):進而決定前端顯示效果

    注意前端請求的url寫法:

    export const login = data => {
      return http.post(`/myloginForm?userName=${data.userName}&passWord=${data.passWord}&rememberMe=${data.rememberMe}&imageCode=${data.imageCode}`)
    }
    export const logout = data => {
      return http.post(`/mylogout`)
    }
    

    3.測試

    三個使用者:admin manager user2進行測試,本程式碼中許可權沒有用,只用到了角色這一級別。測試記住我功能時,要清除cookie,免得影響測試。

    使用者 角色 許可權
    admin admin manager user add delete query queryall update
    manager manager user query queryall
    user2 user query

    對http://localhost:8080/user/list http://localhost:8080/user/list2 http://localhost:8080/user/list3(無需登入都可以訪問) 三個url設定不同的角色

    .antMatchers( "/user/list").hasAuthority("admin")
                    .antMatchers( "/user/list2").hasRole("manager")
    

    輸入:http://localhost:8080 重定向到登入頁:http://localhost:8080/#/login

    2)輸入admin manager user2 的正確使用者名稱和密碼後,登入成功返回的頁面顯示不同效果;三個使用者登入成功後,直接訪問url,會根據使用者的角色不同進行攔截,點選退出後,重新回到http://localhost:8080/#/login

    user2:

    在這裡插入圖片描述

    直接訪問url:http://localhost:8080/user/list

    在這裡插入圖片描述

    manager:

    在這裡插入圖片描述

    直接訪問url:http://localhost:8080/user/www.cppcns.comlist

    在這裡插入圖片描述

    admin:

    在這裡插入圖片描述

    直接訪問url:http://localhost:8080/user/list

    在這裡插入圖片描述

    直接訪問登出url:

    在這裡插入圖片描述

    4)測試記住我
    用admin使用者測試
    這裡關閉瀏覽器或者重啟程序後,直接訪問需要角色的資源如:http://localhost:8080/#/home或者http://localhost:8080/user/list

    可以直接訪問無需登入。

    springboot整合security和vue的實踐

    在這裡插入圖片描述

    但是訪問首頁http://localhost:8080 或者http://localhost:8080/#/login卻不能跳轉到http://localhost:8080/#/home

    5)測試驗證碼

    驗證碼過期或者輸錯或者重新整理頁面,會重新生成驗證碼。

    在這裡插入圖片描述

    6)測試限制登入次數

    在輸入正確驗證碼的情況下,輸錯驗證碼會直接丟擲驗證碼的異常,連續輸錯3次(可以設定)使用者名稱或者密碼,賬號會鎖定,丟擲賬號鎖定異常。

    在這裡插入圖片描述

    在這裡插入圖片描述

    到此這篇關於springboot整合security和vue的實踐的文章就介紹到這了,更多相關springboot整合security和vue內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!