《Spring Security實現OAuth2.0授權服務 - 基礎版》和《Spring Security實現OAuth2.0授權服務 - 進階版》兩篇文章中介紹如何搭建OAuth2.0授權服務器和資源服務器。
本文將繼續優化,將授權服務器和資源服務器分離,部署在不同的服務器上面。
一、簡要說明
Spring Security OAuth2.0既可以把授權服務器(AuthorizationServer)和資源服務器(ResourceServer)配置在一個應用中,也可以分開配置。
授權服務器負責用戶登錄、授權、token驗證等。
資源服務器負責提供受保護資源,只是需要到授權服務器進行token驗證。
在此部分,將介紹以下內容:
- 如何將AuthorizationServer和ResourceServer分開配置,各司其職。
- 使用postman替換curl命令作為接口調用的工具。
- 依賴、實體類、工具類、DAO、Service、授權頁、登錄頁等內容與上一部分沒有區別,不再贅述,只記錄需要修改的內容。
二、AuthorizationServer配置
在上一部分的代碼(Spring Security實現OAuth2.0進階)中抽取以下內容:
- 實體類。
- 登錄頁和授權頁。
- DAO和Service層。
- Mybatis配置、Security配置和AuthorizationServerConfigurer配置。
需要修改一部分代碼。
1、修改AuthorizationServerConfigurer配置
重寫configure(AuthorizationServerSecurityConfigurer)方法,配置前來驗證token的client需要擁有ROLE_TRUSTED_CLIENT角色。
1 @Configuration 2 public class Oauth2AuthorizationServerConfiguration extends 3 AuthorizationServerConfigurerAdapter { 4 5 @Autowired 6 private UserDetailsService userDetailsService; 7 @Autowired 8 private DataSource dataSource; 9 10 @Override 11 public void configure(AuthorizationServerSecurityConfigurer security) 12 throws Exception { 13 // 配置前來驗證token的client需要擁有的角色 14 security.checkTokenAccess("hasAuthority('ROLE_TRUSTED_CLIENT')"); 15 } 16 17 @Override 18 public void configure(ClientDetailsServiceConfigurer clients) 19 throws Exception { 20 // 不變 21 } 22 23 @Override 24 public void configure(AuthorizationServerEndpointsConfigurer endpoints) 25 throws Exception { 26 // 不變 27 } 28 }
2、修改啟動類
啟動類刪除@EnableResourceServer注解。
1 @SpringBootApplication 2 @EnableAuthorizationServer 3 @MapperScan("org.net5ijy.oauth2.repository") 4 public class Oauth2AuthorizationServer { 5 6 public static void main(String[] args) { 7 8 // args = new String[] { "--debug" }; 9 10 SpringApplication.run(Oauth2AuthorizationServer.class, args); 11 } 12 }
三、ResourceServer配置
在上一部分的代碼(Spring Security實現OAuth2.0進階)中抽取以下內容:
- 響應工具類
- 受保護資源controller
1、配置Spring Security
1 @EnableWebSecurity 2 public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 3 4 @Override 5 protected void configure(HttpSecurity http) throws Exception { 6 7 http.authorizeRequests().antMatchers("/order/**").authenticated(); 8 9 // 禁用CSRF 10 http.csrf().disable(); 11 } 12 }
2、配置ResourceServerConfigurer
需要配置一個受信任的client到授權服務器驗證token令牌。
1 @Configuration 2 public class Oauth2ResourceServerConfiguration extends ResourceServerConfigurerAdapter { 3 4 private static final String URL = "http://localhost:7002/oauth/check_token"; 5 6 @Override 7 public void configure(ResourceServerSecurityConfigurer resources) 8 throws Exception { 9 10 RemoteTokenServices tokenService = new RemoteTokenServices(); 11 tokenService.setCheckTokenEndpointUrl(URL); 12 tokenService.setClientId("net5ijy"); 13 tokenService.setClientSecret("12345678"); 14 15 resources.tokenServices(tokenService); 16 } 17 }
3、修改啟動類
啟動類刪除@EnableAuthorizationServer注解。
1 @SpringBootApplication 2 @EnableResourceServer 3 public class Oauth2ResourceServer { 4 5 public static void main(String[] args) { 6 SpringApplication.run(Oauth2ResourceServer.class, args); 7 } 8 }
四、測試授權碼模式
首先啟動授權服務器,再啟動資源服務器。
1、獲取authorization_code授權碼
使用瀏覽器訪問:
http://localhost:7002/oauth/authorize?response_type=code&client_id=tencent&redirect_uri=http://localhost:8080&scope=all
地址
http://localhost:7002/oauth/authorize
參數
response_type |
code |
client_id |
根據實際的client-id填寫,此處寫tencent |
redirect_uri |
生成code后的回調地址,http://localhost:8080 |
scope |
權限范圍 |
登錄,admin002和123456
允許授權
看到瀏覽器重定向到了http://localhost:8080並攜帶了code參數,這個code就是授權服務器生成的授權碼
2、獲取token令牌
地址
http://localhost:7002/oauth/token
參數
grant_type |
授權碼模式,寫authorization_code |
scope |
權限范圍 |
redirect_uri |
回調地址,http://localhost:8080需要urlencode |
code |
就是上一步生成的授權碼 |
使用postman獲取token令牌。
返回值
1 { 2 "access_token": "e50a400c-439f-4df0-95d5-79154d2cbf87", 3 "token_type": "bearer", 4 "refresh_token": "29ac936f-69ef-4356-91b1-775fbec65805", 5 "expires_in": 3599, 6 "scope": "all" 7 }
這樣就獲取到了token令牌,該token的訪問權限范圍是all權限,在1小時后失效。
3、使用token訪問資源
http://localhost:7003/order/demo?access_token=e50a400c-439f-4df0-95d5-79154d2cbf87
五、Github源碼下載
https://github.com/xuguofeng/springsecurityoauth2