OAuth 2 開發人員指南

這是支持OAuth2.0的用戶指南。對於OAuth1.0,一切都是不一樣的,因此看它的用戶指南。
本用戶指南分爲兩個部分,第一部分是OAuth2.0提供端(OAuth 2.0 Provider),第二部分是OAuth2.0的客戶端(OAuth 2.0 Client)
OAuth2.0提供端

OAuth2.0的提供端的用途是負責將受保護的資源暴露出去。配置包括創建一個能夠訪問受保護的資源的客戶端表明。提供端是經過管理和驗證可用於訪問受保護的資源的OAuth 2令牌來作的。在適當的地方,提供端也必須爲用戶提供一個用於確認客戶端 是否可以訪問受保護的資源的接口(也就是一個頁面或是一個窗口)。
Knowvin
Knowvin

在 OAuth 2 提供者實際上是分紅受權服務和資源服務兩個角色的,而這兩個角色有時是存在於同一個應用程序中的,經過 Spring Security OAuth 你能夠有選擇的將它們分裂到兩個應用程序中,也能夠有選擇的給受權服務配置多個資源服務。獲取令牌(Tokens)的請求是由Spring MVC的控制器端點來處理的,訪問受保護的資源是經過標準的Spring Security請求過濾器來處理的。
下面列舉的端點是 Spring Security 過濾器鏈實現 OAuth 2 受權服務器必須的端點:
AuthorizationEndpoint  是用於受權服務請求的。默認的URL是:/oauth/authrize。
TokenEndpoint  是用於獲取訪問令牌(Access Tokens)的請求。默認的URL是:/oauth/token。
下面過濾器是實現一個OAuth2資源服務器所必須的:
OAuth2AuthenticationProcessingFilter 這個過濾器是用於加載請求提供的一個受權了的訪問令牌是否有效。
對於全部的OAuth 2.0的提供端,經過使用Spring OAuth專門的@Configuration適配器來簡化配置。也能夠經過XML命名空間來配置OAuth,XML的schema存在:http://www.springframework.org/schema/security/spring-security-oauth2.xsd。命令空間是http://www.springframework.org/schema/security/oauth2

配置受權服務器時,您必須考慮的grant類型,從終端用戶那,客戶端會使用獲取到的訪問令牌(如受權代碼、用戶憑證、刷新令牌)。服務器的配置是用於提供一些實現,像客戶端細節服務和令牌服務還有啓用或禁用某些方面的全球機制。可是請注意,每一個客戶端能夠專門配置權限可以使用某些受權機制和訪問受權。即僅僅由於您的提供者配置爲支持「客戶證書」grant類型,並不意味着一個特定的客戶端被受權使用grant類型。

@EnableAuthorizationServer 註釋用於配置 OAuth 2.0 受權服務器機制,加上任意一個
@Beans 去實現 AuthorizationServerConfigurer (這是一個hander適配器實現的空方法)。
如下功能委託給由 spring 創造的獨立 configurers 並且傳遞到 AuthorizationServerConfigurer:
ClientDetailsServiceConfigurer:
這個configurer定義了客戶端細節服務。
客戶詳細信息能夠被初始化,或者你能夠參考現有的商店。
AuthorizationServerSecurityConfigurer:在令牌端點上定義了安全約束。
AuthorizationServerEndpointsConfigurer:定義了受權和令牌端點和令牌服務

提供端配置中重要的一項是提供給OAuth 客戶端的受權碼。 OAuth 客戶端經過將終端用戶導向一個能夠輸入證書/口令的受權驗證頁面來獲取受權碼,而後,將受權碼傳遞給提供端受權服務器,服務器驗證後重定向頁面。 在 OAuth 2 說明文檔中有詳細的示例。
在 xml 配置文件中,可使用<authorization-server/>節點配置 OAuth 2.0 受權服務器。


