package com.cattong.commons.http.auth; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Scanner; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.StatusLine; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.ResponseHandler; import org.apache.http.util.EntityUtils; import com.cattong.commons.LibException; import com.cattong.commons.LibResultCode; import com.cattong.commons.LibRuntimeException; import com.cattong.commons.Logger; import com.cattong.commons.ServiceProvider; import com.cattong.commons.http.HttpMethod; import com.cattong.commons.http.HttpRequestHelper; import com.cattong.commons.http.HttpRequestWrapper; import com.cattong.commons.oauth.OAuth; import com.cattong.commons.oauth.config.OAuthConfig; public class OAuthAuthorizeHelper { public OAuthAuthorizeHelper() throws LibException { } /** * 获取RequestToken * * @return 获取RequestToken * @throws LibException * @see <a href="http://oauth.net/core/1.0a/#auth_step1">OAuth Core 1.0a - 6.1. * Obtaining an Unauthorized Request Token</a> */ public Authorization retrieveRequestToken(Authorization auth) throws LibException { if (auth == null) { throw new LibException(LibResultCode.E_PARAM_NULL); } OAuthConfig oAuthConfig = auth.getoAuthConfig(); HttpRequestWrapper request = new HttpRequestWrapper( HttpMethod.GET, oAuthConfig.getRequestTokenUrl(), auth); request.addParameter(OAuth.OAUTH_CALLBACK, oAuthConfig.getCallbackUrl()); Map<String, String> responseMap = HttpRequestHelper.execute( request, new FormEncodedResponseHandler(auth)); String token = responseMap.get(OAuth.OAUTH_TOKEN); String tokenSecret = responseMap.get(OAuth.OAUTH_TOKEN_SECRET); //boolean isCallbackConfirmed = Boolean.valueOf(responseMap.get(OAuth.OAUTH_CALLBACK_CONFIRMED)); auth.setAccessToken(token); auth.setAccessSecret(tokenSecret); return auth; } public String getAuthorizeUrl(Authorization auth) throws LibException { if (auth == null) { throw new LibException(LibResultCode.E_PARAM_NULL); } OAuthConfig oauthConfig = auth.getoAuthConfig(); StringBuilder authorizeUrl = new StringBuilder(oauthConfig.getAuthorizeUrl()); if (authorizeUrl.indexOf("?") < 0) { authorizeUrl.append("?"); } else { authorizeUrl.append("&"); } authorizeUrl.append(OAuth.OAUTH_TOKEN) .append("=") .append(auth.getAccessToken()); boolean isCallbackConfirmed = Boolean.valueOf("false"); if (!isCallbackConfirmed) { // 使用的是 OAuth 1.0 规定的callback传递方式,需要通过授权url参数传递 authorizeUrl.append("&"); authorizeUrl.append(OAuth.OAUTH_CALLBACK) .append("=") .append(oauthConfig.getCallbackUrl()); } return authorizeUrl.toString(); } /** * 通过OAuthRquestToken和Verifier获取OAuthAccessToken * * @param requestToken * OAuth rquest token * @param oauthVerifier * OAuth verifier. AKA pin. * @return 与提供的OAuthRquestToken相关的OAuthAccessToken * @throws LibException * @see <a href="http://oauth.net/core/1.0a/#auth_step2">OAuth Core 1.0a - 6.2. * Obtaining User Authorization</a> */ public Authorization retrieveAccessToken(Authorization auth, String oauthVerifier) throws LibException { if (auth == null ) {//|| StringUtil.isEmpty(oauthVerifier)网易不需要 throw new LibRuntimeException(LibResultCode.E_PARAM_NULL); } OAuthConfig oAuthConfig = auth.getoAuthConfig(); String userAuthorizationUrl = oAuthConfig.getAuthorizeUrl(); StringBuilder authorizationUrl = new StringBuilder(userAuthorizationUrl); if (authorizationUrl.indexOf("?") < 0) { authorizationUrl.append("?"); } else { authorizationUrl.append("&"); } authorizationUrl.append(OAuth.OAUTH_TOKEN).append("=").append(auth.getAccessToken()); //if (!isCallbackConfirmed) { // 使用的是 OAuth 1.0 规定的callback传递方式,需要通过授权url参数传递 authorizationUrl.append("&"); authorizationUrl.append(OAuth.OAUTH_CALLBACK) .append("=") .append(oAuthConfig.getCallbackUrl()); //} HttpRequestWrapper request = new HttpRequestWrapper(HttpMethod.GET, oAuthConfig.getAccessTokenUrl(), auth); request.addParameter(OAuth.OAUTH_VERIFIER, oauthVerifier); Map<String, String> responseMap = HttpRequestHelper.execute( request, new FormEncodedResponseHandler(auth)); String accessToken = responseMap.get(OAuth.OAUTH_TOKEN); String accessSecret = responseMap.get(OAuth.OAUTH_TOKEN_SECRET); String userId = responseMap.get("user_id"); String username = responseMap.get("screen_name"); auth.setAccessToken(accessToken); auth.setAccessSecret(accessSecret); //accessToken.setUserId(userId); //accessToken.setUsername(username); return auth; } /** * 使用用户名和密码通过XAuth认证方式获取OAuthAccessToken.<br> * * @param username * 用户名 * @param password * 密码 * @return 获取到的OAuthAccessToken * @throws LibException */ public Authorization retrieveAccessToken(Authorization auth) throws LibException { if (auth == null) { throw new LibRuntimeException(LibResultCode.E_PARAM_NULL); } String username = auth.getAccessToken(); String password = auth.getAccessSecret(); auth.setAccessToken(null); auth.setAccessSecret(null); OAuthConfig oAuthConfig = auth.getoAuthConfig(); HttpRequestWrapper request = new HttpRequestWrapper(HttpMethod.POST, oAuthConfig.getAccessTokenUrl(), auth); request.addParameter("x_auth_username", username); request.addParameter("x_auth_password", password); request.addParameter("x_auth_mode", "client_auth"); Map<String, String> xAuthResponse = HttpRequestHelper.execute( request, new FormEncodedResponseHandler(auth)); String accessToken = xAuthResponse.get(OAuth.OAUTH_TOKEN); String accessSecret = xAuthResponse.get(OAuth.OAUTH_TOKEN_SECRET); String userId = xAuthResponse.get("user_id"); auth.setAccessToken(accessToken); auth.setAccessSecret(accessSecret); //accessToken.setUserId(userId); //accessToken.setUsername(username); return auth; } private class FormEncodedResponseHandler implements ResponseHandler<Map<String, String>> { private Authorization auth; private ServiceProvider sp; public FormEncodedResponseHandler(Authorization auth) { this.auth = auth; this.sp = auth.getServiceProvider(); } @Override public Map<String, String> handleResponse(HttpResponse response) throws ClientProtocolException, IOException { StatusLine statusLine = response.getStatusLine(); if (statusLine.getStatusCode() >= 300) { int statusCode = statusLine.getStatusCode(); if (statusCode == HttpStatus.SC_FORBIDDEN && (sp == ServiceProvider.Sina || sp == ServiceProvider.NetEase)) { //在使用XAuth认证方式下,若用户名或密码错误,新浪、网易的响应是403,搜狐的是401,统一为401 statusCode = HttpStatus.SC_UNAUTHORIZED; } if (sp == ServiceProvider.Tencent && HttpStatus.SC_BAD_REQUEST == statusCode && "Bad Request: Unsupported parameter".equals(statusLine.getReasonPhrase())){ statusCode = LibResultCode.OAUTH_TIMESTAMP_REFUSED; } throw new LibRuntimeException(statusCode); } Map<String, String> resultMap = new HashMap<String, String>(); HttpEntity entity = response.getEntity(); final String responseString = EntityUtils.toString(entity); Logger.debug("FormEncodedResponseHandler : {}", responseString); Scanner scanner = new Scanner(responseString); scanner.useDelimiter("&"); while (scanner.hasNext()) { final String[] nameValue = scanner.next().split("="); if (nameValue.length == 0 || nameValue.length > 2){ throw new LibRuntimeException(LibResultCode.E_PARAM_ERROR, "", "Bad Parameter", ServiceProvider.None); } final String name = nameValue[0]; String value = null; if (nameValue.length == 2){ value = nameValue[1]; } resultMap.put(name, value); } return resultMap; } } }