“摘要: 原創(chuàng)出處 http://www./Spring-Security/OAuth2-learning-sso/ 「芋道源碼」歡迎轉(zhuǎn)載,,保留摘要,,謝謝!
“本文在提供完整代碼示例,,可見(jiàn) https://github.com/YunaiV/SpringBoot-Labs 的 lab-68-spring-security-oauth 目錄,。
原創(chuàng)不易,給點(diǎn)個(gè) Star 嘿,,一起沖鴨,!
1. 概述
在前面的文章中,,我們學(xué)習(xí)了 Spring Security OAuth 的簡(jiǎn)單使用。
- 《芋道 Spring Security OAuth2 入門》
- 《芋道 Spring Security OAuth2 存儲(chǔ)器》
今天我們來(lái)搞波“大”的,,通過(guò) Spring Security OAuth 實(shí)現(xiàn)一個(gè)單點(diǎn)登錄的功能,。
可能會(huì)有女粉絲不太了解單點(diǎn)登錄是什么?單點(diǎn)登錄,,英文是 Single Sign On,,簡(jiǎn)稱為 SSO,指的是當(dāng)有多個(gè)系統(tǒng)需要登錄時(shí),,用戶只需要登錄一個(gè)統(tǒng)一的登錄系統(tǒng),而無(wú)需在多個(gè)系統(tǒng)重復(fù)登錄,。
舉個(gè)最常見(jiàn)的例子,,我們?cè)跒g覽器中使用阿里“全家桶”:
“求助信:麻煩有認(rèn)識(shí)阿里的胖友,讓他們給打下錢,。,。。
- 淘寶:https://www.taobao.com
我們只需要在統(tǒng)一登錄系統(tǒng)(https://login.taobao.com)進(jìn)行登錄即可,,而后就可以“愉快”的自由剁手,,并且無(wú)需分別在淘寶、天貓,、飛豬等等系統(tǒng)重新登錄,。
登錄系統(tǒng)“友情提示:更多單點(diǎn)登錄的介紹,可見(jiàn)《維基百科 —— 單點(diǎn)登錄》,。
下面,,我們正式搭建 Spring Security OAuth 實(shí)現(xiàn) SSO 的示例項(xiàng)目,如下圖所示:
項(xiàng)目結(jié)構(gòu)創(chuàng)建 lab-68-demo21-authorization-server-on-sso
項(xiàng)目,,作為統(tǒng)一登錄系統(tǒng),。
“旁白君:機(jī)智的胖友,是不是發(fā)現(xiàn)這個(gè)項(xiàng)目和授權(quán)服務(wù)器非常相似?。,。?/p>
創(chuàng)建 lab-68-demo21-resource-server-on-sso
項(xiàng)目,,模擬需要登錄的 XXX 系統(tǒng),。
“旁白君:機(jī)智的胖友,是不是發(fā)現(xiàn)這個(gè)項(xiàng)目和資源服務(wù)器非常相似?。,。?/p>
2. 搭建統(tǒng)一登錄系統(tǒng)
“示例代碼對(duì)應(yīng)倉(cāng)庫(kù):
- 統(tǒng)一登錄系統(tǒng):
lab-68-demo21-authorization-server-on-sso
創(chuàng)建 lab-68-demo21-authorization-server-on-sso
項(xiàng)目,,作為統(tǒng)一登錄系統(tǒng),。
“友情提示:整個(gè)實(shí)現(xiàn)代碼,和我們前文看到的授權(quán)服務(wù)器是基本一致的。
2.1 初始化數(shù)據(jù)庫(kù)
在 resources/db
目錄下,,有四個(gè) SQL 腳本,,分別用于初始化 User 和 OAuth 相關(guān)的表。
SQL 腳本2.1.1 初始化 OAuth 表
① 執(zhí)行 oauth_schema.sql
腳本,,創(chuàng)建數(shù)據(jù)庫(kù)表結(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 訪問(wèn)令牌 |
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è)計(jì),我們可以借鑒參考,,實(shí)現(xiàn)自己的 OAuth 2.0 的功能,。
② 執(zhí)行 oauth_data.sql
腳本,插入一個(gè)客戶端記錄,。
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
字段,我們?cè)O(shè)置為 http://127.0.0.1:9090/login,,這是稍后我們搭建的 XXX 系統(tǒng)的回調(diào)地址,。
- 統(tǒng)一登錄系統(tǒng)采用 OAuth 2.0 的授權(quán)碼模式進(jìn)行授權(quán)。
- 授權(quán)成功后,,瀏覽器會(huì)跳轉(zhuǎn) http://127.0.0.1:9090/login 回調(diào)地址,,然后 XXX 系統(tǒng)會(huì)通過(guò)授權(quán)碼向統(tǒng)一登錄系統(tǒng)獲取訪問(wèn)令牌。
通過(guò)這樣的方式,,完成一次單點(diǎn)登錄的過(guò)程,。
結(jié)果如下圖所示:
oauth_client_details
表記錄2.1.2 初始化 User 表
① 執(zhí)行 user_schema.sql
腳本,創(chuàng)建數(shù)據(jù)庫(kù)表結(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
腳本,插入一個(gè)用戶記錄和一個(gè)授權(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./POM/4.0.0'
xmlns:xsi='http://www./2001/XMLSchema-instance'
xsi:schemaLocation='http://maven./POM/4.0.0 http://maven./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>
<!-- 實(shí)現(xiàn)對(duì) Spring MVC 的自動(dòng)配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 實(shí)現(xiàn)對(duì) Spring Security OAuth2 的自動(dòng)配置 -->
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<!-- 實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)連接池的自動(dòng)化配置 -->
<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ù)庫(kù)連接池的配置:
spring:
# datasource 數(shù)據(jù)源配置內(nèi)容,對(duì)應(yīng) DataSourceProperties 配置屬性類
datasource:
url: jdbc:mysql://127.0.0.1:43063/demo-68-authorization-server-sso?useSSL=false&useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.jdbc.Driver
username: root # 數(shù)據(jù)庫(kù)賬號(hào)
password: 123456 # 數(shù)據(jù)庫(kù)密碼
2.4 SecurityConfig
創(chuàng)建 SecurityConfig 配置類,,通過(guò) Spring Security 提供用戶認(rèn)證的功能,。代碼如下:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 數(shù)據(jù)源 DataSource
*/
@Autowired
private DataSource dataSource;
@Override
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public static NoOpPasswordEncoder passwordEncoder() {
return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource);
}
}
“友情提示:如果胖友想要自定義用戶的讀取,可以參考《芋道 Spring Boot 安全框架 Spring Security 入門》文章,。
2.5 OAuth2AuthorizationServerConfig
創(chuàng)建 OAuth2AuthorizationServerConfig 配置類,,通過(guò) Spring Security OAuth 提供授權(quán)服務(wù)器的功能。代碼如下:
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
/**
* 用戶認(rèn)證 Manager
*/
@Autowired
private AuthenticationManager authenticationManager;
/**
* 數(shù)據(jù)源 DataSource
*/
@Autowired
private DataSource dataSource;
@Bean
public TokenStore jdbcTokenStore() {
return new JdbcTokenStore(dataSource);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager)
.tokenStore(jdbcTokenStore());
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.checkTokenAccess('isAuthenticated()');
}
@Bean
public ClientDetailsService jdbcClientDetailsService() {
return new JdbcClientDetailsService(dataSource);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(jdbcClientDetailsService());
}
}
“友情提示:如果胖友看不懂這個(gè)配置類,,回到《芋道 Spring Security OAuth2 存儲(chǔ)器》文章復(fù)習(xí)下,。
2.6 AuthorizationServerApplication
創(chuàng)建 AuthorizationServerApplication 類,,統(tǒng)一登錄系統(tǒng)的啟動(dòng)類。代碼如下:
@SpringBootApplication
public class AuthorizationServerApplication {
public static void main(String[] args) {
SpringApplication.run(AuthorizationServerApplication.class, args);
}
}
2.7 簡(jiǎn)單測(cè)試
執(zhí)行 AuthorizationServerApplication 啟動(dòng)統(tǒng)一登錄系統(tǒng),。下面,,我們使用 Postman 模擬一個(gè) Client,測(cè)試我們是否搭建成功,!
POST
請(qǐng)求 http://localhost:8080/oauth/token 地址,,使用密碼模式進(jìn)行授權(quán)。如下圖所示:
密碼模式成功獲取到訪問(wèn)令牌,,成功,!
3. 搭建 XXX 系統(tǒng)
“示例代碼對(duì)應(yīng)倉(cāng)庫(kù):
- XXX 系統(tǒng):
lab-68-demo21-resource-server-on-sso
創(chuàng)建 lab-68-demo21-resource-server-on-sso
項(xiàng)目,搭建 XXX 系統(tǒng),,接入統(tǒng)一登錄系統(tǒng)實(shí)現(xiàn) SSO 功能,。
“友情提示:整個(gè)實(shí)現(xiàn)代碼,和我們前文看到的資源服務(wù)器是基本一致的,。
3.1 引入依賴
創(chuàng)建 pom.xml
文件,引入 Spring Security OAuth 依賴,。
<?xml version='1.0' encoding='UTF-8'?>
<project xmlns='http://maven./POM/4.0.0'
xmlns:xsi='http://www./2001/XMLSchema-instance'
xsi:schemaLocation='http://maven./POM/4.0.0 http://maven./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>
<!-- 實(shí)現(xiàn)對(duì) Spring MVC 的自動(dòng)配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 實(shí)現(xiàn)對(duì) Spring Security OAuth2 的自動(dòng)配置 -->
<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: 9090
servlet:
session:
cookie:
name: SSO-SESSIONID # 自定義 Session 的 Cookie 名字,防止沖突,。沖突后,,會(huì)導(dǎo)致 SSO 登錄失敗。
security:
oauth2:
# OAuth2 Client 配置,,對(duì)應(yīng) OAuth2ClientProperties 類
client:
client-id: clientapp
client-secret: 112233
user-authorization-uri: http://127.0.0.1:8080/oauth/authorize # 獲取用戶的授權(quán)碼地址
access-token-uri: http://127.0.0.1:8080/oauth/token # 獲取訪問(wèn)令牌的地址
# OAuth2 Resource 配置,,對(duì)應(yīng) ResourceServerProperties 類
resource:
token-info-uri: http://127.0.0.1:8080/oauth/check_token # 校驗(yàn)訪問(wèn)令牌是否有效的地址
① server.servlet.session.cookie.name
配置項(xiàng),自定義 Session 的 Cookie 名字,,防止沖突,。沖突后,會(huì)導(dǎo)致 SSO 登錄失敗,。
“友情提示:具體的值,,胖友可以根據(jù)自己的喜歡設(shè)置。
② security.oauth2.client
配置項(xiàng),,OAuth2 Client 配置,,對(duì)應(yīng) OAuth2ClientProperties 類。在這個(gè)配置項(xiàng)中,,我們添加了客戶端的 client-id
和 client-secret
,。
③ security.oauth2.client.user-authorization-uri
配置項(xiàng),獲取用戶的授權(quán)碼地址,。
在訪問(wèn) XXX 系統(tǒng)需要登錄的地址時(shí),,Spring Security OAuth 會(huì)自動(dòng)跳轉(zhuǎn)到統(tǒng)一登錄系統(tǒng),,進(jìn)行統(tǒng)一登錄獲取授權(quán)。
而這里配置的 security.oauth2.client.user-authorization-uri
地址,,就是之前授權(quán)服務(wù)器的 oauth/authorize
接口,,可以進(jìn)行授權(quán)碼模式的授權(quán)。
“友情提示:如果胖友忘記授權(quán)服務(wù)器的 oauth/authorize
接口,,建議回看下《芋道 Spring Security OAuth2 入門》的「3. 授權(quán)碼模式」小節(jié),。
④ security.oauth2.client.access-token-uri
配置項(xiàng),獲取訪問(wèn)令牌的地址,。
在統(tǒng)一登錄系統(tǒng)完成統(tǒng)一登錄并授權(quán)后,,瀏覽器會(huì)跳轉(zhuǎn)回 XXX 系統(tǒng)的回調(diào)地址。在該地址上,,會(huì)調(diào)用統(tǒng)一登錄系統(tǒng)的 security.oauth2.client.user-authorization-uri
地址,,通過(guò)授權(quán)碼獲取到訪問(wèn)令牌。
而這里配置的 security.oauth2.client.user-authorization-uri
地址,,就是之前授權(quán)服務(wù)器的 oauth/token
接口,。
⑤ security.oauth2.resource.client.token-info-uri
配置項(xiàng),校驗(yàn)訪問(wèn)令牌是否有效的地址,。
在獲取到訪問(wèn)令牌之后,,每次請(qǐng)求 XXX 系統(tǒng)時(shí),都會(huì)調(diào)用 統(tǒng)一登錄系統(tǒng)的 security.oauth2.resource.client.token-info-uri
地址,,校驗(yàn)訪問(wèn)令牌的有效性,,同時(shí)返回用戶的基本信息。
而這里配置的 security.oauth2.resource.client.token-info-uri
地址,,就是之前授權(quán)服務(wù)器的 oauth/check_token
接口,。
至此,我們可以發(fā)現(xiàn),,Spring Security OAuth 實(shí)現(xiàn)的 SSO 單點(diǎn)登錄功能,,是基于其授權(quán)碼模式實(shí)現(xiàn)的。這一點(diǎn),,非常重要,,稍后我們演示下會(huì)更加容易理解到。
3.3 OAuthSsoConfig
創(chuàng)建 OAuthSsoConfig 類,,配置接入 SSO 功能,。代碼如下:
@Configuration
@EnableOAuth2Sso // 開(kāi)啟 Sso 功能
public class OAuthSsoConfig {
}
在類上添加 @EnableOAuth2Sso
注解,聲明基于 Spring Security OAuth 的方式接入 SSO 功能,。
“友情提示:想要深入的胖友,,可以看看 SsoSecurityConfigurer 類。
3.4 UserController
創(chuàng)建 UserController 類,,提供獲取當(dāng)前用戶的 /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)的啟動(dòng)類。代碼如下:
@SpringBootApplication
public class ResourceServerApplication {
public static void main(String[] args) {
SpringApplication.run(ResourceServerApplication.class, args);
}
}
3.6 簡(jiǎn)單測(cè)試(第一彈)
執(zhí)行 ResourceServerApplication 啟動(dòng) XXX 系統(tǒng),。下面,,我們來(lái)演示下 SSO 單點(diǎn)登錄的過(guò)程。
① 使用瀏覽器,,訪問(wèn) XXX 系統(tǒng)的 http://127.0.0.1:9090/user/info 地址,。因?yàn)闀何吹卿洠员恢囟ㄏ虻?strong>統(tǒng)一登錄系統(tǒng)的 http://127.0.0.1:8080/oauth/authorize 授權(quán)地址,。
又因?yàn)樵?strong>統(tǒng)一登錄系統(tǒng)暫未登錄,,所以被重定向到統(tǒng)一登錄系統(tǒng)的 http://127.0.0.1:8080/login 登錄地址。如下圖所示:
登錄界面② 輸入用戶的賬號(hào)密碼「yunai/1024」,,進(jìn)行統(tǒng)一登錄系統(tǒng)的登錄,。登錄完成后,進(jìn)入統(tǒng)一登錄系統(tǒng)的 http://127.0.0.1:8080/oauth/authorize 授權(quán)地址,。如下圖所示:
授權(quán)界面③ 點(diǎ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)碼后,,會(huì)自動(dòng)請(qǐng)求統(tǒng)一登錄系統(tǒng),通過(guò)授權(quán)碼獲取到訪問(wèn)令牌,。如此,,我們便完成了 XXX 系統(tǒng) 的登錄。
獲取授權(quán)碼完成后,,自動(dòng)跳轉(zhuǎn)到登錄前的 http://127.0.0.1:9090/user/info 地址,,打印出當(dāng)前登錄的用戶信息。如下圖所示:
用戶信息
如此,,我們從統(tǒng)一登錄系統(tǒng)也拿到了用戶信息,。下面,我們來(lái)進(jìn)一步將 Spring Security 的權(quán)限控制功能來(lái)演示下,。
3.7 SecurityConfig
創(chuàng)建 SecurityConfig 配置類,,添加 Spring Security 的功能。代碼如下:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true) // 開(kāi)啟對(duì) Spring Security 注解的方法,,進(jìn)行權(quán)限驗(yàn)證,。
@Order(101) // OAuth2SsoDefaultConfiguration 使用了 Order(100),所以這里設(shè)置為 Order(101),,防止相同順序?qū)е聢?bào)錯(cuò)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
}
在類上,,增加 @EnableGlobalMethodSecurity
注解,,開(kāi)啟對(duì) Spring Security 注解的方法,進(jìn)行權(quán)限驗(yàn)證,。
3.8 DemoController
創(chuàng)建 DemoController 類,,提供測(cè)試權(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 '用戶列表';
}
}
因?yàn)楫?dāng)前登錄的用戶只有 ROLE_USE 角色,,所以可以訪問(wèn) /demo/user-list
接口,,無(wú)法訪問(wèn) /demo/admin-list
接口。
3.9 簡(jiǎn)單測(cè)試(第二彈)
執(zhí)行 ResourceServerApplication 重啟 XXX 系統(tǒng),。下面,,我們來(lái)演示下 Spring Security 的權(quán)限控制功能。
① 使用瀏覽器,,訪問(wèn) http://127.0.0.1:9090/demo/user-list 地址,,成功。如下圖所示:
成功訪問(wèn)② 使用瀏覽器,,訪問(wèn) http://127.0.0.1:9090/demo/admin-list 地址,,失敗。如下圖所示:
失敗訪問(wèn)666. 彩蛋
至此,,我們成功使用 Spring Security OAuth 實(shí)現(xiàn)了一個(gè) SSO 單點(diǎn)登錄的示例,。下圖,是 SSO 的整體流程圖,,胖友可以繼續(xù)深入理解下:
SSO 流程圖后續(xù),,想要深入的胖友,可以看看 Spring Security OAuth 提供的如下兩個(gè)過(guò)濾器:
- OAuth2ClientContextFilter
- OAuth2ClientAuthenticationProcessingFilter