spring security登錄認(rèn)證授權(quán)的項目實踐
是什么
Spring Security 主要實現(xiàn)了Authentication(認(rèn)證,解決who are you? ) 和 Access Control(訪問控制,也就是what are you allowed to do?,也稱為Authorization)。Spring Security在架構(gòu)上將認(rèn)證與授權(quán)分離,并提供了擴(kuò)展點
使用-1 快速開始 引入依賴,出現(xiàn)登錄頁面
<!-- 實現(xiàn)對 Spring MVC 的自動化配置 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 實現(xiàn)對 Spring Security 的自動化配置 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
自定義登錄的用戶名密碼(練手)
配置類繼承適配器 WebSecurityConfigurerAdapter, 重寫configure方法,實現(xiàn)UserDetailsService接口,設(shè)置用戶名,密碼
從數(shù)據(jù)庫讀取密碼
配置類繼承適配器 WebSecurityConfigurerAdapter, 重寫configure方法,實現(xiàn)UserDetailsService接口,調(diào)用UserDetailsService的已有的實現(xiàn)類,或者調(diào)用自定義的類,實現(xiàn)了UserDetailsService實現(xiàn)類接口,重寫loadUserByUsername方法(數(shù)據(jù)庫查登錄的用戶名密碼)
認(rèn)證邏輯
認(rèn)證邏輯:SecurityContextPersistenceFilter Security上下文持久化過濾器拿到登錄信息,生成session存儲 ->SecurityContextHolderStrategy 策略 ->ThreadLocalSecurityContextHolderStrategy 用的ThreadLocal
AbstractAuthenticationProcessingFilter 的 doFilter方法->attemptAuthentication方法->AuthenticationManager接口的authenticate接口方法
->retrieveUser->getUserDetailsService().loadUserByUsername(獲取到自定義的數(shù)據(jù)庫獲取用戶名密碼方法)–>authenticate方法中 調(diào)用additionalAuthenticationChecks
檢查用戶名密碼的準(zhǔn)確性–>正確的話就走認(rèn)證成功的邏輯,認(rèn)證成功后 ->SecurityContextHolder.getContext().setAuthentication設(shè)置登錄信息到上下文;錯誤就走認(rèn)真失敗的邏輯
自定義認(rèn)證成功失敗的處理
自定義登錄成功失敗邏輯(執(zhí)行方法步驟)原理:認(rèn)證成功后: successForwardUrl–>ForwardAuthenticationSuccessHandler->調(diào)用了AuthenticationSuccessHandler 的onAuthenticationSuccess 方法
因此可以實現(xiàn)AuthenticationSuccessHandler接口,重寫 onAuthenticationSuccess 方法
認(rèn)證失敗同理:failureForwardUrl->ForwardAuthenticationFailureHandler->調(diào)用了 ForwardAuthenticationFailureHandler的 onAuthenticationFailure 方法
因此可以實現(xiàn) ForwardAuthenticationFailureHandler接口,重寫 onAuthenticationFailure 方法
會話管理(session)
是什么?http請求是無狀態(tài)的,因此需要在瀏覽器和服務(wù)器端存儲狀態(tài),即會話。
tomcat 會生成session對象,響應(yīng)的時候會帶給客戶端存到瀏覽器的Cookie中,
下次再請求服務(wù)器時,帶上JSESSIONID,和服務(wù)器的JSESSIONID比對,相同的話響應(yīng),否則不響應(yīng)
原理 :SecurityContextHolder.getContext().getAuthentication()可以獲取到登錄信息,因為登錄的認(rèn)證信息存在 SecurityContext上下文中
AbstractAuthenticationProcessingFilter 的 doFilter方法 -> successfulAuthentication 認(rèn)證成功后 ->SecurityContextHolder.getContext().setAuthentication 登錄的認(rèn)證信息存在 SecurityContext上下文中
會話并發(fā)控制-spring security實現(xiàn)
同一個賬號只能同時登錄一次(后面登錄人把前面登錄人擠掉)—>可以用redis實現(xiàn),此處是用spring security實現(xiàn)
http.sessionManagement().maximumSessions(1)原理:AbstractAuthenticationProcessingFilter -> sessionStrategy.onAuthentication()-> ConcurrentSessionControlAuthenticationStrategy 的onAuthentication方法比較當(dāng)前登錄的session個數(shù)是否小于我們自己設(shè)置 -> 是的話就session 設(shè)置過期- >ConcurrentSessionFilter 并發(fā)session過濾器 -> doFilter方法 -> 沒有過期則登錄成功,否則走session過期策略
可自定義實現(xiàn)SessionInformationExpiredStrategy接口重寫onExpiredSessionDetected方法
問題:http.sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(true) //超過最大的登錄數(shù),阻止登錄
問題:我們在yml配置的http session設(shè)置的超時時間和內(nèi)部SessionInformation 是重新的一個session,超時時間和之前不同,導(dǎo)致http session設(shè)置的超時時間超時了,但是SessionInformation 沒超時會報多人同時登錄的錯誤最好不要用,可以用redis實現(xiàn)
會話并發(fā)控制-redis實現(xiàn)
實現(xiàn)原理:引入的spring session包中有個session倉庫的過濾器 SessionRepositoryFilter -> doFilter方法 ->commitSession ->sessionRepository.save(session)實現(xiàn)了重寫了RedisSessionRepository中save 方法,把session存到redis中
1.引入spring session依賴
<dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.1.0</version> </dependency>
2.修改application.yml
session: store-type: redis redis: host: localhost port: 6379
3.開啟多個項目實例即可測試
Remember me實現(xiàn)
設(shè)置數(shù)據(jù)源,Spring Security會自動把用戶信息存儲到數(shù)據(jù)源中,下次登錄直接比對數(shù)據(jù)庫值就ok
原理:RememberMeAuthenticationFilter -> doFilter方法 -> autoLogin ->AbstractRememberMeServices的autoLogin ->PersistentTokenBasedRememberMeServices 的processAutoLoginCookie 取出remember-me的值拆分為series和token 去數(shù)據(jù)庫根據(jù)series找到記錄,看token是否一致一致就調(diào)用 getUserDetailsService().loadUserByUsername方法,實現(xiàn)自動登錄
退出登錄
原理:LogoutFilter-> doFilter方法 -> SecurityContextLogoutHandler的logout方法,setAuthentication為null清除認(rèn)證狀態(tài),銷毀HTTPSession對象
SimpleUrlLogoutSuccessHandler的onLogoutSuccess 重定向到登錄頁面
csrf跨站請求偽造
從 Spring Security4開始CSRF防護(hù)默認(rèn)開啟,默認(rèn)會攔截請求,進(jìn)行CSRF處理。CSRF為了保證不是其他第三方網(wǎng)站訪問,要求訪問時攜帶參數(shù)名為 _csrf 值為token(token 在服務(wù)端產(chǎn)生,在渲染請求頁面時埋入頁面)的內(nèi)容,如果token和服務(wù)端的token匹配成功,則正常訪問。
原理:CsrfFilter -> doFilter方法 -> 如果沒有token 先生成一個,然后放到填充到CSRF_TOKEN中返回給頁面,會再走一遍doFilter方法去比對CSRF_TOKEN和服務(wù)端的token是否能匹配成功,成功則可以訪問,否則不能訪問
授權(quán)
這里是引用訪問控制url的匹配
antMatchers ant 表達(dá)式,統(tǒng)配符 ? 匹配任何單字符,* 匹配0或者任意數(shù)量的字符, ** 匹配0或者更多的目錄
hasAuthority 有…的角色權(quán)限
hasAnyAuthority 有多個角色權(quán)限,符合一個即可
自定義403處理方案
使用 Spring Security 時經(jīng)常會看見 403(無權(quán)限)。Spring Security 支持自定義權(quán)限受限處理,需要
實現(xiàn) AccessDeniedHandler接口
基于方法的授權(quán)
1.JSR250注解,可以定義在方法和類上面
配置類開啟@EnableGlobalMethodSecurity(jsr250Enabled = true,securedEnabled = true,prePostEnabled = true)
@RolesAllowed 訪問對應(yīng)方法時所應(yīng)該具有的角色
@PermitAll 不進(jìn)行權(quán)限控制
@DenyAll 無論什么角色都不能訪問
2.@Secured注解專門用于判斷是否具有角色的,能寫在方法或類上。參數(shù)要以 ROLE_開頭
配置類開啟@EnableGlobalMethodSecurity(jsr250Enabled = true,securedEnabled = true,prePostEnabled = true)
3.支持表達(dá)式注解
配置類開啟@EnableGlobalMethodSecurity(jsr250Enabled = true,securedEnabled = true,prePostEnabled = true)
使用@PreAuthorize和@PostAuthorize 在方法之前,之后進(jìn)行訪問控制
授權(quán)原理:FilterSecurityInterceptor -> doFilter方法 -> invoke-> beforeInvocation -> attemptAuthorization -> decide(AffirmativeBased) -> vote 投票是否通過授權(quán)通過則可以訪問資源,失敗則跳轉(zhuǎn)到登錄頁面認(rèn)證
到此這篇關(guān)于spring security登錄認(rèn)證授權(quán)的項目實踐的文章就介紹到這了,更多相關(guān)spring security登錄認(rèn)證授權(quán)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Spring Security 自定義短信登錄認(rèn)證的實現(xiàn)
- Springboot+Spring Security實現(xiàn)前后端分離登錄認(rèn)證及權(quán)限控制的示例代碼
- Java SpringSecurity+JWT實現(xiàn)登錄認(rèn)證
- SpringBoot security安全認(rèn)證登錄的實現(xiàn)方法
- SpringSecurity實現(xiàn)前后端分離登錄token認(rèn)證詳解
- Springboot整合SpringSecurity實現(xiàn)登錄認(rèn)證和鑒權(quán)全過程
- springsecurity實現(xiàn)用戶登錄認(rèn)證快速使用示例代碼(前后端分離項目)
- Spring Security實現(xiàn)登錄認(rèn)證實戰(zhàn)教程
- SpringSecurity 自定義認(rèn)證登錄的項目實踐
相關(guān)文章
Java多線程CountDownLatch的實現(xiàn)
本文主要介紹了Java多線程CountDownLatch的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02Mybatis不啟動項目直接測試Mapper的實現(xiàn)方法
在項目開發(fā)中,測試單個Mybatis Mapper方法通常需要啟動整個SpringBoot項目,消耗大量時間,本文介紹通過Main方法和Mybatis配置類,快速測試Mapper功能,無需啟動整個項目,這方法使用AnnotationConfigApplicationContext容器2024-09-09java算法題解LeetCode35復(fù)雜鏈表的復(fù)制實例
這篇文章主要為大家介紹了java算法題解LeetCode35復(fù)雜鏈表的復(fù)制實例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01jasypt對配置文件的數(shù)據(jù)加密與解密方式
這篇文章主要介紹了jasypt對配置文件的數(shù)據(jù)加密與解密方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01java統(tǒng)計字符串中重復(fù)字符出現(xiàn)次數(shù)的方法
這篇文章主要介紹了java統(tǒng)計字符串中重復(fù)字符出現(xiàn)次數(shù)的方法,涉及java針對字符串的遍歷與判斷相關(guān)操作技巧,需要的朋友可以參考下2016-08-08