oauth2介紹 點擊進入 spring security oauth2 官方文檔
OAuth2 是一個開放標準,
它允許用戶讓第三方應用訪問該用戶在某一網站上存儲的私密資源(如頭像、照片、視頻等),
在這個過程中無須將用戶名和密碼提供給第三方應用,
實現這一功能是通過提供一個令牌(token),而不是用戶名和密碼來訪問他們存放在特定服務提供者的數據。
四種授權模式
- 授權碼模式(authorization code):正宗的OAuth2的授權模式,客戶端先將用戶導向認證服務器,登錄后獲取授權碼,然后進行授權,最后根據授權碼獲取訪問令牌;
- 簡化模式(implicit):和授權碼模式相比,取消了獲取授權碼的過程,直接獲取訪問令牌;
- 密碼模式(resource owner password credentials):客戶端直接向用戶獲取用戶名和密碼,之后向認證服務器獲取訪問令牌;
- 客戶端模式(client credentials):客戶端直接通過客戶端認證(比如client_id和client_secret)從認證服務器獲取訪問令牌。
這里我們用的是密碼模式
一、項目 - New - Module
二、選擇Maven - jdk- Next
三、修改Name為 oauth - 查看GroupId是否正確 - Finish
四、修改pom.xml文件
<?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>bi-cloud</artifactId>
<groupId>com.bi.cloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>oauth</artifactId>
<dependencies>
<!--集成公共模塊-->
<dependency>
<groupId>com.bi.cloud</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--nacos service discovery client依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--nacos config client 依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- Java Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--導入spring cloud oauth2依賴-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
</project>
五、java - New - Java Class 新增啟動類 com.bi.cloud.OauthApplication
package com.bi.cloud;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
@EntityScan("com.bi.cloud.pojo")
@MapperScan("com.bi.cloud.dao")
public class OauthApplication {
public static void main(String[] args) {
SpringApplication.run(OauthApplication.class, args);
}
}
六、在resources下新增bootstrap.yml 配置文件
bootstrap.yml 配置文件展示
spring:
profiles:
active: test
---
server:
port: 8002
spring:
profiles: test
application:
name: bi-cloud-oauth
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 #Nacos 鏈接地址
namespace: a60273f4-07fb-4568-82eb-d078a3b02107 #Nacos 命名空間ID
config:
server-addr: 127.0.0.1:8848 #Nacos 鏈接地址
namespace: a60273f4-07fb-4568-82eb-d078a3b02107 #Nacos 命名空間ID
group: DEFAULT_GROUP # 默認分組就是DEFAULT_GROUP,如果使用默認分組可以不配置
file-extension: yml #默認properties
---
server:
port: 8002
spring:
profiles: pre
application:
name: bi-cloud-oauth
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 #Nacos 鏈接地址
namespace: c60d2198-0b2f-46c1-82cb-4c2f20fb8123 #Nacos 命名空間ID
config:
server-addr: 127.0.0.1:8848 #Nacos 鏈接地址
namespace: c60d2198-0b2f-46c1-82cb-4c2f20fb8123 #Nacos 命名空間ID
group: DEFAULT_GROUP # 默認分組就是DEFAULT_GROUP,如果使用默認分組可以不配置
file-extension: yml #默認properties
---
server:
port: 8002
spring:
profiles: prd
application:
name: bi-cloud-oauth
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 #Nacos 鏈接地址
namespace: 0be74aa4-00e5-4c48-ae8c-34965c327212 #Nacos 命名空間ID
config:
server-addr: 127.0.0.1:8848 #Nacos 鏈接地址
namespace: 0be74aa4-00e5-4c48-ae8c-34965c327212 #Nacos 命名空間ID
group: DEFAULT_GROUP # 默認分組就是DEFAULT_GROUP,如果使用默認分組可以不配置
file-extension: yml #默認properties
七、Nacos配置(下圖為test環境 配置展示,pre、prd配置方式一致,唯一要注意的是每個環境的命名后綴都是不同的)
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.*.***:3306/****?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
username: *****
password: admin
druid:
initialSize: 10
minIdle: 10
maxActive: 30
maxWait: 50000
redis:
database:
host: 192.168.*.***
port: 6379
timeout: 5000
mybatis:
mapper-locations: classpath:mapper/*.xml
八、用 Redis 的方式來實現 token 的存儲
分別添加 RedisTokenStoreConfig.class 、OAuthConfig.class 、WebSecurityConfig.class
package com.bi.cloud.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.builders.JdbcClientDetailsServiceBuilder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import javax.sql.DataSource;
@Configuration
@EnableAuthorizationServer
public class OAuthConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
public PasswordEncoder passwordEncoder;
@Autowired
public UserDetailsService kiteUserDetailsService;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private TokenStore redisTokenStore;
@Autowired
private DataSource dataSource;
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
/**
* redis token 方式
*/
endpoints.authenticationManager(authenticationManager)
.userDetailsService(kiteUserDetailsService)
.tokenStore(redisTokenStore);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
JdbcClientDetailsServiceBuilder jcsb = clients.jdbc(dataSource);
jcsb.passwordEncoder(passwordEncoder);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.allowFormAuthenticationForClients();
security.checkTokenAccess("isAuthenticated()");
security.tokenKeyAccess("isAuthenticated()");
}
}
package com.bi.cloud.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
@Configuration
public class RedisTokenStoreConfig {
@Autowired
private RedisConnectionFactory redisConnectionFactory;
@Bean
public TokenStore redisTokenStore (){
return new RedisTokenStore(redisConnectionFactory);
}
}
package com.bi.cloud.config;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
/**
* 允許匿名訪問所有接口 主要是 oauth 接口
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/**").permitAll();
}
}
九、添加AuthUserService.class 讀取數據庫用戶信息
//oauth_client表
create table oauth_client_details (
client_id VARCHAR(256) PRIMARY KEY,
resource_ids VARCHAR(256),
client_secret VARCHAR(256),
scope VARCHAR(256),
authorized_grant_types VARCHAR(256),
web_server_redirect_uri VARCHAR(256),
authorities VARCHAR(256),
access_token_validity INTEGER,
refresh_token_validity INTEGER,
additional_information VARCHAR(4096),
autoapprove VARCHAR(256)
);
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
('user-client', '$2a$10$o2l5kA7z.Caekp72h5kU7uqdTDrlamLq.57M1F6ulJln9tRtOJufq', 'all',
'authorization_code,refresh_token,password', null, null, 3600, 36000, null, true);
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
('order-client', '$2a$10$GoIOhjqFKVyrabUNcie8d.ADX.qZSxpYbO6YK4L2gsNzlCIxEUDlW', 'all',
'authorization_code,refresh_token,password', null, null, 3600, 36000, null, true);
//-------------------------------------------------------------------------------------------------------
//用戶表
CREATE TABLE `bi_user` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
INSERT INTO `bi_user`(`id`, `username`, `password`) VALUES (1, 'admin', '123456');//正常數據庫密碼加密,這里只為演示
package com.bi.cloud.service;
import com.bi.cloud.dao.UserDao;
import com.bi.cloud.pojo.Users;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
@Slf4j
@Component
public class AuthUserService implements UserDetailsService {
@Autowired
private UserDao userDao;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
log.info("username:" + username);
// 查詢數據庫操作
Users users = userDao.getUsers(username);
if (StringUtils.isBlank(users.getPassword())) {
throw new UsernameNotFoundException("the user is not found");
}
String password = passwordEncoder.encode(users.getPassword());
return new User(username, password, new ArrayList<>());
}
}
十、SpringCloud Gateway jar包 和 oauth2 包有沖突 所以我們將gateway只作為網關,新增子模塊api 用于調用 engine 子模塊
gateway內容遷移至api
bootstrap.yml配置
spring:
profiles:
active: test
---
server:
port: 8008
spring:
profiles: test
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
namespace: a60273f4-07fb-4568-82eb-d078a3b02107
config:
server-addr: 127.0.0.1:8848
namespace: a60273f4-07fb-4568-82eb-d078a3b02107
group: DEFAULT_GROUP # 默認分組就是DEFAULT_GROUP,如果使用默認分組可以不配置
file-extension: yml #默認properties
gateway:
# 路由數組[路由 就是指定當請求滿足什么條件的時候轉到哪個微服務]
routes:
- id: bi-cloud-oauth # 當前路由的標識, 要求唯一
uri: lb://bi-cloud-oauth # lb指的是從 nacos 中按照名稱獲取微服務,并遵循負載均衡策略
predicates: # 斷言(就是路由轉發要滿足的條件)
- Path=/oauth/** # 當請求路徑滿足Path指定的規則時,才進行路由轉發
# 我們?定義的路由 ID,保持唯?
- id: bi-cloud-api
# ?標服務地址(部署多實例)
uri: lb://bi-cloud-api
# gateway?關從服務注冊中?獲取實例信息然后負載后路由
# 斷?:路由條件,Predicate 接受?個輸?參數,返回?個布爾值結果。該接?包含多種默認?法來將 Predicate 組合成其他復雜的邏輯(?如:與,或,?)。
predicates:
- Path=/bi-gateway/api/**
filters: # 過濾器,請求在傳遞過程中可以通過過濾器對其進行一定的修改
- StripPrefix=1 # 轉發之前去掉1層路徑
application:
name: bi-cloud-gateway
---
server:
port: 8008
spring:
profiles: pre
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
namespace: c60d2198-0b2f-46c1-82cb-4c2f20fb8123
config:
server-addr: 127.0.0.1:8848
namespace: c60d2198-0b2f-46c1-82cb-4c2f20fb8123
group: DEFAULT_GROUP # 默認分組就是DEFAULT_GROUP,如果使用默認分組可以不配置
file-extension: yml #默認properties
sentinel:
transport:
dashboard: 127.0.0.1:8080 #配置Sentinel dashboard地址
port: 8719 #這個端口配置會在應用對應的機器上啟動一個Http Server,該Server會與 Sentinel 控制臺做交互
datasource:
flow:
nacos:
server-addr: 127.0.0.1:8848 #nacos的訪問地址,,根據上面準備工作中啟動的實例配置
dataId: cloud-sentinel-flow-service #nacos中存儲規則的dataId
groupId: DEFAULT_GROUP #nacos中存儲規則的groupId
namespace: a60273f4-07fb-4568-82eb-d078a3b02107 #Nacos 命名空間的ID
data-type: json #配置文件類型
rule-type: flow #類型來自RuleType類 - 流控規則
degrade:
nacos:
server-addr: 127.0.0.1:8848 #nacos的訪問地址,,根據上面準備工作中啟動的實例配置
dataId: cloud-sentinel-degrade-service #nacos中存儲規則的dataId
groupId: DEFAULT_GROUP #nacos中存儲規則的groupId
namespace: a60273f4-07fb-4568-82eb-d078a3b02107 #Nacos 命名空間的ID
data-type: json #配置文件類型
rule-type: degrade #類型來自RuleType類 - 熔斷規則
gateway:
# 路由數組[路由 就是指定當請求滿足什么條件的時候轉到哪個微服務]
routes:
- id: bi-cloud-oauth # 當前路由的標識, 要求唯一
uri: lb://bi-cloud-oauth # lb指的是從 nacos 中按照名稱獲取微服務,并遵循負載均衡策略
predicates: # 斷言(就是路由轉發要滿足的條件)
- Path=/oauth/** # 當請求路徑滿足Path指定的規則時,才進行路由轉發
# 我們?定義的路由 ID,保持唯?
- id: bi-cloud-api
# ?標服務地址(部署多實例)
uri: lb://bi-cloud-api
# gateway?關從服務注冊中?獲取實例信息然后負載后路由
# 斷?:路由條件,Predicate 接受?個輸?參數,返回?個布爾值結果。該接?包含多種默認?法來將 Predicate 組合成其他復雜的邏輯(?如:與,或,?)。
predicates:
- Path=/bi-gateway/api/**
filters: # 過濾器,請求在傳遞過程中可以通過過濾器對其進行一定的修改
- StripPrefix=1 # 轉發之前去掉1層路徑
application:
name: bi-cloud-gateway
---
server:
port: 8008
spring:
profiles: prd
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
namespace: 0be74aa4-00e5-4c48-ae8c-34965c327212
config:
server-addr: 127.0.0.1:8848
namespace: 0be74aa4-00e5-4c48-ae8c-34965c327212
group: DEFAULT_GROUP # 默認分組就是DEFAULT_GROUP,如果使用默認分組可以不配置
file-extension: yml #默認properties
sentinel:
transport:
dashboard: 127.0.0.1:8080 #配置Sentinel dashboard地址
port: 8719 #這個端口配置會在應用對應的機器上啟動一個Http Server,該Server會與 Sentinel 控制臺做交互
datasource:
flow:
nacos:
server-addr: 127.0.0.1:8848 #nacos的訪問地址,,根據上面準備工作中啟動的實例配置
dataId: cloud-sentinel-flow-service #nacos中存儲規則的dataId
groupId: DEFAULT_GROUP #nacos中存儲規則的groupId
namespace: a60273f4-07fb-4568-82eb-d078a3b02107 #Nacos 命名空間的ID
data-type: json #配置文件類型
rule-type: flow #類型來自RuleType類 - 流控規則
degrade:
nacos:
server-addr: 127.0.0.1:8848 #nacos的訪問地址,,根據上面準備工作中啟動的實例配置
dataId: cloud-sentinel-degrade-service #nacos中存儲規則的dataId
groupId: DEFAULT_GROUP #nacos中存儲規則的groupId
namespace: a60273f4-07fb-4568-82eb-d078a3b02107 #Nacos 命名空間的ID
data-type: json #配置文件類型
rule-type: degrade #類型來自RuleType類 - 熔斷規則
gateway:
# 路由數組[路由 就是指定當請求滿足什么條件的時候轉到哪個微服務]
routes:
- id: bi-cloud-oauth # 當前路由的標識, 要求唯一
uri: lb://bi-cloud-oauth # lb指的是從 nacos 中按照名稱獲取微服務,并遵循負載均衡策略
predicates: # 斷言(就是路由轉發要滿足的條件)
- Path=/oauth/** # 當請求路徑滿足Path指定的規則時,才進行路由轉發
# 我們?定義的路由 ID,保持唯?
- id: bi-cloud-api
# ?標服務地址(部署多實例)
uri: lb://bi-cloud-api
# gateway?關從服務注冊中?獲取實例信息然后負載后路由
# 斷?:路由條件,Predicate 接受?個輸?參數,返回?個布爾值結果。該接?包含多種默認?法來將 Predicate 組合成其他復雜的邏輯(?如:與,或,?)。
predicates:
- Path=/bi-gateway/api/**
filters: # 過濾器,請求在傳遞過程中可以通過過濾器對其進行一定的修改
- StripPrefix=1 # 轉發之前去掉1層路徑
application:
name: bi-cloud-gateway
pom.xml修改
<?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>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>gateway</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
</dependency>
<!--GateWay 網關-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--引入webflux-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!--日志依賴-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<!--測試依賴-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--lombok工具-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</dependency>
<!-- Actuator可以幫助你監控和管理Spring Boot應?-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--熱部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--nacos config client 依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--鏈路追蹤-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<!--spring cloud依賴版本管理-->
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--SCA -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--SCA -->
</dependencies>
</dependencyManagement>
<build>
<plugins>
<!--編譯插件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
<encoding>utf-8</encoding>
</configuration>
</plugin>
<!--打包插件-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Nacos配置修改刪除即可
GatewayApplication.class 啟動類
package com.bi.cloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
十一、common增加dao、mapper、mapper.xml文件用于數據庫操作
pom.xml 展示
<?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>bi-cloud</artifactId>
<groupId>com.bi.cloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>common</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- StringUtils -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.11</version>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<!-- 數據庫連接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.22</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
新增或修改 UserDao、Users、UserService、UserMapper.xml 文件
package com.bi.cloud.dao;
import com.bi.cloud.pojo.Users;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserDao {
Users getUsers(String username);
}
package com.bi.cloud.pojo;
import lombok.Data;
import java.io.Serializable;
@Data
public class Users implements Serializable {
private long id;
private String username;
private String password;
}
package com.bi.cloud.service;
import com.bi.cloud.pojo.Users;
public interface UserService {
Users userInfo(String username);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bi.cloud.dao.UserDao">
<resultMap id="BaseResultMap" type="com.bi.cloud.pojo.Users">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="password" property="password"/>
</resultMap>
<sql id="Base_Column_List">
id, username, password
</sql>
<select id="getUsers" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from bi_user where username = #{username}
</select>
</mapper>
十二、engine 子模塊修改 UserServiceImpl.class 文件 (TestConsumerListener 為RocketMQ消息監聽,我們現在用不到,所以在這里把項目中的RocketMQ Jar包、方法都已經注視掉了)
pom.xml修改
<?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>bi-cloud</artifactId>
<groupId>com.bi.cloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>engine</artifactId>
<dependencies>
<!--集成公共模塊-->
<dependency>
<groupId>com.bi.cloud</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--nacos service discovery client依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--nacos config client 依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--spring cloud+dubbo 依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-apache-dubbo-adapter</artifactId>
</dependency>
<!--rocketmq-->
<!--<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>-->
</dependencies>
</project>
UserServiceImpl.class 修改
package com.bi.cloud.service.Impl;
import com.bi.cloud.dao.UserDao;
import com.bi.cloud.pojo.Users;
import com.bi.cloud.service.UserService;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Service
@Component
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
public Users userInfo(String username) {
return userDao.getUsers(username);
}
}
bootstrap.yml 配置文件
spring:
profiles:
active: test #默認運行環境
---
server:
port: 8001
spring:
profiles: test #運行環境 + 命名空間名稱
application:
name: bi-cloud-engine #唯一名稱
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 #Nacos 鏈接地址
namespace: a60273f4-07fb-4568-82eb-d078a3b02107 #Nacos 命名空間ID
config:
server-addr: 127.0.0.1:8848 #Nacos 鏈接地址
namespace: a60273f4-07fb-4568-82eb-d078a3b02107 #Nacos 命名空間ID
group: DEFAULT_GROUP # 默認分組就是DEFAULT_GROUP,如果使用默認分組可以不配置
file-extension: yml #默認properties
mybatis:
mapper-locations: classpath:mapper/*.xml
---
server:
port: 8001
spring:
profiles: pre #運行環境 + 命名空間名稱
application:
name: bi-cloud-engine #唯一名稱
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 #Nacos 鏈接地址
namespace: c60d2198-0b2f-46c1-82cb-4c2f20fb8123 #Nacos 命名空間ID
config:
server-addr: 127.0.0.1:8848 #Nacos 鏈接地址
namespace: c60d2198-0b2f-46c1-82cb-4c2f20fb8123 #Nacos 命名空間ID
group: DEFAULT_GROUP # 默認分組就是DEFAULT_GROUP,如果使用默認分組可以不配置
file-extension: yml #默認properties
mybatis:
mapper-locations: classpath:mapper/*.xml
---
server:
port: 8001
spring:
profiles: prd #運行環境 + 命名空間名稱
application:
name: bi-cloud-engine #唯一名稱
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 #Nacos 鏈接地址
namespace: 0be74aa4-00e5-4c48-ae8c-34965c327212 #Nacos 命名空間ID
config:
server-addr: 127.0.0.1:8848 #Nacos 鏈接地址
namespace: 0be74aa4-00e5-4c48-ae8c-34965c327212 #Nacos 命名空間ID
group: DEFAULT_GROUP # 默認分組就是DEFAULT_GROUP,如果使用默認分組可以不配置
file-extension: yml #默認properties
mybatis:
mapper-locations: classpath:mapper/*.xml
Nacos配置
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.*.***:3306/*****?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
username: ****
password: ****
druid:
initialSize: 10
minIdle: 10
maxActive: 30
maxWait: 50000
dubbo:
scan:
# dubbo 服務掃描基準包
base-packages: com.bi.cloud.service
protocol:
# dubbo 協議
name: dubbo
# dubbo 協議端口( -1 表示自增端口,從 20880 開始)
port: -1
host: 127.0.0.1
registry:
# 掛載到 Spring Cloud 的注冊中心
address: spring-cloud://localhost
rocketmq:
name-server: 192.168.1.***:9876
producer:
# 小坑:必須指定group
group: test-group
EngineApplication.class 啟動類
package com.bi.cloud;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
@EntityScan("com.bi.cloud.pojo")
@MapperScan("com.bi.cloud.dao")
public class EngineApplication {
public static void main(String[] args) {
SpringApplication.run(EngineApplication.class, args);
}
}
十三、新增 api 子模塊(TestProducerController 與 TestDemoController 為 RocketMQ,這里已經注釋掉,不需要)
ResourceServerConfig.class
package com.bi.cloud.config;
import com.bi.cloud.handler.AuthExceptionEntryPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.RemoteTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Value("${security.oauth2.client.client-id}")
private String clientId;
@Value("${security.oauth2.client.client-secret}")
private String secret;
@Value("${security.oauth2.authorization.check-token-access}")
private String checkTokenEndpointUrl;
@Autowired
private RedisConnectionFactory redisConnectionFactory;
@Autowired
private AuthExceptionEntryPoint authExceptionEntryPoint;
@Bean
public TokenStore redisTokenStore() {
return new RedisTokenStore(redisConnectionFactory);
}
@Bean
public RemoteTokenServices tokenService() {
RemoteTokenServices tokenService = new RemoteTokenServices();
tokenService.setClientId(clientId);
tokenService.setClientSecret(secret);
tokenService.setCheckTokenEndpointUrl(checkTokenEndpointUrl);
return tokenService;
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.authenticationEntryPoint(authExceptionEntryPoint);
}
}
UserBlockHandler.class
package com.bi.cloud.config;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import com.alibaba.fastjson.JSON;
import java.util.HashMap;
public class UserBlockHandler {
public static String handleException(BlockException ex) {
HashMap<String, Object> map = new HashMap<>();
if (ex instanceof FlowException) {
map.put("code", -1);
map.put("msg", "系統限流,請稍等");
} else if (ex instanceof DegradeException) {
map.put("code", -2);
map.put("msg", "降級了");
} else if (ex instanceof ParamFlowException) {
map.put("code", -3);
map.put("msg", "熱點參數限流");
} else if (ex instanceof SystemBlockException) {
map.put("code", -4);
map.put("msg", "系統規則(負載/...不滿足要求)");
} else if (ex instanceof AuthorityException) {
map.put("code", -5);
map.put("msg", "授權規則不通過");
}
return JSON.toJSONString(map);
}
public static String handleError() {
HashMap<String, Object> map = new HashMap<>();
map.put("code", 500);
map.put("msg", "系統異常");
return JSON.toJSONString(map);
}
}
UserController.class
package com.bi.cloud.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.fastjson.JSON;
import com.bi.cloud.config.UserBlockHandler;
import com.bi.cloud.pojo.Users;
import com.bi.cloud.service.UserService;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/user")
public class UserController {
@Reference
private UserService userService;
/**
* 獲取用戶信息
*/
@PostMapping("/userInfo")
public String userInfo() {
String userName = SecurityContextHolder.getContext().getAuthentication().getName();
return JSON.toJSONString(userService.userInfo(userName));
}
/**
* 測試流控規則
*/
@PostMapping("/testFlow")
@SentinelResource(value = "user-testFlow",
blockHandlerClass = UserBlockHandler.class, //對應異常類
blockHandler = "handleException", //只負責sentinel控制臺配置違規
fallback = "handleError", //只負責業務異常
fallbackClass = UserBlockHandler.class)
public String testFlow() {
Users user = userService.userInfo("admin");
return JSON.toJSONString(user);
}
/**
* 測試降級規則
*/
@PostMapping("/testDegrade")
@SentinelResource(value = "user-testDegrade",
blockHandlerClass = UserBlockHandler.class, //對應異常類
blockHandler = "handleException", //只負責sentinel控制臺配置違規
fallback = "handleError", //只負責業務異常
fallbackClass = UserBlockHandler.class)
public String testDegrade() {
Users user = userService.userInfo("admin");
return JSON.toJSONString(user);
}
}
AuthExceptionEntryPoint.class (oauth登錄異常處理)
package com.bi.cloud.handler;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
@Slf4j
public class AuthExceptionEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) {
Throwable cause = authException.getCause();
response.setHeader("Content-Type", "application/json;charset=UTF-8");
try {
JSONObject body = new JSONObject();
body.put("code", 1001);
body.put("msg", "token無效");
if (!(cause instanceof InvalidTokenException)) {
body.put("code", 1002);
body.put("msg", "token丟失");
}
response.getWriter().write(body.toJSONString());
} catch (IOException e) {
log.error("token認證失敗", e);
}
}
}
ApiApplication.class 啟動類
package com.bi.cloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@EnableDiscoveryClient
public class ApiApplication {
public static void main(String[] args) {
SpringApplication.run(ApiApplication.class, args);
}
}
bootstrap.yml 配置
spring:
profiles:
active: test
---
server:
port: 8003
spring:
profiles: test
application:
name: bi-cloud-api
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 #Nacos 鏈接地址
namespace: a60273f4-07fb-4568-82eb-d078a3b02107 #Nacos 命名空間ID
config:
server-addr: 127.0.0.1:8848 #Nacos 鏈接地址
namespace: a60273f4-07fb-4568-82eb-d078a3b02107 #Nacos 命名空間ID
group: DEFAULT_GROUP # 默認分組就是DEFAULT_GROUP,如果使用默認分組可以不配置
file-extension: yml #默認properties
sentinel:
transport:
dashboard: 127.0.0.1:8080 #配置Sentinel dashboard地址
port: 8719 #這個端口配置會在應用對應的機器上啟動一個Http Server,該Server會與 Sentinel 控制臺做交互
datasource:
flow:
nacos:
server-addr: 127.0.0.1:8848 #nacos的訪問地址,,根據上面準備工作中啟動的實例配置
dataId: cloud-sentinel-flow-service #nacos中存儲規則的dataId
groupId: DEFAULT_GROUP #nacos中存儲規則的groupId
namespace: a60273f4-07fb-4568-82eb-d078a3b02107 #Nacos 命名空間的ID
data-type: json #配置文件類型
rule-type: flow #類型來自RuleType類 - 流控規則
degrade:
nacos:
server-addr: 127.0.0.1:8848 #nacos的訪問地址,,根據上面準備工作中啟動的實例配置
dataId: cloud-sentinel-degrade-service #nacos中存儲規則的dataId
groupId: DEFAULT_GROUP #nacos中存儲規則的groupId
namespace: a60273f4-07fb-4568-82eb-d078a3b02107 #Nacos 命名空間的ID
data-type: json #配置文件類型
rule-type: degrade #類型來自RuleType類 - 熔斷規則
---
server:
port: 8003
spring:
profiles: pre
application:
name: bi-cloud-api
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 #Nacos 鏈接地址
namespace: c60d2198-0b2f-46c1-82cb-4c2f20fb8123 #Nacos 命名空間ID
config:
server-addr: 127.0.0.1:8848 #Nacos 鏈接地址
namespace: c60d2198-0b2f-46c1-82cb-4c2f20fb8123 #Nacos 命名空間ID
group: DEFAULT_GROUP # 默認分組就是DEFAULT_GROUP,如果使用默認分組可以不配置
file-extension: yml #默認properties
sentinel:
transport:
dashboard: 127.0.0.1:8080 #配置Sentinel dashboard地址
port: 8719 #這個端口配置會在應用對應的機器上啟動一個Http Server,該Server會與 Sentinel 控制臺做交互
datasource:
flow:
nacos:
server-addr: 127.0.0.1:8848 #nacos的訪問地址,,根據上面準備工作中啟動的實例配置
dataId: cloud-sentinel-flow-service #nacos中存儲規則的dataId
groupId: DEFAULT_GROUP #nacos中存儲規則的groupId
namespace: a60273f4-07fb-4568-82eb-d078a3b02107 #Nacos 命名空間的ID
data-type: json #配置文件類型
rule-type: flow #類型來自RuleType類 - 流控規則
degrade:
nacos:
server-addr: 127.0.0.1:8848 #nacos的訪問地址,,根據上面準備工作中啟動的實例配置
dataId: cloud-sentinel-degrade-service #nacos中存儲規則的dataId
groupId: DEFAULT_GROUP #nacos中存儲規則的groupId
namespace: a60273f4-07fb-4568-82eb-d078a3b02107 #Nacos 命名空間的ID
data-type: json #配置文件類型
rule-type: degrade #類型來自RuleType類 - 熔斷規則
---
server:
port: 8003
spring:
profiles: prd
application:
name: bi-cloud-api
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 #Nacos 鏈接地址
namespace: 0be74aa4-00e5-4c48-ae8c-34965c327212 #Nacos 命名空間ID
config:
server-addr: 127.0.0.1:8848 #Nacos 鏈接地址
namespace: 0be74aa4-00e5-4c48-ae8c-34965c327212 #Nacos 命名空間ID
group: DEFAULT_GROUP # 默認分組就是DEFAULT_GROUP,如果使用默認分組可以不配置
file-extension: yml #默認properties
sentinel:
transport:
dashboard: 127.0.0.1:8080 #配置Sentinel dashboard地址
port: 8719 #這個端口配置會在應用對應的機器上啟動一個Http Server,該Server會與 Sentinel 控制臺做交互
datasource:
flow:
nacos:
server-addr: 127.0.0.1:8848 #nacos的訪問地址,,根據上面準備工作中啟動的實例配置
dataId: cloud-sentinel-flow-service #nacos中存儲規則的dataId
groupId: DEFAULT_GROUP #nacos中存儲規則的groupId
namespace: a60273f4-07fb-4568-82eb-d078a3b02107 #Nacos 命名空間的ID
data-type: json #配置文件類型
rule-type: flow #類型來自RuleType類 - 流控規則
degrade:
nacos:
server-addr: 127.0.0.1:8848 #nacos的訪問地址,,根據上面準備工作中啟動的實例配置
dataId: cloud-sentinel-degrade-service #nacos中存儲規則的dataId
groupId: DEFAULT_GROUP #nacos中存儲規則的groupId
namespace: a60273f4-07fb-4568-82eb-d078a3b02107 #Nacos 命名空間的ID
data-type: json #配置文件類型
rule-type: degrade #類型來自RuleType類 - 熔斷規則
Nacos 配置
dubbo:
registry:
# 掛載到 Spring Cloud 注冊中心
address: spring-cloud://localhost
cloud:
# 訂閱服務提供方的應用列表,訂閱多個服務提供者使用 "," 連接
subscribed-services: bi-cloud-engine
rocketmq:
name-server: 192.168.1.117:9876
producer:
# 小坑:必須指定group
group: test-group
spring:
redis:
database:
host: 192.168.1.206
port: 6379
timeout: 5000
security:
oauth2:
client:
client-id: user-client
client-secret: user-secret-8888
user-authorization-uri: http://localhost:8002/oauth/authorize
access-token-uri: http://localhost:8002/oauth/token
resource:
id: user-client
user-info-uri: user-info
authorization:
check-token-access: http://localhost:8002/oauth/check_token
pom.xml 配置
<?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>bi-cloud</artifactId>
<groupId>com.bi.cloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>api</artifactId>
<dependencies>
<!--集成公共模塊-->
<dependency>
<groupId>com.bi.cloud</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</exclusion>
<exclusion>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</exclusion>
<exclusion>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--nacos service discovery client依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--nacos config client 依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--sentinel 核心環境 依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- Sentinel支持采用 Nacos 作為規則配置數據源,引入該適配依賴 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
</dependency>
<!--spring cloud+dubbo 依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-apache-dubbo-adapter</artifactId>
</dependency>
<!-- Java Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<!--JSON 序列化依賴 和 模板引擎-->
<!-- <dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- rocketmq -->
<!--<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>-->
<!--導入spring cloud oauth2依賴-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
</project>
完整Naocs 列表展示
這里項目已經集成完畢
1. 啟動項目
獲取token
- 假設咱們在一個 web 端使用,grant_type 是 password,表明這是使用 OAuth2 的密碼模式。
- username=admin 和 password=123456 就相當于在 web 端登錄界面輸入的用戶名和密碼,我們在認證服務端配置中固定了用戶名是 admin 、密碼是 123456,而線上環境中則應該通過查詢數據庫獲取。
- scope=all 是權限有關的,在認證服務的 OAuthConfig 中指定了 scope 為 all 。
- Authorization 要加在請求頭中,格式為 Basic 空格 base64(clientId:clientSecret),這個微服務客戶端的 client-id 是 user-client,client-secret 是 user-secret-8888,將這兩個值通過冒號連接,并使用 base64 編碼(user-client:user-secret-8888)之后的值為 dXNlci1jbGllbnQ6dXNlci1zZWNyZXQtODg4OA==,可以通過 https://www.sojson.com/base64.html 在線編碼獲取。
POST http://localhost:8002/oauth/token?grant_type=password&username=admin&password=123456&scope=all
Accept: /
Cache-Control: no-cache
Authorization: Basic dXNlci1jbGllbnQ6dXNlci1zZWNyZXQtODg4OA==
運行請求后,如果參數都正確的話,獲取到的返回內容如下,是一段 json 格式
{
"access_token": "34f979d2-525f-4138-830d-dcbd7a2a5d02",
"token_type": "bearer",
"refresh_token": "98a9153b-6a98-4182-9af3-0a1321da7c0d",
"expires_in": 3599,
"scope": "all"
}
- access_token : 就是之后請求需要帶上的 token,也是本次請求的主要目的
- token_type:為 bearer,這是 access token 最常用的一種形式
- refresh_token:之后可以用這個值來換取新的 token,而不用輸入賬號密碼
- expires_in:token 的過期時間(秒)
換取 access_token
token 過期后,用 refresh_token 換取 access_token
一般都會設置 access_token 的過期時間小于 refresh_token 的過期時間,以便在 access_token 過期后,不用用戶再次登錄的情況下,獲取新的 access_token。
POST http://localhost:8002/oauth/token?grant_type=refresh_token&refresh_token=706dac10-d48e-4795-8379-efe8307a2282
Accept: /
Cache-Control: no-cache
Authorization: Basic dXNlci1jbGllbnQ6dXNlci1zZWNyZXQtODg4OA==
- grant_type 設置為 refresh_token。
- refresh_token 設置為請求 token 時返回的 refresh_token 的值。
- 請求頭加入 Authorization,格式依然是 Basic + 空格 + base64(client-id:client-secret)
- 請求成功后會返回和請求 token 同樣的數據格式。
請求獲取當前登錄用戶信息接口
POST http://localhost:8008/bi-gateway/api/user/userInfo
Authorization: bearer 88d08a76-f4bf-4821-93ab-10eca7bdddb6
可以看到,如果不填寫 token 或錯誤 token 會返回對應錯誤信息
微服務 Spring Cloud Alibaba 項目搭建到這里已經全部完成
gitee 地址 https://gitee.com/mybride/bi_cloud
參考文獻:https://github.com/xkcoding/spring-boot-demo/tree/master/demo-oauth
https://www.cnblogs.com/fengzheng/p/11724625.html