ClientDetailsServiceConfigurer 類(AuthorizationServerConfigurer類中的一個調用類)能夠用來定義一個基於內存的或者JDBC的客戶端信息服務。 
客戶端對象重要的屬性有:
clientId:(必須)客戶端id。
secret:(對於可信任的客戶端是必須的)客戶端的私密信息。
scope:客戶端的做用域。若是scope未定義或者爲空(默認值),則客戶端做用域不受限制。
authorizedGrantTypes:受權給客戶端使用的權限類型。默認值爲空。
authorities:受權給客戶端的權限(Spring普通的安全權限)。
在運行的應用中,能夠經過直接訪問隱藏的存儲文件(如:JdbcClientDetailsService中用到的數據庫表)或者經過實現ClientDetailsManager 接口(也能夠實現ClientDetailsService 接口,或者實現兩個接口)來更新客戶端信息。

AuthorizationServerTokenServices 接口裏定義了 OAuth 2.0 令牌的操做方法。 注意如下幾點:
建立一個訪問令牌時,必須保存權限信息,這樣後續令牌才能夠引用它。
訪問令牌用於加載建立令牌時的受權信息。
建立AuthorizationServerTokenServices 接口的實現類時,你能夠考慮使用DefaultTokenServices 類,它使用隨機值建立令牌,並處理除永久令牌之外的全部令牌,對於永久令牌,它委託TokenStore類進行處理。 令牌默認採用基於內存實現的存儲方式,但也有一些其它的存儲方式。 下面是其中一些方式的簡介:
默認的InMemoryTokenStore 處理類對於單服務器場景很是適用(優勢有:低阻塞,宕機時無需熱切換到備份服務器)。大部分項目能夠在開始時或者在開發模式下使用這種方式,這樣比較容易啓動一個沒有其它依賴的服務器。
JdbcTokenStore 類是實現存儲令牌的JDBC 版本,它將令牌信息保存到關係型數據庫中。 若是服務器間共享數據庫或者同一個服務器有多個實例或者受權服務器、資源服務器有多個組件,那麼可使用JDBC方式存儲令牌。 使用JdbcTokenStore 類時,須要將spring-jdbc組件jar包添加到工程的編譯路徑中。
JSON網頁令牌(JWT)能夠加密全部令牌受權訪問的數據(所以不須要在後臺存儲數據,這就是JWT一個重要的優勢)。 缺點是你不能方便地撤銷一個已受權的令牌(所以通常它們被受權的有效期較短,撤銷受權的操做在刷新令牌中進行)。 另外一個缺點是存儲的令牌數據會愈來愈大由於在令牌裏面存儲了大量的用戶證書信息。 JwtTokenStore 類不是一個真正的存儲類,它未持久化(保存)任何數據,可是它在傳輸令牌信息和受權信息(在DefaultTokenServices類中實現)中扮演了一樣的角色。 JwtTokenStore(接口)類依賴JwtAccessTokenConverter類,受權服務器和資源服務器都須要接口的實現類(所以他們能夠安全地使用相同的數據並進行解碼)。 令牌以默認方式進行簽名,資源服務器爲了可以驗證這些簽名,它須要有與受權服務器相同的對稱密鑰(服務器共享對稱密鑰),或者它須要有能夠匹配簽名私鑰的公鑰(公有私有密鑰或混合密鑰)。 爲了使用JwtTokenStore 類,你須要在工程編譯路徑下添加spring-security-jwt組件jar包(你能夠在Spring OAuth的github資源庫中找到,可是二者的版本號是不一致的)。

Grant 類型
AuthorizationEndpoint 經過 AuthorizationServerEndpointsConfigurer 能夠配置支持 
Grant 類型。默認狀況下支持全部的 grant 類型,除了密碼(有關詳細信息,請參閱下面的信息如何開啓和關閉)。
如下屬性影響grant類型:
     authenticationManager:密碼授予被注入一個authenticationManager開啓。
     authorizationCodeServices:爲了身份驗證代碼授予定義了受權代碼服務(org.springframework.security.oauth2.provider.code.AuthorizationCodeServices實例).
     implicitGrantService:在隱式授予管理狀態。
     tokenGranter:TokenGranter(徹底掌控的授予和忽略上面的其餘屬性)?在XML grant類型包括authorization-server的子元素。

	
