CODE大全
版权声明:本文为博主原创文章,未经博主允许不得转载。

使用 HttpClient 进行 OAuth 认证

发布时间:『 2016-11-18 15:03』  博客类别:编程语言  阅读(3237) 评论(0)

接上一章的《HttpClient 认证机制 和 OAuth 认证》,本章我们将深入实例,进行实战讲解。

Http协议的重要性相信不用我多说了,HttpClient 相比传统 JDK 自带的 URLConnection,增加了易用性和灵活性(具体区别,日后我们再讨论),它不仅是客户端发送 Http 请求变得容易,而且也方便了开发人员测试接口(基于 Http 协议的),即提高了开发的效率,也方便提高代码的健壮性。因此熟练掌握 HttpClient 是很重要的必修内容,而企业级应用中使用 HttpClient 进行 get、post 请求的需求举不胜举,而OAuth 第三方认证又是最常见的应用场景,本篇文章将具体通过 HttpClient 来实现 OAuth 第三方认证的案例。

使用 oauth.net 的 Java 库来扩展 HttpClient

Oauth.net 提供一个开源 Java™ 库。如上所述,要使用自定义的认证,您需要提供您自己的 AuthScheme 和证书类。OAuth 库已经实现了它自己的 OAuthSchemeOAuthSchemeFactoryOAuthCredentials。您可以利用它们来添加 OAuth 支持到您的 HttpClient 应用程序。

要启用 HttpClient 的一个 OAuth 认证模式:

  1. 在 HttpClient 中注册这个新的 OAuth 认证机制。

  2. 提供一个新 OAuthCredentials

  3. HttpClient 使用一个有序偏好来选择正确的认证机制。您可以使用本地 HttpContext 对象来在请求执行之前定制 HTTP 认证内容,或者您可以在请求执行之后检查其状态。通过设置 HttpContext 对象的 http.auth.scheme-pref 属性修改认证默认首选项。

下面显示了一个示例。注意代码中获取您自己的 OAuthAccessor 的方法被省略了,因为它由您的具体实现而定。

启用 HttpClient 的一个 OAuth 认证模式

AbstractHttpClient httpClient = new DefaultHttpClient();
//register the OAuthScheme
httpClient.getAuthSchemes().register(OAuthSchemeFactory.SCHEME_NAME, 
new OAuthSchemeFactory()); 
//get the OAuthAccessor object
OAuthAccessor accessor = yourMethodToGetOAuthAccessor();
//set credentials 
httpClient.getCredentialsProvider().setCredentials(
new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM,
OAuthSchemeFactory.SCHEME_NAME),
new OAuthCredentials(accessor));
//Adjust the authentication scheme selection
HttpContext localContext = new BasicHttpContext();
localContext.setAttribute("http.auth.scheme-pref", Arrays.asList(new String[] {
"oauth", "digest", "basic"
}));


使用 OAuth 从 LinkedIn 获取配置文件

很多 web 网站支持 OAuth,比如 LinkedIn。以下示例展示如何使用有 OAuth 支持的 HttpClient 从 LinkedIn 获取一个用户的配置文件。

①您需要一个 LinkedIn 账户,需要创建一个应用程序。然后您可以获取 API Key,这在 OAuth 术语中称为 Consumer Key。图 2 显示了一个例子。

②有了 Consumer Key 和 Secret Key 之后,向 LinkedIn 发出一个请求来获取 AccessToken 和 Secret,使用以下内容:
  LinkedIn Oauth 端点 URL
  根路径:https://api.linkedin.com
  请求令牌路径:/uas/oauth/requestToken
  访问令牌路径:/uas/oauth/accessToken
  授权路径:/uas/oauth/authorize

从 LinkedIn 获取 AccessToken 和 Secret

String baseURL = "https://api.linkedin.com";
String requestTokenURL = baseURL + "/requestToken";
String authorizationURL = baseURL + "/authorize";
String accessTokenURL = baseURL + "/accessToken";

String consumerKey="hP80ApmoJkO-9ZHuXC97olUzD1egVI75zKoff9SCKFFTY9zjc
   vWRRRbiNrWbcKIX";
String consumerSecret="toAk3oV1wKuon9W51lfELLHtZSxBZHih-qMyeDIBrIB2Y1hCASbpmK313
   Wubmrd2";
OAuthServiceProvider provider = new OAuthServiceProvider(
				requestTokenURL, authorizationURL, accessTokenURL);
OAuthConsumer consumer = new OAuthConsumer(
		"DemoOAuth", consumerKey, consumerSecret, provider);
OAuthAccessor accessor = new OAuthAccessor(consumer);
OAuthClient client = new OAuthClient(new HttpClient4());
List<Parameter> parameters = new ArrayList<OAuth.Parameter>();
parameters.add(new Parameter("oauth_callback", "yourAppcallbackurl"));
OAuthMessage msg = client.getRequestTokenResponse(accessor,
					"POST", parameters);
String requestToken = msg.getParameter(OAuth.OAUTH_TOKEN);
String requestSecret = msg.getParameter(OAuth.OAUTH_TOKEN_SECRET);

现在您有了 URL:

