工作場景流程

大家都知道OAuth是用於第三方授權的,當你用其他的APP想訪問微信賬號的暱稱、粉絲、聯絡人等資訊,這裡就需要微信進行授權,此時在APP的網頁端是可以發現有微信登入的,點開會出現彈框,在彈框中輸入使用者名稱和密碼,此時即同意授權,會直接到微信授權服務端獲取授權碼Code,接著通過302重定向到redirect,並且把生成的code加入到redirect的後面,此時連結會訪問到APP的服務端,此時APP伺服器會利用擷取到的code到微信的授權伺服器,對code進行驗證,驗證通過就會生成token,此時token傳輸到APP的伺服器,此時會在微信的資源伺服器驗證APP獲取的token進行驗證,如果驗證通過此時會把資源傳輸到APP的伺服器,並傳入到APP顯現出來。

如圖所示:工作流程圖,從19

在程式設計的過程中需要在服務端確定哪些東西呢?

如圖所示,需要確定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