配置端點的URL
AuthorizationServerEndpointsConfigurer有一個pathMapping()方法。該方法有兩個參數:
defaultPath 默認的端點URL
customPath 自定義的URL 
框架本身提供的URL路徑是/oauth/authorize(受權端),/oauth/token (令牌端),/oauth/confirm_access (用戶發送確認受權到這裏),還有/oauth/error (用戶呈現受權服務器受權出錯的請求)。
注意:受權端/oauth/authorize(或者是它的影射)應該是受Spring Security保護的,因此它只能被已受權的用戶訪問。令牌端默認是經過使用支持使用HTTP基自己份驗證客戶機的祕密的註解@Configuration,被Spring Oauth保護的,但不是使用XML文件的(因此在這種狀況下它被保護是很明確的)。
使用XML的<authorization-server/>元素可使用一些屬性來達到改變默認的端點URL。

自定義錯誤處理
受權服務器上錯誤處理使用標準的 Spring MVC 功能,即 @ExceptionHandler 端點自己的方法。用戶還能夠提供一個 WebResponseExceptionTranslator 端點自己,最好的辦法是改變響應的內容而不是他們呈現的方式。異常的呈現表明 HttpMesssageConverters (這個能夠添加到MVC的配置中)令牌的端點和OAuth的錯誤視圖(/ OAuth /error)的受權端點。提供一個whitelabel錯誤端點,可是用戶可能須要提供一個自定義的實現(例如,就添加一個 @Controller,它的請求映射是 @RequestMapping(「/ oauth /error」))。

配置資源服務器
資源服務器(可能和受權服務器或者一個單獨的應用程序在同一臺主機上)提供被OAuth2 令牌保護的資源。 Spring OAuth提供一個Spring Security受權過濾器,它實現保護資源的功能。在@Configuration類中,你可使用@EnableResourceServer來開啓/關閉過濾器,使用ResourceServerConfigurer來配置它。 下面是可配置的屬性:
tokenServices:定義令牌服務的實體(ResourceServerTokenServices類的實例)。
resourceId:資源ID(可選的,建議配置,若是不爲空,受權服務器會對它進行驗證)。
@EnableResourceServer註解把一個 OAuth2AuthenticationProcessingFilter 類型過濾器添加到Spring Security 過濾鏈中。
在 XML中,有一個<resource-server/>元素,它有一個id屬性 – 這是servlet過濾器的bean id,它過濾哪些能夠被添加到Spring Security鏈中。

配置OAuth-Aware表達式處理器

你可能想要使用Spring Security的使用表達式語言配置訪問控制的優勢。 表達式處理器在 @EnableResourceServer配置中以默認方式進行註冊。 表達式包括#oauth2.clientHasRole,#oauth2.clientHasAnyRole, 和 #oath2.denyClient,這些能夠提供基於oauth客戶端角色的訪問控制(詳細列表見OAuth2SecurityExpressionMethods)。 在XML中,你能夠在<http/> 安全配置節點內使用expression-handler元素註冊一個oauth-aware表達式處理器。
OAuth 2.0 客戶端

OAuth 2.0 客戶端控制着 OAuth 2.0保護的其它服務器的資源的訪問權限。 配置包括創建相關受保護資源與有權限訪問資源的用戶之間的鏈接。 客戶端也須要實現存儲用戶的受權代碼和訪問令牌的功能。


受保護的資源(或稱爲遠程資源)可使用OAuth2ProtectedResourceDetails類型的實體bean定義。 一個受保護的資源有如下屬性:
id:資源id。它僅在客戶端搜索資源的時候使用;在OAuth協議中它從未被用到。它也被用做bean的id。
clientId:OAuth客戶端id。OAuth提供端依賴這個id來識別客戶端。
clientSecret:與資源有關的祕密。默認狀況下,該值不爲空。
accessTokenUri:提供訪問口令的OAuth提供者終端的統一資源標識符(URI)。
scope:以逗號分隔的字符串列表,標識可訪問資源的範圍。默認狀況下,該值爲空。
clientAuthenticationScheme: 客戶端對訪問的令牌終端受權時使用的機制。 建議值: "http_basic" 和 "form"。 默認值: "http_basic"。 見OAuth 2 幫助文檔2.1節。
不一樣的受權類型有不一樣的實現OAuth2ProtectedResourceDetails (對於client_credentials受權類型,使用ClientCredentialsResource )的方式。對於須要進行用戶身份驗證的受權類型,還有一個屬性:
userAuthorizationUri: 用戶訪問資源須要身份驗證時跳轉頁面的URI。 注意這個字段不是必填的,它依賴於被支持的OAuth 2的配置文件類型。
在XML中,可使用<resource/>元素建立一個OAuth2ProtectedResourceDetails類型的實體bean。 它有上面提到的全部的屬性。

