Spring Security 的登錄密碼驗證過程 UsernamePasswordAuthenticationFilter


 

認證過程如下

一、先判斷請求(請求必須是post請求)地址是否為配置的 login-processing-url 值(默認/j_spring_security_check),如果不是,則放行,進入下一個過濾器,是則進行校驗。

二、驗證用戶密碼信息並返回Authentication類,在驗證過程中如果失敗則捕獲異常進行處理(執行unsuccessfulAuthentication方法調轉到配置中的錯誤鏈接),如果驗證成功,則將調用SessionAuthenticationStrategy中的方法onAuthentication()判斷用戶能否重復登陸,是否二次登陸——根據你的配置文件決定,如果用戶登陸滿足條件則再執行successfulAuthentication(配置中的驗證成功鏈接),如果失敗則還是執行unsuccessfulAuthentication方法

詳細說明:

1、用戶密碼認證過程

    AbstractAuthenticationProcessingFilter.doFilter()調用UsernamePasswordAuthenticationFilter中的attemptAuthentication方法,

    

    UsernamePasswordAuthenticationFilter中的attemptAuthentication方法將表單請求的信息(用戶、密碼等信息)賦值給UsernamePasswordAuthenticationToken(authRequest),

    然后調用getAuthenticationManager().authenticate(authRequest)對用戶密碼的正確性進行驗證,認證失敗就拋出異常,成功就返回Authentication對象。

    

AuthenticationManager就是認證管理器,它的方法authenticate執行邏輯如下(默認配置DaoAuthenticationProvider,以DaoAuthenticationProvider為例):

(1)、判斷是否有Authentication 對應的AuthenticationProvider,

           有就執行AuthenticationProvider的authenticate方法,

           沒有就獲取父類AuthenticationManager,查看父類中是否有Authentication 對應的AuthenticationProvider,

                  如果也沒有則拋出ProviderNotFoundException異常

(2)執行AuthenticationProvider的authenticate方法

        1、根據輸入名,查看緩存中是否已經有有用戶實體對象

             如果有,則對密碼重新驗證;

             如果沒有,則進行用戶的信息驗證,執行DaoAuthenticationProvider中的retrieveUser方法,獲取一個UserDetails對象

                    如果UserDetails對象為null或者獲取時出錯就拋出異常UsernameNotFoundException或AuthenticationServiceException異常,

                    然后一些屬性驗證之后,對用戶密碼進行驗證。

        2、給新獲取的UserDetails對象放入緩存中

        3、新建一個UsernamePasswordAuthenticationToken一個對象,將authenticated設為true(原來傳入的UsernamePasswordAuthenticationToken對象authenticated為false)並返回

 

2、SessionAuthenticationStrategy.onAuthentication處理過程(主要處理一個用戶是否可以同時多次登陸)

    1、checkAuthenticationAllowed方法

         根據maximumSessions和exceptionIfMaximumExceeded的設置判斷

             用戶是否多次登陸,

             是否超過maximumSessions同時登陸了,

             是否限制用戶二次登陸(限制的話則第二次登陸的時候會拋出SessionAuthenticationException異常)還是第二次登陸使第一次登陸無效

    2、復制一個新的session,擁有新的sessionID

   3、更新SessionRegistry中的ConcurrentMap<Object,Set<String>> principals和Map<String, SessionInformation> sessionIds,這個是在第三個過濾器中ConcurrentSessionFilter需要使用的

2018-03-29總結


AuthenticationManager調用Provider,provider調用userDetaisService來根據username獲取真實的數據庫信息。 而在usernamePasswordAuthenticationFilter中來調用的是AuthenticationManager。。這個流程雖然沒多么復雜,但是花費我不少時間給理解到了。。。


免責聲明!

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



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