1. OAuth2簡易實戰(一)-四種模式
1.1. 授權碼授權模式(Authorization code Grant)
1.1.1. 流程圖
1.1.2. 授權服務器配置
- 配置授權服務器中 client,secret,redirectUri,授權模式,權限配置
//授權服務器配置 @Configuration @EnableAuthorizationServer public class OAuth2AuthorizationServer extends AuthorizationServerConfigurerAdapter { @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("clientapp") .secret("112233") .redirectUris("http://localhost:9001/callback") // 授權碼模式 .authorizedGrantTypes("authorization_code") .scopes("read_userinfo", "read_contacts"); } }
1.1.3. 資源服務器配置
- 配置需要資源授權的接口地址
//資源服務配置 @Configuration @EnableResourceServer public class OAuth2ResourceServer extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .anyRequest() .authenticated() .and() .requestMatchers() .antMatchers("/api/**"); } }
1.1.4. 操作步驟
- 瀏覽器請求下列地址,獲取授權code,請求參數client_id,redirect_uri回調地址,response_type響應類型,scope權限
http://localhost:8080/oauth/authorize?client_id=clientapp&redirect_uri=http://localhost:9001/callback&response_type=code&scope=read_userinfo
- 輸入用戶名密碼,該密碼為Spring Security的登路密碼,application.properties里配置
# Spring Security Setting security.user.name=bobo security.user.password=xyz
- 登陸后顯示
- 選擇Approve,點擊Authorize,會調用回調地址並返回code參數
- 在獲得授權碼后,接下去獲取訪問令牌,訪問
http://localhost:8080/oauth/token?code=ghN0hF&grant_type=authorization_code&redirect_uri=http://localhost:9001/callback&scope=read_userinfo
注意:需要在headers里添加認證
認證參數就是授權服務器配置的client和secret
- 獲取token后訪問
http://localhost:8080/api/userinfo?access_token=f4345f3a-34a3-4887-bc02-e95150c54bf4
如果token錯誤,則
1.1.5. 使用場景
- 授權碼模式是最常見的一種授權模式,在oauth2.0內是最安全和最完善的。
- 適用於所有有Server端的應用,如Web站點、有Server端的手機客戶端。
- 可以得到較長期限授權。
1.2. 隱式授權模式(Implicit Grant)
1.2.1. 流程圖
1.2.2. 改動 authorizedGrantTypes
@Configuration @EnableAuthorizationServer public class OAuth2AuthoriationServer extends AuthorizationServerConfigurerAdapter{ @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("clientapp") .secret("112233") .accessTokenValiditySeconds(60) .redirectUris("http://localhost:9001/callback") .authorizedGrantTypes("implicit") .scopes("admin", "visitor"); } }
1.2.3. 操作步驟
- 申請授權token,參數和申請授權碼類似,client_id,redirect_uri回調地址,response_type有變動,改為直接獲取token,scope權限,state用於認證標記,傳過去什么回調時傳回來什么
http://localhost:8080/oauth/authorize?client_id=clientapp&redirect_uri=http://localhost:9001/callback&response_type=token&scope=admin&state=abc
- 操作同上,輸入密碼跳轉認證確認,選Approve后點Authorize,跳轉
- 可以看到直接返回了access_token,state也是原樣返回
- 之后按授權碼模式第六步操作,把access_token參數帶上,進行接口調用就可以了
1.2.4. 使用場景
- 適用於所有無Server端配合的應用
- 如手機/桌面客戶端程序、瀏覽器插件。
- 基於JavaScript等腳本客戶端腳本語言實現的應用。
注意:因為Access token是附着在 redirect_uri 上面被返回的,所以這個 Access token就可能會暴露給資源所有者或者設置內的其它方(對資源所有者來說,可以看到redirect_uri,對其它方來說,可以通過監測瀏覽器的地址變化來得到 Access token)。
1.3. 密碼模式(Resource Owner Password Credentials Grant)
1.3.1. 流程圖
1.3.2. 改動
- 授權服務器配置,需要添加用戶認證管理端點authenticationManager,修改模式authorizedGrantTypes為password
// 授權服務器配置 @Configuration @EnableAuthorizationServer public class OAuth2AuthoriationServer extends AuthorizationServerConfigurerAdapter{ @Autowired private AuthenticationManager authenticationManager; @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.authenticationManager(authenticationManager); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("clientapp") .secret("112233") .accessTokenValiditySeconds(60) .redirectUris("http://localhost:9001/callback") .authorizedGrantTypes("password") .scopes("admin", "visitor"); } }
1.3.3. 操作步驟
- 調用以下鏈接,向客戶端和服務器提供用戶名密碼
http://localhost:8080/oauth/token?password=123456&grant_type=password&username=lll&scope=admin
注意:和授權碼模式一樣,需要在headers里添加認證
-
結果:
-
獲取token后,步驟同1.1和1.2模式
1.3.4. 使用場景
- 這種模式適用於用戶對應用程序高度信任的情況。比如是用戶操作系統的一部分。
- 認證服務器只有在其他授權模式無法執行的情況下,才能考慮使用這種模式。
1.4. 客戶端憑證模式(Client Credentials Grant)
1.4.1. 流程圖
1.4.2. 改動
- 只需修改授權服務器,authorizedGrantTypes類型client_credentials
1.4.3. 操作步驟
http://localhost:8080/oauth/token?grant_type=client_credentials&scope=admin
- 可以看到客戶端憑證模式也需要在header里添加認證賬戶密碼
- 獲得token后操作同上
1.4.4. 使用場景
- 客戶端模式應用於應用程序想要以自己的名義與授權服務器以及資源服務器進行互動。
- 例如使用了第三方的靜態文件服務
1.5. 刷新TOKEN
1.5.1. 流程圖
1.5.2. 改動
1.5.3. 操作步驟
- 以授權碼模式為例,步驟同授權碼模式,取得授權碼后,去取token時,返回
- 在token過期后,調用
http://localhost:8080/oauth/token?grant_type=refresh_token&refresh_token=ad3941d1-c6dd-4a2e-a9c8-eac6a9a59dd2
- 返回
- 就可以拿新的access_token繼續調用了
- 建議將access_token和refresh_token的過期時間保存下來,每次調用平台方的業務api前先對access_token和refresh_token進行一下時間判斷,如果過期則執行刷新access_token或重新授權操作。refersh_token如果過期就只能讓用戶重新授權。
參考 https://www.cnblogs.com/maoxiaolv/p/5838680.html
代碼學習地址 https://github.com/spring2go/oauth2lab