写了一个 SSO 单点登录的代码示例给胖友!
發(fā)危~
“摘要: 原創(chuàng)出處 http://www.iocoder.cn/Spring-Security/OAuth2-learning-sso/ 「芋道源碼」歡迎轉(zhuǎn)載,保留摘要,謝謝!
-
1. 概述
-
2. 搭建統(tǒng)一登錄系統(tǒng)
-
3. 搭建 XXX 系統(tǒng)
-
666. 彩蛋
“
本文在提供完整代碼示例,可見 https://github.com/YunaiV/SpringBoot-Labs 的 lab-68-spring-security-oauth 目錄。
原創(chuàng)不易,給點個 Star 嘿,一起沖鴨!
1. 概述
在前面的文章中,我們學習了 Spring Security OAuth 的簡單使用。
-
《芋道 Spring Security OAuth2 入門》
-
《芋道 Spring Security OAuth2 存儲器》
今天我們來搞波“大”的,通過 Spring Security OAuth 實現(xiàn)一個單點登錄的功能。
可能會有女粉絲不太了解單點登錄是什么?單點登錄,英文是?Single Sign On,簡稱為?SSO,指的是當有多個系統(tǒng)需要登錄時,用戶只需要登錄一個統(tǒng)一的登錄系統(tǒng),而無需在多個系統(tǒng)重復登錄。
舉個最常見的例子,我們在瀏覽器中使用阿里“全家桶”:
“求助信:麻煩有認識阿里的胖友,讓他們給打下錢。。。
-
淘寶:https://www.taobao.com
-
天貓:https://www.tmall.com
-
飛豬:https://www.fliggy.com
-
...
我們只需要在統(tǒng)一登錄系統(tǒng)(https://login.taobao.com)進行登錄即可,而后就可以“愉快”的自由剁手,并且無需分別在淘寶、天貓、飛豬等等系統(tǒng)重新登錄。
登錄系統(tǒng)?
“友情提示:更多單點登錄的介紹,可見《維基百科 —— 單點登錄》。
下面,我們正式搭建 Spring Security OAuth 實現(xiàn) SSO 的示例項目,如下圖所示:
項目結(jié)構(gòu)?
-
創(chuàng)建?lab-68-demo21-authorization-server-on-sso?項目,作為統(tǒng)一登錄系統(tǒng)。
“旁白君:機智的胖友,是不是發(fā)現(xiàn)這個項目和授權(quán)服務(wù)器非常相似!!!
-
創(chuàng)建?lab-68-demo21-resource-server-on-sso?項目,模擬需要登錄的?XXX 系統(tǒng)。
“旁白君:機智的胖友,是不是發(fā)現(xiàn)這個項目和資源服務(wù)器非常相似!!!
2. 搭建統(tǒng)一登錄系統(tǒng)
“示例代碼對應倉庫:
-
統(tǒng)一登錄系統(tǒng):lab-68-demo21-authorization-server-on-sso
創(chuàng)建?lab-68-demo21-authorization-server-on-sso?項目,作為統(tǒng)一登錄系統(tǒng)。
“友情提示:整個實現(xiàn)代碼,和我們前文看到的授權(quán)服務(wù)器是基本一致的。
2.1 初始化數(shù)據(jù)庫
在?resources/db?目錄下,有四個 SQL 腳本,分別用于初始化 User 和 OAuth 相關(guān)的表。
SQL 腳本?
2.1.1 初始化 OAuth 表
① 執(zhí)行?oauth_schema.sql?腳本,創(chuàng)建數(shù)據(jù)庫表結(jié)構(gòu)。
drop?table?if?exists?oauth_client_details; create?table?oauth_client_details?(client_id?VARCHAR(255)?PRIMARY?KEY,resource_ids?VARCHAR(255),client_secret?VARCHAR(255),scope?VARCHAR(255),authorized_grant_types?VARCHAR(255),web_server_redirect_uri?VARCHAR(255),authorities?VARCHAR(255),access_token_validity?INTEGER,refresh_token_validity?INTEGER,additional_information?VARCHAR(4096),autoapprove?VARCHAR(255) );create?table?if?not?exists?oauth_client_token?(token_id?VARCHAR(255),token?LONG?VARBINARY,authentication_id?VARCHAR(255)?PRIMARY?KEY,user_name?VARCHAR(255),client_id?VARCHAR(255) );create?table?if?not?exists?oauth_access_token?(token_id?VARCHAR(255),token?LONG?VARBINARY,authentication_id?VARCHAR(255)?PRIMARY?KEY,user_name?VARCHAR(255),client_id?VARCHAR(255),authentication?LONG?VARBINARY,refresh_token?VARCHAR(255) );create?table?if?not?exists?oauth_refresh_token?(token_id?VARCHAR(255),token?LONG?VARBINARY,authentication?LONG?VARBINARY );create?table?if?not?exists?oauth_code?(code?VARCHAR(255),?authentication?LONG?VARBINARY );create?table?if?not?exists?oauth_approvals?(userId?VARCHAR(255),clientId?VARCHAR(255),scope?VARCHAR(255),status?VARCHAR(10),expiresAt?TIMESTAMP?DEFAULT?CURRENT_TIMESTAMP,lastModifiedAt?TIMESTAMP?DEFAULT?CURRENT_TIMESTAMP );結(jié)果如下圖所示:
表結(jié)構(gòu)?
| oauth_access_token | OAuth 2.0?訪問令牌 |
| oauth_refresh_token | OAuth 2.0?刷新令牌 |
| oauth_code | OAuth 2.0?授權(quán)碼 |
| oauth_client_details | OAuth 2.0?客戶端 |
| oauth_client_token | ? |
| oauth_approvals | ? |
旁白君:這里的表結(jié)構(gòu)設(shè)計,我們可以借鑒參考,實現(xiàn)自己的 OAuth 2.0 的功能。
② 執(zhí)行?oauth_data.sql?腳本,插入一個客戶端記錄。
INSERT?INTO?oauth_client_details(client_id,?client_secret,?scope,?authorized_grant_types,web_server_redirect_uri,?authorities,?access_token_validity,refresh_token_validity,?additional_information,?autoapprove) VALUES('clientapp',?'112233',?'read_userinfo,read_contacts','password,authorization_code,refresh_token',?'http://127.0.0.1:9090/login',?null,?3600,?864000,?null,?true); “注意!這條記錄的?web_server_redirect_uri?字段,我們設(shè)置為 http://127.0.0.1:9090/login,這是稍后我們搭建的 XXX 系統(tǒng)的回調(diào)地址。
-
統(tǒng)一登錄系統(tǒng)采用 OAuth 2.0 的授權(quán)碼模式進行授權(quán)。
-
授權(quán)成功后,瀏覽器會跳轉(zhuǎn) http://127.0.0.1:9090/login 回調(diào)地址,然后 XXX 系統(tǒng)會通過授權(quán)碼向統(tǒng)一登錄系統(tǒng)獲取訪問令牌。
通過這樣的方式,完成一次單點登錄的過程。
結(jié)果如下圖所示:
oauth_client_details?表記錄?
2.1.2 初始化 User 表
① 執(zhí)行?user_schema.sql?腳本,創(chuàng)建數(shù)據(jù)庫表結(jié)構(gòu)。
DROP?TABLE?IF?EXISTS?`authorities`; CREATE?TABLE?`authorities`?(`username`?varchar(50)?NOT?NULL,`authority`?varchar(50)?NOT?NULL,UNIQUE?KEY?`ix_auth_username`?(`username`,`authority`) )?ENGINE=InnoDB?DEFAULT?CHARSET=utf8;DROP?TABLE?IF?EXISTS?`users`; CREATE?TABLE?`users`?(`username`?varchar(50)?NOT?NULL,`password`?varchar(500)?NOT?NULL,`enabled`?tinyint(1)?NOT?NULL,PRIMARY?KEY?(`username`) )?ENGINE=InnoDB?DEFAULT?CHARSET=utf8;結(jié)果如下圖所示:
表結(jié)構(gòu)?
| users | 用戶表 |
| authorities | 授權(quán)表,例如用戶擁有的角色 |
② 執(zhí)行?user_data.sql?腳本,插入一個用戶記錄和一個授權(quán)記錄。
INSERT?INTO?`authorities`?VALUES?('yunai',?'ROLE_USER');INSERT?INTO?`users`?VALUES?('yunai',?'112233',?'1');結(jié)果如下圖所示:
users?和?authorities?表記錄?
2.2 引入依賴
創(chuàng)建?pom.xml?文件,引入 Spring Security OAuth 依賴。
<?xml?version="1.0"?encoding="UTF-8"?> <project?xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0?http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>lab-68</artifactId><groupId>cn.iocoder.springboot.labs</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>lab-68-demo21-authorization-server-on-sso</artifactId><properties><!--?依賴相關(guān)配置?--><spring.boot.version>2.2.4.RELEASE</spring.boot.version><!--?插件相關(guān)配置?--><maven.compiler.target>1.8</maven.compiler.target><maven.compiler.source>1.8</maven.compiler.source></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>${spring.boot.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><!--?實現(xiàn)對?Spring?MVC?的自動配置?--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--?實現(xiàn)對?Spring?Security?OAuth2?的自動配置?--><dependency><groupId>org.springframework.security.oauth.boot</groupId><artifactId>spring-security-oauth2-autoconfigure</artifactId><version>${spring.boot.version}</version></dependency><!--?實現(xiàn)對數(shù)據(jù)庫連接池的自動化配置?--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency>?<!--?本示例,我們使用?MySQL?--><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.48</version></dependency></dependencies></project>2.3 配置文件
創(chuàng)建?application.yaml?配置文件,添加數(shù)據(jù)庫連接池的配置:
spring:#?datasource?數(shù)據(jù)源配置內(nèi)容,對應?DataSourceProperties?配置屬性類datasource:url:?jdbc:mysql://127.0.0.1:43063/demo-68-authorization-server-sso?useSSL=false&useUnicode=true&characterEncoding=UTF-8driver-class-name:?com.mysql.jdbc.Driverusername:?root?#?數(shù)據(jù)庫賬號password:?123456?#?數(shù)據(jù)庫密碼2.4 SecurityConfig
創(chuàng)建 SecurityConfig 配置類,通過?Spring Security?提供用戶認證的功能。代碼如下:
@Configuration @EnableWebSecurity public?class?SecurityConfig?extends?WebSecurityConfigurerAdapter?{/***?數(shù)據(jù)源?DataSource*/@Autowiredprivate?DataSource?dataSource;@Override@Bean(name?=?BeanIds.AUTHENTICATION_MANAGER)public?AuthenticationManager?authenticationManagerBean()?throws?Exception?{return?super.authenticationManagerBean();}@Beanpublic?static?NoOpPasswordEncoder?passwordEncoder()?{return?(NoOpPasswordEncoder)?NoOpPasswordEncoder.getInstance();}@Overrideprotected?void?configure(AuthenticationManagerBuilder?auth)?throws?Exception?{auth.jdbcAuthentication().dataSource(dataSource);}} “友情提示:如果胖友想要自定義用戶的讀取,可以參考《芋道 Spring Boot 安全框架 Spring Security 入門》文章。
2.5 OAuth2AuthorizationServerConfig
創(chuàng)建 OAuth2AuthorizationServerConfig 配置類,通過?Spring Security OAuth?提供授權(quán)服務(wù)器的功能。代碼如下:
@Configuration @EnableAuthorizationServer public?class?OAuth2AuthorizationServerConfig?extends?AuthorizationServerConfigurerAdapter?{/***?用戶認證?Manager*/@Autowiredprivate?AuthenticationManager?authenticationManager;/***?數(shù)據(jù)源?DataSource*/@Autowiredprivate?DataSource?dataSource;@Beanpublic?TokenStore?jdbcTokenStore()?{return?new?JdbcTokenStore(dataSource);}@Overridepublic?void?configure(AuthorizationServerEndpointsConfigurer?endpoints)?throws?Exception?{endpoints.authenticationManager(authenticationManager).tokenStore(jdbcTokenStore());}@Overridepublic?void?configure(AuthorizationServerSecurityConfigurer?oauthServer)?throws?Exception?{oauthServer.checkTokenAccess("isAuthenticated()");}@Beanpublic?ClientDetailsService?jdbcClientDetailsService()?{return?new?JdbcClientDetailsService(dataSource);}@Overridepublic?void?configure(ClientDetailsServiceConfigurer?clients)?throws?Exception?{clients.withClientDetails(jdbcClientDetailsService());}} “友情提示:如果胖友看不懂這個配置類,回到《芋道 Spring Security OAuth2 存儲器》文章復習下。
2.6 AuthorizationServerApplication
創(chuàng)建 AuthorizationServerApplication 類,統(tǒng)一登錄系統(tǒng)的啟動類。代碼如下:
@SpringBootApplication public?class?AuthorizationServerApplication?{public?static?void?main(String[]?args)?{SpringApplication.run(AuthorizationServerApplication.class,?args);}}2.7 簡單測試
執(zhí)行 AuthorizationServerApplication 啟動統(tǒng)一登錄系統(tǒng)。下面,我們使用 Postman 模擬一個 Client,測試我們是否搭建成功!
POST?請求 http://localhost:8080/oauth/token 地址,使用密碼模式進行授權(quán)。如下圖所示:
密碼模式成功獲取到訪問令牌,成功!
3. 搭建 XXX 系統(tǒng)
“示例代碼對應倉庫:
-
XXX 系統(tǒng):lab-68-demo21-resource-server-on-sso
創(chuàng)建?lab-68-demo21-resource-server-on-sso?項目,搭建?XXX 系統(tǒng),接入統(tǒng)一登錄系統(tǒng)實現(xiàn) SSO 功能。
“友情提示:整個實現(xiàn)代碼,和我們前文看到的資源服務(wù)器是基本一致的。
3.1 引入依賴
創(chuàng)建?pom.xml?文件,引入 Spring Security OAuth 依賴。
<?xml?version="1.0"?encoding="UTF-8"?> <project?xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0?http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>lab-68</artifactId><groupId>cn.iocoder.springboot.labs</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>lab-68-demo21-resource-server</artifactId><properties><!--?依賴相關(guān)配置?--><spring.boot.version>2.2.4.RELEASE</spring.boot.version><!--?插件相關(guān)配置?--><maven.compiler.target>1.8</maven.compiler.target><maven.compiler.source>1.8</maven.compiler.source></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>${spring.boot.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><!--?實現(xiàn)對?Spring?MVC?的自動配置?--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--?實現(xiàn)對?Spring?Security?OAuth2?的自動配置?--><dependency><groupId>org.springframework.security.oauth.boot</groupId><artifactId>spring-security-oauth2-autoconfigure</artifactId><version>${spring.boot.version}</version></dependency></dependencies></project>3.2 配置文件
創(chuàng)建?application.yaml?配置文件,添加?SSO?相關(guān)配置:
server:port:?9090servlet:session:cookie:name:?SSO-SESSIONID?#?自定義 Session 的 Cookie 名字,防止沖突。沖突后,會導致 SSO 登錄失敗。security:oauth2:#?OAuth2?Client?配置,對應?OAuth2ClientProperties?類client:client-id:?clientappclient-secret:?112233user-authorization-uri:?http://127.0.0.1:8080/oauth/authorize?#?獲取用戶的授權(quán)碼地址access-token-uri:?http://127.0.0.1:8080/oauth/token?#?獲取訪問令牌的地址#?OAuth2?Resource?配置,對應?ResourceServerProperties?類resource:token-info-uri:?http://127.0.0.1:8080/oauth/check_token?#?校驗訪問令牌是否有效的地址①?server.servlet.session.cookie.name?配置項,自定義 Session 的 Cookie 名字,防止沖突。沖突后,會導致 SSO 登錄失敗。
“友情提示:具體的值,胖友可以根據(jù)自己的喜歡設(shè)置。
②?security.oauth2.client?配置項,OAuth2 Client 配置,對應 OAuth2ClientProperties 類。在這個配置項中,我們添加了客戶端的?client-id?和?client-secret。
③?security.oauth2.client.user-authorization-uri?配置項,獲取用戶的授權(quán)碼地址。
在訪問 XXX 系統(tǒng)需要登錄的地址時,Spring Security OAuth 會自動跳轉(zhuǎn)到統(tǒng)一登錄系統(tǒng),進行統(tǒng)一登錄獲取授權(quán)。
而這里配置的?security.oauth2.client.user-authorization-uri?地址,就是之前授權(quán)服務(wù)器的?oauth/authorize?接口,可以進行授權(quán)碼模式的授權(quán)。
“友情提示:如果胖友忘記授權(quán)服務(wù)器的?oauth/authorize?接口,建議回看下《芋道 Spring Security OAuth2 入門》的「3. 授權(quán)碼模式」小節(jié)。
④?security.oauth2.client.access-token-uri?配置項,獲取訪問令牌的地址。
在統(tǒng)一登錄系統(tǒng)完成統(tǒng)一登錄并授權(quán)后,瀏覽器會跳轉(zhuǎn)回 XXX 系統(tǒng)的回調(diào)地址。在該地址上,會調(diào)用統(tǒng)一登錄系統(tǒng)的?security.oauth2.client.user-authorization-uri?地址,通過授權(quán)碼獲取到訪問令牌。
而這里配置的?security.oauth2.client.user-authorization-uri?地址,就是之前授權(quán)服務(wù)器的?oauth/token?接口。
⑤?security.oauth2.resource.client.token-info-uri?配置項,校驗訪問令牌是否有效的地址。
在獲取到訪問令牌之后,每次請求 XXX 系統(tǒng)時,都會調(diào)用?統(tǒng)一登錄系統(tǒng)的?security.oauth2.resource.client.token-info-uri?地址,校驗訪問令牌的有效性,同時返回用戶的基本信息。
而這里配置的?security.oauth2.resource.client.token-info-uri?地址,就是之前授權(quán)服務(wù)器的?oauth/check_token?接口。
至此,我們可以發(fā)現(xiàn),Spring Security OAuth 實現(xiàn)的 SSO 單點登錄功能,是基于其授權(quán)碼模式實現(xiàn)的。這一點,非常重要,稍后我們演示下會更加容易理解到。
3.3 OAuthSsoConfig
創(chuàng)建 OAuthSsoConfig 類,配置接入 SSO 功能。代碼如下:
@Configuration @EnableOAuth2Sso?//?開啟?Sso?功能 public?class?OAuthSsoConfig?{}在類上添加?@EnableOAuth2Sso?注解,聲明基于 Spring Security OAuth 的方式接入 SSO 功能。
“友情提示:想要深入的胖友,可以看看 SsoSecurityConfigurer 類。
3.4 UserController
創(chuàng)建 UserController 類,提供獲取當前用戶的?/user/info?接口。代碼如下:
@RestController @RequestMapping("/user") public?class?UserController?{@RequestMapping("/info")public?Authentication?info(Authentication?authentication)?{return?authentication;}}3.5 ResourceServerApplication
創(chuàng)建 ResourceServerApplication 類,XXX 系統(tǒng)的啟動類。代碼如下:
@SpringBootApplication public?class?ResourceServerApplication?{public?static?void?main(String[]?args)?{SpringApplication.run(ResourceServerApplication.class,?args);}}3.6 簡單測試(第一彈)
執(zhí)行 ResourceServerApplication 啟動 XXX 系統(tǒng)。下面,我們來演示下 SSO 單點登錄的過程。
① 使用瀏覽器,訪問?XXX 系統(tǒng)的 http://127.0.0.1:9090/user/info 地址。因為暫未登錄,所以被重定向到統(tǒng)一登錄系統(tǒng)的 http://127.0.0.1:8080/oauth/authorize?授權(quán)地址。
又因為在統(tǒng)一登錄系統(tǒng)暫未登錄,所以被重定向到統(tǒng)一登錄系統(tǒng)的 http://127.0.0.1:8080/login?登錄地址。如下圖所示:
登錄界面② 輸入用戶的賬號密碼「yunai/1024」,進行統(tǒng)一登錄系統(tǒng)的登錄。登錄完成后,進入統(tǒng)一登錄系統(tǒng)的 http://127.0.0.1:8080/oauth/authorize?授權(quán)地址。如下圖所示:
授權(quán)界面③ 點擊「Authorize」按鈕,完成用戶的授權(quán)。授權(quán)完成后,瀏覽器重定向到?XXX 系統(tǒng)的 http://127.0.0.1:9090/login?回調(diào)地址。
在?XX 系統(tǒng)的回調(diào)地址,拿到授權(quán)的授權(quán)碼后,會自動請求統(tǒng)一登錄系統(tǒng),通過授權(quán)碼獲取到訪問令牌。如此,我們便完成了?XXX 系統(tǒng)?的登錄。
獲取授權(quán)碼完成后,自動跳轉(zhuǎn)到登錄前的 http://127.0.0.1:9090/user/info 地址,打印出當前登錄的用戶信息。如下圖所示:
用戶信息?
如此,我們從統(tǒng)一登錄系統(tǒng)也拿到了用戶信息。下面,我們來進一步將 Spring Security 的權(quán)限控制功能來演示下。
3.7 SecurityConfig
創(chuàng)建 SecurityConfig 配置類,添加 Spring Security 的功能。代碼如下:
@Configuration @EnableGlobalMethodSecurity(prePostEnabled?=?true)?//?開啟對 Spring Security 注解的方法,進行權(quán)限驗證。 @Order(101)?//?OAuth2SsoDefaultConfiguration?使用了?Order(100),所以這里設(shè)置為?Order(101),防止相同順序?qū)е聢箦e public?class?SecurityConfig?extends?WebSecurityConfigurerAdapter?{ }在類上,增加?@EnableGlobalMethodSecurity?注解,開啟對 Spring Security 注解的方法,進行權(quán)限驗證。
3.8 DemoController
創(chuàng)建 DemoController 類,提供測試權(quán)限的功能的接口。代碼如下:
@RestController @RequestMapping("/demo") public?class?DemoController?{@GetMapping("/admin-list")@PreAuthorize("hasRole('ADMIN')")?//?要求管理員?ROLE_ADMIN?角色public?String?adminList()?{return?"管理員列表";}@GetMapping("/user-list")@PreAuthorize("hasRole('USER')")?//?要求普通用戶?ROLE_USER?角色public?String?userList()?{return?"用戶列表";}}因為當前登錄的用戶只有?ROLE_USE?角色,所以可以訪問?/demo/user-list?接口,無法訪問?/demo/admin-list?接口。
3.9 簡單測試(第二彈)
執(zhí)行 ResourceServerApplication?重啟?XXX 系統(tǒng)。下面,我們來演示下 Spring Security 的權(quán)限控制功能。
① 使用瀏覽器,訪問 http://127.0.0.1:9090/demo/user-list 地址,成功。如下圖所示:
成功訪問② 使用瀏覽器,訪問 http://127.0.0.1:9090/demo/admin-list 地址,失敗。如下圖所示:
失敗訪問?
666. 彩蛋
至此,我們成功使用 Spring Security OAuth 實現(xiàn)了一個 SSO 單點登錄的示例。下圖,是 SSO 的整體流程圖,胖友可以繼續(xù)深入理解下:
SSO 流程圖后續(xù),想要深入的胖友,可以看看 Spring Security OAuth 提供的如下兩個過濾器:
-
OAuth2ClientContextFilter
-
OAuth2ClientAuthenticationProcessingFilter
總結(jié)
以上是生活随笔為你收集整理的写了一个 SSO 单点登录的代码示例给胖友!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 日志系统新贵 Loki,真香!!
- 下一篇: GraphQL是什么“渣渣“?它想干掉R