国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Java 編程中的 OAuth 2.0 客戶端,第 1 部分: 資源所有者密碼憑據授權

2019-11-15 01:07:01
字體:
來源:轉載
供稿:網友
java 編程中的 OAuth 2.0 客戶端,第 1 部分: 資源所有者密碼憑據授權

原文出處:IBM - Varun Ojha

概述

OAuth 是一個開放的授權標準,允許客戶端代表一個資源所有者獲得訪問受保護服務器資源的訪問權。資源所有者可以是另一個客戶端或最終用戶。OAuth 還可以幫助最終用戶將對其服務器資源的訪問權限授權給第三方,而不必共享其憑據,比如用戶名和密碼。本系列文章遵循 RFC 6749 中所列出的 OAuth 2.0 授權框架。可以在 Internet Engineering Task Force 的網站上找到 RFC 6749 中列出的完整 OAuth 2.0 授權框架(請參閱參考資料)。

授權批準

授權批準是一種憑據,可代表資源所有者用來訪問受保護資源的權限。客戶端使用此憑據獲取訪問令牌。訪問令牌最終與請求一起發送,以便訪問受保護資源。OAuth 2.0 定義了四種授權類型:

  1. 授權碼
  2. 隱式
  3. 資源所有者密碼憑據
  4. 客戶端憑據

本文是由四部分組成的系列中的第 1 部分,將引導您使用上面列出的每種授權類型在 Java™ 編程中實現 OAuth 2.0 客戶端。在第 1 部分中,我會告訴大家如何實現資源所有者密碼憑據授權。本文詳細介紹各種授權,并解釋示例客戶端代碼,此代碼可用于兼容 OAuth 2.0 的任何服務器接口,以支持此授權。在本文的最后,您應該對客戶端實現有全面的了解,并準備好下載示例客戶端代碼,自己進行測試。

資源所有者密碼憑據授權

當資源所有者對客戶端有高度信任時,資源所有者密碼憑據授權類型是可行的。此授權類型適合于能夠獲取資源所有者的用戶名和密碼的客戶端。對于使用 HTTP 基礎的現有企業客戶端,或者想遷移到 OAuth 的摘要式身份驗證,該授權最有用。然后,通過利用現有憑據來生成一個訪問令牌,然后就可以實現遷移。

例如,Salesforce.com 添加了 OAuth 2.0 作為對其現有基礎架構的一個授權機制。對于現有的客戶端轉變為這種授權方案,資源所有者密碼憑據授權將是最方便的,因為他們只需使用現有的帳戶詳細信息(比如用戶名和密碼)來獲取訪問令牌。

圖 1. 資源所有者密碼憑據流

該圖顯示資源所有者密碼憑據流

在 圖 1 中所示的流程包括以下步驟:

  1. 資源所有者提供一個可信的 OAuth 2.0 客戶端,并提供其用戶名和密碼。
  2. OAuth 2.0 客戶端對授權服務器的令牌端點發出訪問令牌請求,其中包括從資源所有者那里收到的憑據。在發出請求時,OAuth 2.0 客戶端使用由授權服務器提供的憑據和授權服務器進行身份驗證。
  3. 授權服務器對 OAuth 2.0 客戶端進行身份驗證,并驗證資源所有者憑據,如果該憑據是有效的,那么授權服務器會頒發一個訪問令牌。
訪問令牌請求

對應于第二個步驟的訪問令牌請求如 圖 1 所示。

客戶端對令牌端點(授權服務器)發出請求,采用 application/x-www-form-urlencoded 格式發送以下參數。

  • grant_type:必選項。必須將其值設置為 “passWord
  • username:必選項。資源所有者的用戶名。
  • password:必選項。資源所有者密碼。
  • scope:可選項。訪問請求的范圍

如果客戶端類型是機密的,或客戶端獲得了客戶端憑據(或者被分配了其他身份驗證要求),那么客戶端必須向授權服務器進行身份驗證。例如,客戶端使用傳輸層安全性發出下列 HTTP 請求。

清單 1. 向授權服務器進行身份驗證
12345POST /token HTTP/1.1Host: server.example.comAuthorization:Basic czZCaGRSa3F0MzpnWDFmQmF0M2JWContent-Type: application/x-www-form-urlencodedgrant_type=password&username=varun&password=ab32vr
訪問令牌響應

對應于上述步驟 C 的訪問令牌響應如圖 1所示。如果訪問令牌請求是有效的,并且獲得了授權,那么授權服務器將返回訪問令牌和一個可選的刷新令牌。清單 2 顯示了一個成功響應的示例。

