/* * © Copyright IBM Corp. 2012 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package com.ibm.sbt.services.endpoints; import java.io.IOException; import java.util.Map; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpRequestInterceptor; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.protocol.HttpContext; import com.ibm.commons.runtime.Context; import com.ibm.commons.runtime.RuntimeConstants; import com.ibm.commons.runtime.util.UrlUtil; import com.ibm.commons.util.PathUtil; import com.ibm.commons.util.StringUtil; import com.ibm.sbt.security.authentication.AuthenticationException; import com.ibm.sbt.security.authentication.oauth.OAuthException; import com.ibm.sbt.security.authentication.oauth.consumer.AccessToken; import com.ibm.sbt.security.authentication.oauth.consumer.HMACOAuth1Handler; import com.ibm.sbt.security.authentication.oauth.consumer.OAuth1Handler; import com.ibm.sbt.security.authentication.oauth.consumer.OAuthHandler; import com.ibm.sbt.security.authentication.oauth.consumer.servlet.OAClientAuthentication; import com.ibm.sbt.services.client.ClientServicesException; import com.ibm.sbt.services.endpoints.js.JSReference; import com.ibm.sbt.util.SBTException; import org.apache.http.Header; /** * Bean that provides authentication via OAuth. * <p> * </p> * * @author Philippe Riand * @author Vimal Dhupar */ public class OAuthEndpoint extends AbstractEndpoint { protected OAuth1Handler oAuthHandler; public OAuthEndpoint(){ this.oAuthHandler = new OAuth1Handler(); } protected OAuthEndpoint(OAuth1Handler handler) { this.oAuthHandler = handler; } /** * Force login of the specified user using the cached credentials if available. * If not cached credential are available or these are invalid the login will fail. * * @param user * @return true if the specified user was logged in using their cached credentials * @throws ClientServicesException */ public boolean login(String user) throws ClientServicesException { this.oAuthHandler.setUserId(user); if (isAuthenticated()) { return isAuthenticationValid(); } return false; } @Override public void checkValid() throws SBTException { super.checkValid(); if (StringUtil.isEmpty(oAuthHandler.getConsumerKey())) { throw new SBTException(null, "The Endpoint consumer key is empty for {0}", getClass()); } if (StringUtil.isEmpty(oAuthHandler.getConsumerSecret())) { throw new SBTException(null, "The Endpoint consumer secret is empty for {0}", getClass()); } if (StringUtil.isEmpty(oAuthHandler.getAuthorizationURL())) { throw new SBTException(null, "The Endpoint authorization URL is empty for {0}", getClass()); } if (StringUtil.isEmpty(oAuthHandler.getRequestTokenURL())) { throw new SBTException(null, "The Endpoint request token URL is empty for {0}", getClass()); } if (StringUtil.isEmpty(oAuthHandler.getAccessTokenURL())) { throw new SBTException(null, "The Endpoint access token URL is empty for {0}", getClass()); } } @Override public void setUrl(String url) { super.setUrl(url); // Make the URL the service name if not already set if (StringUtil.isEmpty(oAuthHandler.getServiceName())) { oAuthHandler.setServiceName(url); } } public String getConsumerKey() { return oAuthHandler.getConsumerKey(); } public void setConsumerKey(String consumerKey) { oAuthHandler.setConsumerKey(consumerKey); } public String getConsumerSecret() { return oAuthHandler.getConsumerSecret(); } public void setConsumerSecret(String consumerSecret) { oAuthHandler.setConsumerSecret(consumerSecret); } @Override public String getCredentialStore() { return oAuthHandler.getCredentialStore(); } @Override public void setCredentialStore(String credentialStore) { oAuthHandler.setCredentialStore(credentialStore); } public String getAppId() { return oAuthHandler.getAppId(); } public void setAppId(String appId) { oAuthHandler.setAppId(appId); } public String getServiceName() { return oAuthHandler.getServiceName(); } public void setServiceName(String serviceName) { oAuthHandler.setServiceName(serviceName); } public String getRequestTokenURL() { return oAuthHandler.getRequestTokenURL(); } public void setRequestTokenURL(String requestTokenURL) { oAuthHandler.setRequestTokenURL(requestTokenURL); } public String getAuthorizationURL() { return oAuthHandler.getAuthorizationURL(); } public void setAuthorizationURL(String authorizationURL) { oAuthHandler.setAuthorizationURL(authorizationURL); } public String getAccessTokenURL() { return oAuthHandler.getAccessTokenURL(); } public void setAccessTokenURL(String accessTokenURL) { oAuthHandler.setAccessTokenURL(accessTokenURL); } public String getSignatureMethod() { return oAuthHandler.getSignatureMethod(); } public void setSignatureMethod(String signatureMethod) { oAuthHandler.setSignatureMethod(signatureMethod); } protected void setOauthHandler(HMACOAuth1Handler hmacoAuth1Handler) { this.oAuthHandler = hmacoAuth1Handler; } @Override public String getAuthType() { return "oauth1.0a"; } @Override public boolean isForceTrustSSLCertificate() { return oAuthHandler.getForceTrustSSLCertificate(); } @Override public void setForceTrustSSLCertificate(boolean forceTrustSSLCertificate) { oAuthHandler.setForceTrustSSLCertificate(forceTrustSSLCertificate); } @Override public JSReference getAuthenticator(String endpointName, String sbtUrl) { Context ctx = Context.get(); JSReference reference = new JSReference("sbt/authenticator/OAuth"); StringBuilder b = new StringBuilder(); RuntimeConstants.get().appendBaseProxyUrl(b, ctx); b.append("/"); b.append(OAClientAuthentication.URL_PATH); b.append('/'); b.append(endpointName); String url = b.toString(); reference.getProperties().put("url", url); reference.getProperties().put("loginUi", ctx.getProperty("loginUi")); return reference; } @Override public boolean isAuthenticated() throws ClientServicesException { try { return oAuthHandler.acquireToken() != null; } catch (OAuthException ex) { throw new ClientServicesException(ex); } } @Override public void authenticate(boolean force) throws ClientServicesException { try { oAuthHandler.acquireToken(true, force); } catch (OAuthException ex) { throw new ClientServicesException(ex); } } @Override public void logout() throws OAuthException { oAuthHandler.deleteToken(); } @Override public void initialize(DefaultHttpClient httpClient) throws ClientServicesException { try { AccessToken token = oAuthHandler.acquireToken(false); if ((token != null) && (oAuthHandler != null)) { HttpRequestInterceptor oauthInterceptor = new OAuthInterceptor(token, super.getUrl(),oAuthHandler); httpClient.addRequestInterceptor(oauthInterceptor, 0); } } catch (OAuthException ex) { throw new ClientServicesException(ex); } } private static class OAuthInterceptor implements HttpRequestInterceptor { private final AccessToken token; private final String baseUrl; private final OAuthHandler oaHandler; public OAuthInterceptor(AccessToken token, String baseUrl, OAuthHandler oaHandler) { this.token = token; this.baseUrl = baseUrl; this.oaHandler = oaHandler; } @Override public void process(HttpRequest request, HttpContext context) throws HttpException, IOException { String authorizationheader = null; if (oaHandler != null) { if (oaHandler.getClass().equals(HMACOAuth1Handler.class)) { String requestUri = request.getRequestLine().getUri().toString(); // Using UrlUtil's getParamsMap for creating the ParamsMap // from the query String Request Uri. Map<String, String> mapOfParams = UrlUtil.getParamsMap(requestUri); try { if(StringUtil.isNotEmpty(requestUri)&& requestUri.indexOf("?")!=-1) requestUri = requestUri.substring(0, requestUri.indexOf("?")); requestUri = PathUtil.concat(baseUrl, requestUri, '/'); // creating authorization header authorizationheader = ((HMACOAuth1Handler) oaHandler).createAuthorizationHeader(requestUri, mapOfParams); } catch (OAuthException e) { throw new HttpException( "OAuthException thrown while creating Authorization header in OAuthInterceptor", e); } } else { authorizationheader = oaHandler.createAuthorizationHeader(); } } else { throw new HttpException("Error retrieving OAuth Handler. OAuth Handler is null"); } // Remove any existing authorization headers which can cause oauth requests to fail if(request.containsHeader("authorization")){ Header[] header = request.getHeaders("authorization"); for (int i = 0; i < header.length; i++) { request.removeHeader(header[i]); } } request.addHeader("Authorization", authorizationheader); } } }