工作場景流程
大家都知道OAuth
是用於第三方授權的,當你用其他的APP
想訪問微信賬號的暱稱、粉絲、聯絡人等資訊,這裡就需要微信進行授權,此時在APP
的網頁端是可以發現有微信登入的,點開會出現彈框,在彈框中輸入使用者名稱和密碼,此時即同意授權,會直接到微信授權服務端獲取授權碼Code
,接著通過302
重定向到redirect
,並且把生成的code
加入到redirect
的後面,此時連結會訪問到APP
的服務端,此時APP
伺服器會利用擷取到的code
到微信的授權伺服器,對code
進行驗證,驗證通過就會生成token
,此時token
傳輸到APP
的伺服器,此時會在微信的資源伺服器驗證APP
獲取的token
進行驗證,如果驗證通過此時會把資源傳輸到APP
的伺服器,並傳入到APP
顯現出來。
如圖所示:工作流程圖,從1
到9
。
在程式設計的過程中需要在服務端確定哪些東西呢?
如圖所示,需要確定4部分其中在授權碼模式下式不需要client_secret
的。
它的請求url
如下:
請求url:localhost:8080/oauth/authorize?client_id=client&respose_type=code&redirect_url=http://www.baidu.com
想獲取認證,此時需要輸入微信的使用者名稱與密碼,同意授權,生成code
,進行重定向。
重定向url:http://www.baidu.com/?code=fnajlgah
假如APP
是百度,此時重定向之後百度服務端會得到code
,利用code
獲取token
,得到token
之後就會得到資源伺服器獲取得到資源。
程式碼中兩種配置方式
常見的兩種配置方式,第一種常用於測試中,利用到了InMemory
的方式,資料都存在記憶體中。
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory() // 使用in-memory儲存
.withClient("client") // client_id
.secret("secret") //client_secret
.authorizedGrantTypes("authorization_code") // 該client允許的授權型別
.scopes("app"); // 允許的授權範圍
}
這種只能用於測試,當執行緒結束之後,所有的東西都會清楚。另一種方式是資料庫JDBC
實現,所有的資料都會持久化到資料庫。
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private DataSource dataSource;
@Bean // 宣告TokenStore實現
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
@Bean // 宣告 ClientDetails實現
public ClientDetailsService clientDetails() {
return new JdbcClientDetailsService(dataSource);
}
@Override // 配置框架應用上述實現
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager); endpoints.tokenStore(tokenStore());
// 配置TokenServices引數
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setTokenStore(endpoints.getTokenStore());
tokenServices.setSupportRefreshToken(false);
tokenServices.setClientDetailsService(endpoints.getClientDetailsService());
tokenServices.setTokenEnhancer(endpoints.getTokenEnhancer());
tokenServices.setAccessTokenValiditySeconds( (int) TimeUnit.DAYS.toSeconds(30)); // 30天
endpoints.tokenServices(tokenServices); }
這個授權協議蠻複雜的,想完全弄懂還有很長的路要走,但是這是每個開發者必須要去弄懂的,路漫漫。。。
請關注我的公眾號:CodeJames