清單 2. 成功的訪問令牌響應
123456789101112HTTP/1.1 200 OKContent-Type: application/json;charset=UTF-8Cache-Control: no-storePRagma: no-cache{"access_token":"2YotnFZFEjr1zCsicMWpAA","token_type":"example","expires_in":3600,"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA","example_parameter":"example_value"}

如果請求無效,或者是未經授權的,那么授權服務器將會使用代碼返回一個相應的錯誤消息。

設置

示例 OAuth 2.0 客戶端被附加為可導入Eclipse環境中的 Java 項目。您需要將第三方依賴關系 JAR 文件下載到 Java 項目中的 lib 文件夾中。

依賴關系 JAR 文件

該項目使用以下 JAR 文件:

  • commons-codec-1.6.jar
  • commons-logging-1.1.1.jar
  • httpclient-4.2.5.jar
  • httpclient-cache-4.2.5.jar
  • httpcore-4.2.4.jar
  • httpmime-4.2.5.jar
  • json-simple-1.1.1.jar

在前六項中提到的 JAR 文件可以在 Http Components JAR 文件中找到。下載這些文件和 json-simple-1.1.1.jar 文件的鏈接,請參見更多下載。確保已將下面這些可供下載的 JAR 文件復制到 Java 項目的 lib 文件夾。

先決條件

下載 Eclipse IDE for Java EE developers,以便設置開發環境,并導入附加項目。相關的鏈接請參見更多下載。

OAuth 2.0 客戶端

此處討論的 OAuth 2.0 客戶端實現了資源所有者密碼憑據授權。本系列文章的后續部分將描述其余授權類型,并繼續更新客戶端代碼。

輸入參數

使用在示例客戶端代碼下載(請參閱Download)中提供的 Oauth2Client.config 屬性文件向客戶端提供所需的輸入參數。

  • scope:這是一個可選參數。它代表訪問請求的范圍。由服務器返回的訪問令牌只可以訪問 scope 中提到的服務。
  • grant_type:需要將這個參數設置為"password",表示資源所有者密碼憑據授權。
  • username:用于登錄到資源服務器的用戶名。
  • password:用于登錄到資源服務器的密碼。
  • client_id:注冊應用程序時由資源服務器提供的客戶端或使用者 ID。
  • client_secret:注冊應用程序時由資源服務器提供的客戶端或使用者的密碼。
  • access_token:授權服務器響應有效的和經過授權的訪問令牌請求時返回的訪問令牌。作為該請求的一部分,您的用戶名和密碼將用于交換訪問令牌。
  • refresh_token:這是一個可選參數,由授權服務器在響應訪問令牌請求時返回。然而,大多數端點(比如 Salesforce、IBMWebSphere® Application Server 和 IBM DataPower)對資源所有者密碼憑據授權不返回刷新令牌。因此,我的客戶端實現不打算考慮刷新令牌。
  • authenticatation_server_url:這表示令牌端點。批準和重新生成訪問令牌的所有請求都必須發送到這個 URL。
  • resource_server_url:這表示需要聯系的資源服務器的 URL,通過將授權標頭中的訪問令牌傳遞給它來訪問受保護的資源。
