Springboot使用Security實(shí)現(xiàn)OAuth2授權(quán)驗(yàn)證完整過(guò)程
OAuth2獲取授權(quán)令牌(token)通常有四種方式:授權(quán)碼模式,簡(jiǎn)化模式,客戶端模式,和密碼模式。針對(duì)自己系統(tǒng)內(nèi)用戶的登錄,通常使用密碼模式進(jìn)行授權(quán)。
我們利用Spring Security OAuth2來(lái)制作一個(gè)授權(quán)服務(wù)器。
第一步-添加依賴
pom文件中添加如下依賴,引入oauth2相關(guān)框架
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>我還是用到了數(shù)據(jù)庫(kù)進(jìn)行存儲(chǔ),我用的jpa連接數(shù)據(jù)庫(kù),使用其他持久層框架(MyBatis)也可以。
引入數(shù)據(jù)庫(kù)依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--數(shù)據(jù)庫(kù)鏈接驅(qū)動(dòng)-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>第二步-添加代碼
1 實(shí)現(xiàn)UserDetailsService,獲取用戶
@Service
public class MyUserDetailsService implements UserDetailsService {
@Resource
private UserService userService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//根據(jù)用戶名獲取用戶,并驗(yàn)證用戶是否有效及權(quán)限
//從數(shù)據(jù)庫(kù)中獲取用戶
TUser user = userService.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("用戶不存在");
}
Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
boolean enabled = user.getStatus() == 1; // 可用性 :true:可用 false:不可用
boolean accountNonExpired = true; // 過(guò)期性 :true:沒(méi)過(guò)期 false:過(guò)期
boolean credentialsNonExpired = true; // 有效性 :true:憑證有效 false:憑證無(wú)效
boolean accountNonLocked = true; // 鎖定性 :true:未鎖定 false:已鎖定
//配置權(quán)限
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ADMIN");
grantedAuthorities.add(grantedAuthority);
//將用戶名和密碼及其他配置返還個(gè)spring security 進(jìn)行驗(yàn)證
return new User(username, user.getPassword(),
enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, grantedAuthorities);
}
}2 添加WebSecurityConfigurerAdapter
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}3 添加AuthorizationServerConfigurerAdapter
@Configuration
@EnableAuthorizationServer
public class Oauth2ServerConfig extends AuthorizationServerConfigurerAdapter {
//驗(yàn)證管理器
@Resource
private AuthenticationManager authenticationManager;
//獲取用戶,自己實(shí)現(xiàn)獲取用戶的相關(guān)功能
@Resource
private MyUserDetailsService userService;
//數(shù)據(jù)庫(kù)配置
@Resource
private DataSource dataSource;
/**
* 自定義授權(quán)服務(wù)配置
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints.authenticationManager(authenticationManager)
.userDetailsService(userService)
.tokenStore(new JdbcTokenStore(dataSource));
// 配置TokenServices參數(shù)
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setTokenStore(endpoints.getTokenStore());
tokenServices.setSupportRefreshToken(true);
tokenServices.setClientDetailsService(endpoints.getClientDetailsService());
tokenServices.setTokenEnhancer(endpoints.getTokenEnhancer());
tokenServices.setAccessTokenValiditySeconds((int) TimeUnit.HOURS.toSeconds(12)); // 12小時(shí)
tokenServices.setRefreshTokenValiditySeconds((int) TimeUnit.DAYS.toSeconds(30));// 30天
endpoints.tokenServices(tokenServices);
}
/**
* 配置認(rèn)證客戶端
* @param clients
* @throws Exception
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
//自定義客戶端配置
clients.withClientDetails(clientDetails());
}
//從數(shù)據(jù)庫(kù)中獲取客戶端的配置
public ClientDetailsService clientDetails() {
return new JdbcClientDetailsService(dataSource);
}
/**
* 自定義授權(quán)令牌端點(diǎn)的安全約束
* @param security
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer security) {
//自定義安全約束
security.allowFormAuthenticationForClients();
}
}第三步-初始化數(shù)據(jù)庫(kù)
在數(shù)據(jù)庫(kù)中創(chuàng)建三個(gè)表 oauth_access_token (存儲(chǔ)token),oauth_client_details(允許請(qǐng)求授權(quán)的客戶端),oauth_refresh_token(存儲(chǔ)refreshToken)
為了測(cè)試,我還建了一個(gè)t_user的用戶表,這個(gè)表可以不導(dǎo)入
CREATE TABLE `oauth_access_token` (
`token_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`token` blob NULL,
`authentication_id` varchar(250) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`user_name` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`client_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`authentication` blob NULL,
`refresh_token` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`authentication_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = DYNAMIC;
CREATE TABLE `oauth_client_details` (
`client_id` varchar(250) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`resource_ids` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`client_secret` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`scope` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`authorized_grant_types` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`web_server_redirect_uri` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`authorities` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`access_token_validity` int(11) NULL DEFAULT NULL,
`refresh_token_validity` int(11) NULL DEFAULT NULL,
`additional_information` varchar(4096) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`autoapprove` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`client_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = DYNAMIC;
-- 初始化了一個(gè)客戶端的數(shù)據(jù)
INSERT INTO `oauth_client_details` VALUES ('client', '', '$2a$10$My8G.sWJs/WQN8hdYS862.BsUuoL4p51xyfTIJu2NMMrIQ/JXRc2a', 'web', 'authorization_code,password,refresh_token,client_credentials', NULL, NULL, NULL, NULL, '{\"code\":\"test\"}', NULL);
DROP TABLE IF EXISTS `oauth_refresh_token`;
CREATE TABLE `oauth_refresh_token` (
`token_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`token` blob NULL,
`authentication` blob NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = DYNAMIC;
-- 我自己測(cè)試用的用戶表,這個(gè)可以不導(dǎo)入,使用自己系統(tǒng)的用戶表
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',
`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用戶名',
`nickname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '昵稱',
`password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '密碼',
`status` int(11) NULL DEFAULT NULL COMMENT '狀態(tài) 1正常 2停用',
`e_mail` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '電子郵箱',
`phone` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '手機(jī)號(hào)',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
INSERT INTO `t_user` VALUES (1, 'admin', '管理員', '$2a$10$gD1u5uXEmCFmlvg.hgN7P.zv.sbCOEmX1sFNRHEBRIx6Ad.qydceu', 1, 'admin@admin.com', '15812345678');在application中配置數(shù)據(jù)庫(kù)信息
spring:
application:
name: HelloSecurity
#數(shù)據(jù)庫(kù)配置連接
datasource:
url: jdbc:mysql://127.0.0.1:3306/hello_security?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: "123456"
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
show-sql: true
server:
port: 8080
完成以上步驟后,一個(gè)簡(jiǎn)單的OAuth2授權(quán)驗(yàn)證服務(wù)器就搭建完成了,我們啟動(dòng)項(xiàng)目,進(jìn)行測(cè)試。
獲取token的接口是http://127.0.0.1:8080/oauth/token

源碼地址:https://gitee.com/xiaobailovejiajia/hello-security
到此這篇關(guān)于Springboot使用Security實(shí)現(xiàn)OAuth2授權(quán)驗(yàn)證完整過(guò)程的文章就介紹到這了,更多相關(guān)Springboot Security內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Java的TCP/IP編程學(xué)習(xí)--基于定界符的成幀
這篇文章主要介紹了Java的TCP/IP編程學(xué)習(xí)--基于定界符的成幀,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
Java實(shí)現(xiàn)簡(jiǎn)單修改文件名的方法分析
這篇文章主要介紹了Java實(shí)現(xiàn)簡(jiǎn)單修改文件名的方法,結(jié)合具體實(shí)例分析了2種比較常用的java文件名修改方法,需要的朋友可以參考下2017-09-09
Java異常:java.net.UnknownHostException產(chǎn)生的原因和解決方案
這篇文章主要給大家介紹了關(guān)于Java異常:java.net.UnknownHostException產(chǎn)生的原因和解決方案,這個(gè)異常是java.net包中的一部分,具體說(shuō)它是類的一個(gè)實(shí)例,異常通常是由主機(jī)名無(wú)法解析為IP地址引起的,文中將解決的辦法介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01
Spring加載XSD文件發(fā)生錯(cuò)誤的解決方法
這篇文章主要介紹了Spring加載XSD文件發(fā)生錯(cuò)誤的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08
Collections工具類_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
Collections工具類提供了大量針對(duì)Collection/Map的操作。這篇文章主要介紹了Collections工具類_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理,需要的朋友可以參考下2017-04-04