authorizationURL + "?" + OAuth.OAUTH_TOKEN+ "=" + requestToken

 

如果在一个 web 应用程序中,用户应该访问 LinkedIn 或被重定向到 LinkedIn 以得到批准。

请求 AccessToken 和 Secret

OAuthMessage msg = OAuthServlet.getMessage(request, null);
String requestToken = msg.getParameter(OAuth.OAUTH_TOKEN);
String verifier = msg.getParameter(OAuth.OAUTH_VERIFIER);
…
get the accessor object in List 1…
….
OAuthClient oauthClient = new OAuthClient(new HttpClient4());
List<Parameter> list = new ArrayList<Parameter>();
list.add(new Parameter(OAuth.OAUTH_VERIFIER, verifier));
OAuthMessage returned = oauthClient.getAccessToken(accessor,
       "POST", list);
String accessToken = returned.getParameter(OAuth.OAUTH_TOKEN));
String accessKey = returned.getParameter(OAuth.OAUTH_TOKEN_SECRET));
  • LinkedIn Oauth 端点 URL

  • 根路径:https://api.linkedin.com

  • 请求令牌路径:/uas/oauth/requestToken

  • 访问令牌路径:/uas/oauth/accessToken

  • 授权路径:/uas/oauth/authorize

③添加 OAuth 支持到 HttpClient。
  使用上述代码,注册 OAuthScheme。使用 accessor 对像设置证书。

④使用 OAuth 认证发送请求到 LinkedIn。

使用 OAuth 认证发送请求到 LinkedIn

HttpGet httpget = new HttpGet("https://api.linkedin.com/v1/people/~");
//Run the http get method under the modified context
httpClient.execute(httpget, localContext);

现在您可以使用 OAuth 认证通过 HttpClient 获取用户配置文件,如清单 5 所示。

LinkedIn 返回用户信息

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<person>
  <first-name>Zheng</first-name>
  <last-name>BI</last-name>
  <headline>SE at IBM</headline>
  <site-standard-profile-request>
<url>http://www.linkedin.com/profile?viewProfile=&amp;key=84546207
&amp;authToken=SMl9&amp;authType=name&amp;
trk=api*a113393*s121886*</url>
  </site-standard-profile-request>
</person>

先占式模式支持

HttpClient 不支持开箱即用的先占式认证,但是您可以使用一个协议拦截器事先引入一个 AuthScheme 实例到执行上下文。这个拦截器必须在标准认证拦截器之前 添加到协议处理链。

仅支持 OAuth 1.0 的 web 网站不提供 “挑战” 响应。要使用 OAuth 认证,您需要使用先占式认证。OAuth 库也使用 HttpClient 4.0.1 的 HttpRequestInterceptor 使其得以实现。清单 6 中显示的样例代码可以启用先占式认证。

启用先占式认证

HttpRequestInterceptor preemptiveAuth = new PreemptiveAuthorizer();
httpClient.addRequestInterceptor(preemptiveAuth, 0);

HttpClient 3.0.x OAuth 支持(低版本支持OAuth的方法)

HttpClient 原生支持基础认证、摘要认证和 NTLM 认证。在 HttpClient 3.0.x 中添加一个自定义的 AuthScheme 与在 HttpClient 4.x 中添加有所不同。

  1. OAuth Java Lib 不提供 HttpClient 3.0.x 支持,因此您需要创建您自己的 Scheme 类,来实现 AuthScheme 接口。关于编写该函数的解释不在本文讨论范围中。

  2. 使用 AuthPolicy.registerAuthScheme() 注册 OAuthScheme(见 http://hc.apache.org/httpclient-3.x/apidocs/org/apache/commons/httpclient/auth/AuthPolicy.html#registerAuthScheme%28java.lang.String,%20java.lang.Class%29)

  3. 更改 AuthPolicy.AUTH_SCHEME_PRIORITY 首选项来启用自定义的 AuthScheme

启用自定义的 AuthScheme

HttpClient client = new HttpClient();
List authPrefs = new ArrayList(2);
authPrefs.add(AuthPolicy.OAUTH);
authPrefs.add(AuthPolicy.DIGEST);
authPrefs.add(AuthPolicy.BASIC);
client.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);

HttpClient v3.0.x 的局限性

HttpClient 3.0.x 也支持先占式认证。

HttpClient 3.0.x 支持先占式认证

client.getParams().setAuthenticationPreemptive(true);


然而,在该模式下,您只能使用基础认证。对于一个需要 OAuth 先占式认证的网站,您不能使用 HttpClient 3.0.x。

总结

HttpClient 认证模式提供一种机制来进行自身扩展,对于在开发期间使用 HttpClient 的应用程序来说,利用一个第三方 OAuth 库来添加 OAuth 认证是比较容易的。然而对于 HttpClient 3.0.x 有一些限制。


——— 全文完 ———
如有版权问题,请联系532009913@qq.com。
关键字:   HttpClient     OAuth     第三方认证     CredentialProvider     OAuthCredentials  
评论信息
暂无评论
发表评论
验证码: 
Powered by CODE大全 | 鄂ICP备14009759号-2 | 网站留言 Copyright © 2014-2016 CODE大全 版权所有