ApiBoot是一款基于SpringBoot1.x,2.x的接口服務內建基礎架構, 内部提供了架構的封裝內建、使用擴充、自動化完成配置,讓接口開發者可以選着性完成開箱即用, 不再為搭建接口架構而犯愁,進而極大的提高開發效率。
引入 ApiBoot Security Oauth
在
pom.xml
配置檔案内添加如下:
<!--ApiBoot Security Oauth-->
<dependency>
<groupId>org.minbox.framework</groupId>
<artifactId>api-boot-starter-security-oauth-jwt</artifactId>
</dependency>
ApiBoot
所提供的依賴都不需要添加版本号,但是需要添加版本依賴,具體檢視 ApiBoot版本依賴
配置參數清單
ApiBoot
在整合
SpringSecurity
、
Oauth2
時把配置參數進行了分離,配置清單如下所示:
整合SpringSecurity配置清單
配置名稱 | 介紹 | 預設值 | 生效方式 |
---|---|---|---|
| SpringSecurity讀取使用者的方式,預設為記憶體方式 | memory | all |
| 攔截的接口路徑字首,如:/api/users就會被預設攔截 | /api/** | memory/jdbc |
| 配置使用者清單,具體使用檢視 記憶體方式介紹 | 無 | |
| 所排除的路徑,預設排除Swagger、Actuator相關路徑字首 | /v2/api-docs /swagger-ui.html /swagger-resources/configuration/security /META-INF/resources/webjars/ /swagger-resources /swagger-resources/configuration/ui /actuator/ | |
| 僅在Jdbc方式生效 | true | jdbc |
整合Oauth2配置清單
綁定away | |||
---|---|---|---|
| Oauth存儲Token、讀取Client資訊方式 | ||
| Oauth2 Client ID | ApiBoot | |
| Oauth2 Client Secret | ApiBootSecret | |
| 用戶端授權方式 | Srtring[]{"password"} | |
| 用戶端作用域 | String[]{"api"} | |
| 是否啟用JWT格式化AccessToken | false | |
| 使用JWT格式化AccessToken時的簽名 |
ApiBoot
SpringSecurity
Oauth2
時配置進行了分離,也就意味着我們可以讓
SpringSecurity
讀取記憶體使用者、
Oauth2
将生成的
AccessToken
存放到
資料庫
,當然反過來也是可以的,互相不影響!!!
記憶體方式(預設方式)
Spring Security
ApiBoot
Spring Security
的記憶體方式時,僅僅需要配置
api.boot.security.users
使用者清單參數即可,就是這麼的簡單,
配置使用者示例如下所示:
api:
boot:
security:
# Spring Security 記憶體方式使用者清單示例
users:
- username: hengboy
password: 123456
- username: apiboot
password: abc321
api.boot.security.users
是一個
List<SecurityUser>
類型的集合,是以這裡可以配置多個使用者。
Oauth2
如果全部使用預設值的情況話不需要做任何配置!!!
Jdbc方式
前提:項目需要添加資料源依賴。
預設使用者表
ApiBoot
Spring Security
的Jdbc方式時,在使用
ApiBoot
提供的預設結構使用者表時隻需要修改
api.boot.security.away: jdbc
即可,
ApiBoot
提供的使用者表結構如下所示:
CREATE TABLE `api_boot_user_info` (
`UI_ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '使用者編号,主鍵自增',
`UI_USER_NAME` varchar(30) DEFAULT NULL COMMENT '使用者名',
`UI_NICK_NAME` varchar(50) DEFAULT NULL COMMENT '使用者昵稱',
`UI_PASSWORD` varchar(255) DEFAULT NULL COMMENT '使用者密碼',
`UI_EMAIL` varchar(30) DEFAULT NULL COMMENT '使用者郵箱位址',
`UI_AGE` int(11) DEFAULT NULL COMMENT '使用者年齡',
`UI_ADDRESS` varchar(200) DEFAULT NULL COMMENT '使用者位址',
`UI_IS_LOCKED` char(1) DEFAULT 'N' COMMENT '是否鎖定',
`UI_IS_ENABLED` char(1) DEFAULT 'Y' COMMENT '是否啟用',
`UI_STATUS` char(1) DEFAULT 'O' COMMENT 'O:正常,D:已删除',
`UI_CREATE_TIME` timestamp NULL DEFAULT current_timestamp() COMMENT '使用者建立時間',
PRIMARY KEY (`UI_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='ApiBoot預設的使用者資訊表';
自定義使用者表
如果你的系統已經存在了自定義使用者表結構,
ApiBoot
是支援的,而且很簡單就可以完成整合,我們需要先修改
api.boot.security.enable-default-store-delegate
參數為
false
,如下所示:
api:
boot:
security:
# Spring Security jdbc方式使用者清單示例
enable-default-store-delegate: false
away: jdbc
添加
ApiBootStoreDelegate
接口實作類,如下所示:
@Component
public class DisableDefaultUserTableStoreDelegate implements ApiBootStoreDelegate {
@Autowired
private PasswordEncoder passwordEncoder;
/**
* 使用者清單示例
* 從該集合内讀取使用者資訊
* 可以使用集合内的使用者擷取access_token
*/
static List<String> users = new ArrayList() {
{
add("api-boot");
add("hengboy");
add("yuqiyu");
}
};
/**
* 根據使用者名查詢使用者資訊
*
* @param username 使用者名
* @return
* @throws UsernameNotFoundException
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (!users.contains(username)) {
throw new UsernameNotFoundException("使用者:" + username + "不存在");
}
return new DisableDefaultUserDetails(username);
}
@Data
@AllArgsConstructor
@NoArgsConstructor
class DisableDefaultUserDetails implements UserDetails {
private String username;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return new ArrayList() {
{
add((GrantedAuthority) () -> "ROLE_USER");
}
};
}
/**
* 示例密碼使用123456
*
* @return
*/
@Override
public String getPassword() {
return passwordEncoder.encode("123456");
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
}
根據上面代碼示例,我們可以通過
users
使用者清單進行通路擷取
access_token
。
建立Oauth所需表結構
Oauth2
如果使用
Jdbc
方式進行存儲
access_token
client_details
時,需要在資料庫内初始化
Oauth2
所需相關表結構,
oauth-mysql.sql添加用戶端資料
初始化
Oauth2
表結構後,需要向
oauth_client_details
表内添加一個用戶端資訊,下面是對應
ApiBoot Security Oauth
配置資訊的資料初始化,如下所示:
INSERT INTO `oauth_client_details` VALUES ('ApiBoot','api','$2a$10$M5t8t1fHatAj949RCHHB/.j1mrNAbxIz.mOYJQbMCcSPwnBMJLmMK','api','password',NULL,NULL,7200,7200,NULL,NULL);
加密方式統一使用
AppSecret
,資料初始化時需要注意。
BCryptPasswordEncoder
在上面
memory/jdbc
兩種方式已經配置完成,接下來我們就可以擷取
access_token
擷取AccessToken
通過CURL擷取
~ curl ApiBoot:ApiBootSecret@localhost:8080/oauth/token -d "grant_type=password&username=api-boot&password=123456"
{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NTMxMDk1MjMsInVzZXJfbmFtZSI6ImFwaS1ib290IiwiYXV0aG9yaXRpZXMiOlsiUk9MRV9VU0VSIl0sImp0aSI6IjBmZTUyY2RlLTBhZjctNDI1YS04Njc2LTFkYTUyZTA0YzUxYiIsImNsaWVudF9pZCI6IkFwaUJvb3QiLCJzY29wZSI6WyJhcGkiXX0.ImqGZssbDEOmpf2lQZjLQsch4ukE0C4SCYJsutfwfx0","token_type":"bearer","expires_in":42821,"scope":"api","jti":"0fe52cde-0af7-425a-8676-1da52e04c51b"}
啟用JWT
ApiBoot Security Oauth
在使用
JWT
格式化
access_token
時非常簡單的,配置如下所示:
api:
boot:
oauth:
jwt:
# 開啟Jwt轉換AccessToken
enable: true
# 轉換Jwt時所需加密key,預設為ApiBoot
sign-key: 恒宇少年 - 于起宇
預設不啟用
JWT
,
sign-key
簽名建議進行更換。
本章源碼位址:
https://github.com/hengboy/api-boot/tree/master/api-boot-samples/api-boot-sample-security-oauth-jwt