SpringBoot2 整合OAuth2元件,模擬第三方授權訪問
阿新 • • 發佈:2020-12-22
本文原始碼:[GitHub·點這裡](https://github.com/cicadasmile/middle-ware-parent) || [GitEE·點這裡](https://gitee.com/cicadasmile/middle-ware-parent)
# 一、模式描述
![](https://img2020.cnblogs.com/blog/1691717/202012/1691717-20201222000728407-710422319.png)
**授權服務**
驗證第三方服務的身份,驗證郵箱使用者的身份,記錄和管理認證Token,為資源伺服器提供Token校驗。場景:第三方網站藉助使用者的郵箱登入,並訪問郵箱賬戶的基礎資訊,頭像、名稱等。
**資源服務**
第三方服務通過郵箱賬戶登入後需要獲取的一些資訊,即理解為資源,儲存郵箱賬戶的資料資源。
**第三方服務**
即藉助郵箱使用者的賬戶,快速登入第三個服務,免去繁雜的註冊流程,有助於快速積累新使用者。
**互動流程**
第三方服務給使用者開放快速郵箱登入功能,引導使用者調到郵箱認證服務,通過認證後返回身份令牌到第三方服務,第三方服務攜帶令牌訪問郵箱的資源服務,獲取一些基本的郵箱使用者資訊。
# 二、專案配置管理
## 1、案例結構
![](https://img2020.cnblogs.com/blog/1691717/202012/1691717-20201222000742811-1019875819.png)
**核心依賴**
```xml
```
這裡有兩個核心元件依賴:OAuth2元件和Security元件。
**模組劃分**
- auth-server:授權服務
- resource-server:資源伺服器
- third-server:第三個服務
## 2、配置描述
【授權服務】
**OAuth2配置**
這裡的配置管理的是第三方的授權流程和發放給第三方的身份證明ClientID和密碼,實際的場景就是第三方藉助郵箱賬號登入,首先就是向郵箱管理方提供材料,獲取訪問郵箱服務的身份證明,然後才能對接開放服務,這種模式在第三方對接業務中很常見。
```java
/**
* 模擬第三方授權配置
*/
@EnableAuthorizationServer
@Configuration
public class AuthConfig extends AuthorizationServerConfigurerAdapter {
@Resource
ClientDetailsService clientDetailsService;
/**
* 資源伺服器校驗Token
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer security) {
security.checkTokenAccess("permitAll()").allowFormAuthenticationForClients();
}
/**
* 第三方客戶端請求配置,和資源服務訪問的配置,不設定預設都可以訪問,提供預設回撥地址
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("third01")
.secret(new BCryptPasswordEncoder().encode("third01"))
.resourceIds("resource-01")
.authorizedGrantTypes("authorization_code","refresh_token")
.scopes("all")
.redirectUris("http://localhost:8082/notify.html");
}
/**
* 配置訪問端點
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints.authorizationCodeServices(authorizationCodeServices()).tokenServices(tokenServices());
}
/**
* 記憶體管理
*/
@Bean
AuthorizationCodeServices authorizationCodeServices() {
return new InMemoryAuthorizationCodeServices();
}
/**
* Token管理規則
*/
@Bean
AuthorizationServerTokenServices tokenServices() {
DefaultTokenServices services = new DefaultTokenServices();
services.setClientDetailsService(clientDetailsService);
services.setSupportRefreshToken(true);
services.setTokenStore(tokenStore());
services.setAccessTokenValiditySeconds(3600);
services.setRefreshTokenValiditySeconds(3600*7);
return services;
}
@Bean
TokenStore tokenStore() {
return new InMemoryTokenStore();
}
}
```
通常需要資料庫儲存第三方資訊,可以到第OAuth2開源專案中,獲取表結構放到本地資料庫中,然後這裡換成資料來源載入模式即可,簡單的流程管理都在原始碼裡寫了SQL語句,資料來源引入即可。
**Security配置**
```java
/**
* 模擬本地使用者配置
*/
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 密碼加密方式
*/
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
/**
* 記憶體中虛擬使用者和角色
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user")
.password(new BCryptPasswordEncoder().encode("123456"))
.roles("user");
}
/**
* 表單登入
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().formLogin();
}
}
```
基於這裡的配置管理郵箱使用者的認證流程,例如使用郵箱賬號密碼登入驗證,判斷授權是否成立,這裡管理的是服務本地的郵箱賬號,基於資料來源儲存資料在下面案例中都有。
- 案例一:[JWT元件管理身份驗證機制](https://mp.weixin.qq.com/s/CYvsho_kCwUndTuDkDOvOg)
- 案例二:[Shiro元件實現使用者許可權管理](https://mp.weixin.qq.com/s/3tyPcvfUzv6BI8KWkLZ53w)
- 案例三:[Security使用者安全認證流程](https://mp.weixin.qq.com/s/7GYddhPSf3C7ZSEqF7OZKw)
關於Spring框架中安全認證的相關的幾個元件,在使用OAuth2之前可以先了解一下。
【資源服務】
主要功能有三塊,配置第三方攜帶的Token身份令牌校驗機制,即訪問授權服務校驗介面,這裡是OAuth2自定義好的介面;配置resourceId資源服務的編號,用來控制第三個服務能訪問的資源服務範圍,屬於大的許可權點控制;模擬校驗使用者的Role角色,較精細的控制權限。
```java
/**
* 資源服務管理配置
*/
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
/**
* Token令牌校驗
*/
@Bean
RemoteTokenServices tokenServices() {
RemoteTokenServices services = new RemoteTokenServices();
services.setCheckTokenEndpointUrl("http://localhost:8080/oauth/check_token");
services.setClientId("third01");
services.setClientSecret("third01");
return services;
}
/**
* 服務資源ID配置
*/
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("resource-01").tokenServices(tokenServices());
}
/**
* 模擬使用者許可權規則
*/
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/user/**").hasRole("user")
.anyRequest().authenticated();
}
}
```
【第三方服務】
主要提供兩個流程的模擬:請求授權服務獲取身份令牌;攜帶身份令牌請求資源服務獲取資料。這裡則是授權碼回撥介面的處理方式。
```java
@Controller
public class NotifyController {
private static final Logger LOG = LoggerFactory.getLogger(NotifyController.class);
@Resource
private RestTemplate restTemplate;
@GetMapping("/notify.html")
public String notify(String code, Model model) {
if (code != null) {
Multi