清單 3. Oauth2Client 代碼
123456789101112131415161718192021222324252627282930313233343536Properties config = OAuthUtils.getClientConfigProps (OAuthConstants.CONFIG_FILE_PATH);String resourceServerUrl = config.getProperty(OAuthConstants.RESOURCE_SERVER_URL); String username = config.getProperty(OAuthConstants.USERNAME);String password = config.getProperty(OAuthConstants.PASSWORD);String grantType = config.getProperty(OAuthConstants.GRANT_TYPE);String authenticationServerUrl = config.getProperty(OAuthConstants.AUTHENTICATION_SERVER_URL);if (!OAuthUtils.isValid(username)|| !OAuthUtils.isValid(password)|| !OAuthUtils.isValid(authenticationServerUrl)|| !OAuthUtils.isValid(grantType)) {System.out.println("Please provide valid values for username, password,authentication server url and grant type");System.exit(0);}if (!OAuthUtils.isValid(resourceServerUrl)) {// Resource server url is not valid.//Only retrieve the access tokenSystem.out.println("Retrieving Access Token");OAuth2Details oauthDetails = OAuthUtils.createOAuthDetails(config);String accessToken = OAuthUtils.getAccessToken(oauthDetails);System.out.println("Successfully retrieved Access tokenfor Password Grant:" + accessToken);}else {// Response from the resource server must be in Json or//Urlencoded or xmlSystem.out.println("Resource endpoint url:" + resourceServerUrl);System.out.println("Attempting to retrieve protected resource");OAuthUtils.getProtectedResource(config);}

在清單 3中的客戶端代碼讀取 Oauth2Client.config 文件中所提供的輸入參數。usernamepasswordauthentication server urlgrant type的有效值是強制性的。如果配置文件中所提供的資源服務器 URL 是有效的,那么客戶端會嘗試檢索該 URL 中提供的受保護資源。否則,客戶端只對授權服務器發出訪問令牌請求,并取回訪問令牌。以下部分說明了負責檢索受保護資源和訪問令牌的代碼。

訪問受保護資源

清單 4 中的代碼演示了如何使用訪問令牌來訪問受保護的資源。

清單 4. 訪問受保護資源
123456789101112131415161718192021222324252627282930313233343536373839404142434445String resourceURL =config.getProperty(OAuthConstants.RESOURCE_SERVER_URL);OAuth2Details oauthDetails = createOAuthDetails(config);HttpGet get = new HttpGet(resourceURL);get.addHeader(OAuthConstants.AUTHORIZATION,getAuthorizationHeaderForAccessToken(oauthDetails.getAccessToken()));DefaultHttpClient client = new DefaultHttpClient();HttpResponse response = null;int code = -1;try {response = client.execute(get);code = response.getStatusLine().getStatusCode();if (code >= 400) {// Access token is invalid or expired.// Regenerate the access tokenSystem.out.println("Access token is invalidor expired.Regenerating access token....");String accessToken = getAccessToken(oauthDetails);if (isValid(accessToken)) {// update the access token// System.out.println("New access token:" + accessToken);oauthDetails.setAccessToken(accessToken);get.removeHeaders(OAuthConstants.AUTHORIZATION);get.addHeader(OAuthConstants.AUTHORIZATION,getAuthorizationHeaderForAccessToken(oauthDetails.getAccessToken()));get.releaseConnection();response = client.execute(get);code = response.getStatusLine().getStatusCode();if (code >= 400) {throw new RuntimeException("Could notaccess protected resource.Server returned http code:"+ code);}} else {throw new RuntimeException("Could notregenerate access token");}}handleResponse(response);
注意
  • 此方法使用從配置文件檢索到的值來填充OauthDetailsbean。
  • 顧名思義,這種方法將嘗試從資源服務器檢索受保護的資源,因此,您需要創建一個簡單的HttpGet方法。
  • 為了向資源服務器進行身份驗證,需要將訪問令牌作為 Authorization 標頭的一部分發送。示例:Authorization:Bearer accessTokenValue
  • 創建一個DefaultHttpClient對資源服務器發出一個get請求。
  • 如果從資源服務器收到的響應代碼是403401,則用于身份驗證的訪問令牌可能已過期或無效。
  • 下一步是重新創建訪問令牌(清單 5)。
  • 成功地重新生成訪問令牌之后,更新OauthDetailsbean 中的訪問令牌值。用新的訪問令牌值替換get方法中現有的 Authorization 標頭。
  • 現在發出對受保護資源的另一個訪問請求。
  • 如果訪問令牌有效,而且資源服務器的 URL 也是正確的,那么您應該可以在控制臺中看到響應內容。
重新生成過期的訪問令牌

清單 5 中的代碼將會處理已過期訪問令牌的重新生成。

清單 5. 重新生成過期的訪問令牌
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778HttpPost post = new HttpPost(oauthDetails.getAuthenticationServerUrl());String clientId = oauthDetails.getClientId();String clientSecret = oauthDetails.getClientSecret();String scope = oauthDetails.getScope();List<BasicNameValuePair> parametersBody =new ArrayList<BasicNameValuePair>();parametersBody.add(new BasicNameValuePair(OAuthConstants.GRANT_TYPE,oauthDetails.getGrantType()));parametersBody.add(new BasicNameValuePair(OAuthConstants.USERNAME,oauthDetails.getUsername()));parametersBody.add(new BasicNameValuePair(OAuthConstants.PASSWORD,oauthDetails.getPassword()));if (isValid(clientId)) {parametersBody.add(new BasicNameValuePair(OAuthConstants.CLIENT_ID,clientId));}if (isValid(clientSecret)) {parametersBody.add(new BasicNameValuePair(OAuthConstants.CLIENT_SECRET, clientSecret));}if (isValid(scope)) {parametersBody.add(new BasicNameValuePair(OAuthConstants.SCOPE,scope));}DefaultHttpClient client = new DefaultHttpClient();HttpResponse response = null;String accessToken = null;try {post.setEntity(new UrlEncodedFormEntity(parametersBody,HTTP.UTF_8));response = client.execute(post);int code = response.getStatusLine().getStatusCode();if (code >= 400) {System.out.println("Authorizationserver expects Basic authentication");// Add Basic Authorization headerpost.addHeader(OAuthConstants.AUTHORIZATION,getBasicAuthorizationHeader(oauthDetails.getUsername(),oauthDetails.getPassword()));System.out.println("Retry with login credentials");post.releaseConnection();response = client.execute(post);code = response.getStatusLine().getStatusCode();if (code >= 400) {System.out.println("Retry with client credentials");post.removeHeaders(OAuthConstants.AUTHORIZATION);post.addHeader(OAuthConstants.AUTHORIZATION,getBasicAuthorizationHeader(oauthDetails.getClientId(),oauthDetails.getClientSecret()));post.releaseConnection();response = client.execute(post);code = response.getStatusLine().getStatusCode();if (code >= 400) {throw new RuntimeException("Could not retrieve access token for user:"oauthDetails.getUsername());}}}Map<String, String> map = handleResponse(response);accessToken = map.get(OAuthConstants.ACCESS_TOKEN);} catch (ClientProtocolException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return accessToken;
注意
  • 這種方法生成一個HttpPost請求,并獲得身份驗證服務器的 URL。
  • Post請求以 URL 編碼參數的形式發送usernamepassword,以及可選的scope,將它們作為有效載荷的一部分。
  • 有些授權服務器還會要求您發送client_idclient_secret作為此請求有效載荷的一部分。
  • 如果client_idclient_secretscope的值不為空,那么它們也將作為有效載荷的一部分被發送。
  • 按照 OAuth 2.0 授權框架,客戶端應該使用客戶端憑據,或使用在發出訪問令牌請求時由服務器所提供的其他任何憑據來設置 Authorization 標頭。但是,這受制于授權服務器實現。客戶端代碼發出初始請求時無需添加基本身份驗證標頭。如果服務器返回一個未經授權的響應,客戶端隨后試圖通過登錄和客戶端憑據進行身份驗證。
  • OAuth 2.0 規定,需要采用 JSON 格式來發送訪問令牌響應。但為了靈活性,我還添加了實用程序方法來處理來自服務器的 XML 編碼或 URL 編碼的響應。
測試客戶端

在本節中,我將討論如何建立一個 OAuth 2.0 兼容的端點并用它來測試客戶端。

在 Salesforce.com 注冊

Salesforce.com 對于資源所有者密碼憑據授權是一個很好的用例。如果用戶有登錄 Salesforce.com 的憑據,并希望自己的客戶端轉變為 OAuth 2.0 身份驗證,那么他需要做的就是在 Salesforce 注冊自己的應用程序,以獲得客戶端憑據。現在可以用這些客戶端憑據以及他現有的登錄憑據從授權服務器中獲得訪問令牌。

  1. 如果您以前沒有在 Salesforce.com 注冊過,請立即注冊。請參閱參考資料。
  2. 單擊Login,然后單擊Sign up for free
  3. 完成注冊,獲得您的憑據。
  4. 除了用戶名和密碼之外,您還將獲得一個安全令牌。您提供的用于發出訪問令牌請求的密碼必須是您的密碼和安全令牌的串聯。(示例:password12312123)。
  5. 有關如何在 salesforce.com 中創建應用程序,請參閱參考資料中有用的文章鏈接。
運行客戶端

現在,您已經完成了 Salesforce.com 中的注冊,您可以測試客戶端并從服務器檢索受保護的信息。

  • 將本文中討論的 Java 項目導入到 Eclipse 工作區(請參閱參考資料)。
  • 下載依賴關系 JAR 文件,并將其復制到項目的 lib 文件夾中(請參閱更多下載)。
  • 導航到 resources/com/ibm/oauth/Oauth2Client.config 文件,并填寫usernamepassword(追加安全令牌)、client_idclient_secretauthorization server URL的值。
  • 打開 Oauth2Client.java 并運行它。
訪問令牌輸出

您應該在控制臺窗口看到下面的輸出。

12345678910Retrieving Access TokenencodedBytes dmVybi5vamhhQGdtYWlsL.......********** Response Received **********instance_url = https://ap1.salesforce.comissued_at = 1380106995639signature = LtMjTrmoBbvVfZ6+qT5Un1UioHaV9KIOK7ayQTmJzCg=id = https://login.salesforce.com/id/00D90000000mQaYEAU/00590000001HCB7AAOaccess_token = 00D90000000mQaY!AQ8AQEn0rLDMvxrP9WgY3Blc.......Successfully retrieved Access token for Password Grant:00D90000000mQaY!AQ8AQEn0rLDMvxrP9WgY3Bl......
從 Salesforce.com 檢索用戶信息

現在,您已經有了訪問令牌和 ID,可以向 Salesforce.com 發出請求,通過使用 OAuth 2.0 進行身份驗證來訪問您的帳戶信息。

  • 用訪問令牌更新 Oauth2Client.confg 文件,并使用作為響應的一部分返回的id值來填充資源服務器 URL 屬性。
  • 再次運行 Oauth2Client.java。
輸出

您應該在控制臺窗口看到類似于下面的輸出。

清單 6. 輸出
12345678910111213141516171819202122232425262728293031323334Resource endpoint URL: https://login.salesforce.com/id/00D90000000mQaYEAU/00590000001HCB7AAOAttempting to retrieve protected resource********** Response Received **********photos = {"thumbnail":"https:////c.ap1.content.force.com//profilephoto//005//T","picture":"https:////c.ap1.content.force.com//profilephoto//005//F"}urls ={"enterprise":"https:////ap1.salesforce.com//services//Soap//c//{version}//00D90000000mQaY","sobjects":"https:////ap1.salesforce.com//services//data//v{version}//sobjects//","partner":"https:////ap1.salesforce.com//services//Soap//u//{version}//00D90000000mQaY","search":"https:////ap1.salesforce.com//services//data//v{version}//search//","query":"https:////ap1.salesforce.com//services//data//v{version}//query//","users":"https:////ap1.salesforce.com//services//data//v{version}//chatter//users","profile":"https:////ap1.salesforce.com//00590000001HCB7AAO","metadata":"https:////ap1.salesforce.com//services//Soap//m//{version}//00D90000000mQaY","rest":"https:////ap1.salesforce.com//services//data//v{version}//","groups":"https:////ap1.salesforce.com//services//data//v{version}//chatter//groups","feeds":"https:////ap1.salesforce.com//services//data//v{version}//chatter//feeds","recent":"https:////ap1.salesforce.com//services//data//v{version}//recent//","feed_items":"https:////ap1.salesforce.com//services//data//v{version}//chatter//feed-items"}asserted_user = trueactive = trueorganization_id = 00D90000000mQaYEAUnick_name = vern.ojha1....display_name = varun ojhauser_type = STANDARDuser_id = ***********status = {"body":null,"created_date":null}last_name = ojhausername = vern.ojha.....utcOffset = -28800000language = en_USlocale = en_USfirst_name = varunlast_modified_date = 2013-06-04T07:43:42.000+0000id = https://login.salesforce.com/id/00D90000000mQaYEAU/00590000001HCB7AAOemail = vern.ojha@Gmail.com

如您所見,您可以通過使用 OAuth 2.0 進行身份驗證,成功獲取用戶信息。在配置文件中提供的訪問令牌過期后,客戶端將會自動重新生成訪問令牌,并使用它來檢索在資源服務器 URL 中提供的受保護資源。

用 IBM 端點測試客戶端

客戶端也已經成功通過 OAuth 2.0 兼容的 IBM 端點的測試,即 IBM WebSphere Application Server 和 IBM DataPower。請參閱參考資料的鏈接,“使用 OAuth:在 WebSphere Application Server 中啟用 OAuth 服務提供程序”,這是一個非常好的資源,介紹了如何在 WebSphere Application Server 上設置 OAuth

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 青州市| 林州市| 山丹县| 曲沃县| 邹城市| 德庆县| 罗源县| 富源县| 富锦市| 七台河市| 从江县| 阿勒泰市| 巧家县| 临洮县| 冀州市| 固阳县| 新宾| 红安县| 左权县| 柘荣县| 禹城市| 固镇县| 淮安市| 鄂托克前旗| 曲沃县| 会泽县| 高陵县| 辉南县| 郧西县| 云阳县| 禄劝| 天峨县| 宣威市| 聂拉木县| 林芝县| 南平市| 常熟市| 长白| 阿克苏市| 京山县| 忻城县|