使用@EnableOAuth2Client對OAuth2.0的客戶端的配置比較簡單。主要要作兩件事情:
建立一個過濾bean(用oauth2ClientContextFilter)來存儲當前的請求和上下文。在這種狀況下須要在請求期間受權,來管理從重定向的位置和OAuth已認證的url。
在請求做用域中建立一個AccessTokenRequest類型的bean。這個類型的bean能夠在我的用戶的衝突中被識別碼識別(或隱式的),受權客戶端保持受權狀態。
這個過濾器須要可以鏈接到應用(例如,使用Servlet初始化程序或者web.xml配置文件配置 一個和DelegatingFilterProxy相同名稱的代理)。


在一個OAuth2RestTemplate中AccessTokenRequest能夠這樣使用:
@Autowired
private OAuth2ClientContext oauth2Context;
 
@Bean
public OAuth2RestTemplate sparklrRestTemplate() {
    return new OAuth2RestTemplate(sparklr(), oauth2Context);
}
OAuth2ClientContext能夠在Session的做用域中保持不一樣用戶不一樣的狀態。若是沒有這個功能,你須要在你本身的服務強上管理等效的數據結構,映射不用用戶進來的請求而且用相互隔離的OAuth2ClientContext實例鏈接各個用戶。
在XML文件中,有一個帶有id屬性的<client/>標籤用於表示servlet的Filter的bean id,這個必須映射成一個和DelegatingFilterProxy有相同名稱的@Configuration註解。


一旦,你已經提供了全部的資源服務器配置時,如今你能夠訪問這些資源。建議的訪問這些資源是經過使用在Spring3中提到的RestTemplate。Spring Security OAuth已經提供了一個擴展的RestTemplate,只須要提供一個OAuth2ProtectedResourceDetails的實例。使用它與user-tokens(受權代碼授予)你應該考慮使用@EnableOAuth2Client配置(或XML等價< oauth:rest-template / >),形成了一些請求和會話做用域上下文對象,要求不一樣的用戶在運行時不發生衝突。
客戶端持久化訪問令牌

客戶端不須要持久化令牌,可是它能夠很好的用戶不須要批准一個新的令牌格蘭特每次從新啓動客戶機應用程序。ClientTokenServices接口定義所需的操做持續OAuth 2.0爲特定用戶令牌。提供一個JDBC實現,可是若是你喜歡的話你能夠實現本身的服務以存儲的訪問令牌持久數據庫和相關的驗證明例。若是你想使用此功能,你須要提供一個專門配置TokenProvider theOAuth2RestTemplate如

@Bean
@Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES)
public OAuth2RestOperations restTemplate() {
    OAuth2RestTemplate template = new OAuth2RestTemplate(resource(), new DefaultOAuth2ClientContext(accessTokenRequest));
    AccessTokenProviderChain provider = new AccessTokenProviderChain(Arrays.asList(new AuthorizationCodeAccessTokenProvider()));
    provider.setClientTokenServices(clientTokenServices());
    return template;
}


Knowvin
Knowvin
翻譯於 9個月前
0人頂
頂 翻譯的不錯哦!
爲外部 OAuth2 提供者定製客戶端

一些外部OAuth2提供商(如Facebook)不徹底實現正確規範,不然他們只是困在一箇舊版本比Spring Security OAuth的規範。在您的客戶機應用程序使用這些供應商可能須要適應客戶端基礎設施的各個部分。
使用Facebook做爲一個例子,有一個Facebook功能tonr2應用程序(您須要更改配置添加你本身的,有效的,客戶機id和祕密,他們很容易生成在Facebook網站上)。
Facebook響應令牌也包含一個不一致的、有失效時間的JSON實體(他們使用到期而不是expires_in),因此若是你想在應用程序中使用失效時間你將不得不使用一個自定義OAuth2SerializationService手動解碼。

 

 

https://github.com/ymero/HeidCloud/blob/master/OAuth%202%20%E5%BC%80%E5%8F%91%E4%BA%BA%E5%91%98%E6%8C%87%E5%8D%97.mdgit

相關文章
相關標籤/搜索