Package com.ibm.sbt.security.authentication.oauth.consumer

Source Code of com.ibm.sbt.security.authentication.oauth.consumer.OAuth2Handler

/****************************************************************************************
* Copyright 2012 IBM Corp.                                                                   *
*                                                                                      *
* 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.security.authentication.oauth.consumer;

//import java.awt.Desktop;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.http.HttpServletRequest;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;

import com.ibm.commons.Platform;
import com.ibm.commons.runtime.Context;
import com.ibm.commons.runtime.util.UrlUtil;
import com.ibm.commons.util.PathUtil;
import com.ibm.commons.util.StringUtil;
import com.ibm.commons.util.io.StreamUtil;
import com.ibm.commons.util.profiler.Profiler;
import com.ibm.commons.util.profiler.ProfilerAggregator;
import com.ibm.commons.util.profiler.ProfilerType;
import com.ibm.sbt.core.configuration.Configuration;
import com.ibm.sbt.security.authentication.oauth.OAuthException;
import com.ibm.sbt.security.credential.store.CredentialStore;
import com.ibm.sbt.security.credential.store.CredentialStoreException;
import com.ibm.sbt.security.credential.store.CredentialStoreFactory;
import com.ibm.sbt.security.authentication.oauth.consumer.servlet.OA2Callback;
import com.ibm.sbt.service.util.ServiceUtil;
import com.ibm.sbt.services.util.AnonymousCredentialStore;
import com.ibm.sbt.services.util.SSLUtil;

/**
* @author Manish Kataria
*/

public class OAuth2Handler extends OAuthHandler {

  public static final int EXPIRE_THRESHOLD = 60// 60sec = 1min
 
  private String appId;
  private String client_uri;
  private String authorization_code;
  private String accessToken;
  private String refreshToken;
  private Date issuedOn;
  private String expiresIn;
  private String tokenType;
  private String servicename;
  private String authorizationURL;
  private String accessTokenURL;
  private String serviceName;
  private String consumerKey;
  private String consumerSecret;
  private String applicationPage;
  private int expireThreshold;
  private boolean forceTrustSSLCertificate;
  private AccessToken accessTokenObject;
 
  // Type used to store the credentials
  public static final String ACCESS_TOKEN_STORE_TYPE = "OAUTH2_ACCESS_TOKEN_STORE";
  public static final String CONSUMER_TOKEN_STORE_TYPE = "OAUTH2_CONSUMER_TOKEN_STORE";
 
  // Persistence store code
  private boolean storeRead;
  private String credentialStore;
    private static final ProfilerType profilerLoadCredentialStore = new ProfilerType("OAuth: Load a token from the store"); //$NON-NLS-1$
    private static final ProfilerType profilerAcquireToken = new ProfilerType("OAuth: Acquire a token from the service"); //$NON-NLS-1$
    private static final ProfilerType profilerRenewToken = new ProfilerType("OAuth: Renew a token from the provider"); //$NON-NLS-1$
    private static final ProfilerType profilerDeleteToken = new ProfilerType("OAuth: Delete a token from the store"); //$NON-NLS-1$
   
  //for logging
  private static final String sourceClass = OAuth1Handler.class.getName();
    private static final Logger logger = Logger.getLogger(sourceClass);

  public OAuth2Handler() {
      this.setExpireThreshold(EXPIRE_THRESHOLD);
  }
 
  @Override
  public boolean isInitialized() {
    return accessToken!=null;
  }
 
  /**
   * Generates the authorization url for fetching the authorization tokens
   *
   * https://apps.lotuslive.com/manage/oauth2/authorize?
   *                    response_type=code&
   *                    client_id=<client_id>&
   *                    callback_uri=<callback_uri>
   *
   * @return URL
   */
  public String getAuthorizationNetworkUrl() {
    StringBuilder url = new StringBuilder();
    try {
      url.append(getAuthorizationURL());
      url.append('?');
      url.append(Configuration.OAUTH2_RESPONSE_TYPE);
      url.append('=');
      url.append(Configuration.OAUTH2_CODE);
      url.append('&');
      url.append(Configuration.OAUTH2_CLIENT_ID);
      url.append('=');
      url.append(URLEncoder.encode(consumerKey, "UTF-8"));
      url.append('&');
      url.append(Configuration.OAUTH2_CALLBACK_URI);
      url.append('=');
      url.append(URLEncoder.encode(client_uri, "UTF-8"));
    } catch (UnsupportedEncodingException e) {
    }
    return url.toString()
  }
 
  /**
   ** Authorization: OAuth
   *                callback_uri="<callback_uri>",
   *                client_secret="<client_secret>",
   *                client_id="<client_id>",
   *                grant_type="authorization_code",
   *                code="<authorization_code>"
   *
   * Calls the server URL with Authorization header and gets back following values:
   *    access_token, refresh_token, issued_on expires_in, token_type.
   *
   * @throws Exception
   */
  public void getAccessTokenForAuthorizedUser() throws Exception {
    if (logger.isLoggable(Level.FINEST)) {
        logger.entering(sourceClass, "getAccessTokenForAuthorizedUser", new Object[] { });
        }
    HttpGet method = null;
    int responseCode = HttpStatus.SC_OK;
    String responseBody = null;
    InputStream content = null;
    try {
      HttpClient client = new DefaultHttpClient();
      if(forceTrustSSLCertificate)
        client = (DefaultHttpClient)SSLUtil.wrapHttpClient((DefaultHttpClient)client);
      StringBuffer url = new StringBuffer(2048);
      url.append(getAccessTokenURL()).append("?");
      url.append(Configuration.OAUTH2_CALLBACK_URI).append('=').append(URLEncoder.encode(client_uri, "UTF-8"));
      url.append('&');
      url.append(Configuration.OAUTH2_CLIENT_ID).append('=').append(URLEncoder.encode(consumerKey, "UTF-8"));
      url.append('&');
      url.append(Configuration.OAUTH2_CLIENT_SECRET).append('=').append(URLEncoder.encode(consumerSecret, "UTF-8"));
      url.append('&');
      url.append(Configuration.OAUTH2_GRANT_TYPE).append('=').append(Configuration.OAUTH2_AUTHORIZATION_CODE);
      url.append('&');
      url.append(Configuration.OAUTH2_CODE).append('=').append(URLEncoder.encode(authorization_code, "UTF-8"));
      method = new HttpGet(url.toString());
      HttpResponse httpResponse =client.execute(method);
      responseCode = httpResponse.getStatusLine().getStatusCode();
      if (logger.isLoggable(Level.FINEST)) {
          logger.log(Level.FINEST, "OAuth2.0 network call to fetch token :" + url, responseCode);
        }
      content = httpResponse.getEntity().getContent();
      BufferedReader reader = new BufferedReader(new InputStreamReader(content));
      try {
        responseBody = StreamUtil.readString(reader);
      } finally {
        StreamUtil.close(reader);
      }
    } catch (Exception e) {
      throw new OAuthException(e, "getAccessToken failed with Exception: <br>" + e);
    } finally {
      if(content != null) {
        content.close();
      }
    }
    if (responseCode != HttpStatus.SC_OK) {
      getAccessTokenForAuthorizedUsingPOST();
       return;
//      if (responseCode == HttpStatus.SC_UNAUTHORIZED) {
//        throw new Exception("getAccessToken failed with Response Code: Unauthorized (401),<br>Msg: " + responseBody);
//      } else if (responseCode == HttpStatus.SC_BAD_REQUEST) {
//        throw new Exception("getAccessToken failed with Response Code: Bad Request (400),<br>Msg: " + responseBody);
//      } else if (responseCode == HttpStatus.SC_INTERNAL_SERVER_ERROR) {
//        throw new Exception("getAccessToken failed with Response Code: Internal Server error (500),<br>Msg: " + responseBody);
//      } else {
//        throw new Exception("getAccessToken failed with Response Code: (" + responseCode + "),<br>Msg: " + responseBody);
//      }
    } else {
      setOAuthData(responseBody); //save the returned data
    }
 
    }
 
  /*
   *
   grant_type
         REQUIRED.  Value MUST be set to "authorization_code".
   code
         REQUIRED.  The authorization code received from the
         authorization server.
   redirect_uri
         REQUIRED, if the "redirect_uri" parameter was included in the
         authorization request as described in Section 4.1.1, and their
         values MUST be identical.
   client_id
         REQUIRED, if the client is not authenticating with the
         authorization server as described in Section 3.2.1.

   */
 
  public void getAccessTokenForAuthorizedUsingPOST() throws Exception {
   
    if (logger.isLoggable(Level.FINEST)) {
        logger.entering(sourceClass, "getAccessTokenForAuthorizedUsingPOST", new Object[] { });
        }
   
    HttpPost method = null;
    int responseCode = HttpStatus.SC_OK;
    String responseBody = null;
    InputStream content = null;
    try {
      HttpClient client = new DefaultHttpClient();
      if(forceTrustSSLCertificate)
        client = (DefaultHttpClient)SSLUtil.wrapHttpClient((DefaultHttpClient)client);
      StringBuffer url = new StringBuffer(2048);
     
      // This works for Smartcloud
/*      url.append(getAccessTokenURL()).append("?");
      url.append(Configuration.OAUTH2_CALLBACK_URI).append('=').append(URLEncoder.encode(client_uri, "UTF-8"));
      url.append('&');
      url.append(Configuration.OAUTH2_CLIENT_ID).append('=').append(URLEncoder.encode(consumerKey, "UTF-8"));
      url.append('&');
      url.append(Configuration.OAUTH2_CLIENT_SECRET).append('=').append(URLEncoder.encode(consumerSecret, "UTF-8"));
      url.append('&');
      url.append(Configuration.OAUTH2_GRANT_TYPE).append('=').append(Configuration.OAUTH2_AUTHORIZATION_CODE);
      url.append('&');
      url.append(Configuration.OAUTH2_CODE).append('=').append(URLEncoder.encode(authorization_code, "UTF-8"));
      System.err.println("url used here "+url);
      method = new HttpPost(url.toString());*/
     
     
      // This works for connections
      // add parameters to the post method 
      method = new HttpPost(getAccessTokenURL());
      List <NameValuePair> parameters = new ArrayList <NameValuePair>();  
      parameters.add(new BasicNameValuePair(Configuration.OAUTH2_CALLBACK_URI, URLEncoder.encode(client_uri, "UTF-8")));  
      parameters.add(new BasicNameValuePair(Configuration.OAUTH2_CLIENT_ID, URLEncoder.encode(consumerKey, "UTF-8")));  
      parameters.add(new BasicNameValuePair(Configuration.OAUTH2_CLIENT_SECRET, URLEncoder.encode(consumerSecret, "UTF-8")));  
      parameters.add(new BasicNameValuePair(Configuration.OAUTH2_GRANT_TYPE, Configuration.OAUTH2_AUTHORIZATION_CODE));  
      parameters.add(new BasicNameValuePair(Configuration.OAUTH2_CODE, URLEncoder.encode(authorization_code, "UTF-8")));  
      UrlEncodedFormEntity sendentity = new UrlEncodedFormEntity(parameters, HTTP.UTF_8)
      method.setEntity(sendentity);  
      HttpResponse httpResponse =client.execute(method);
      responseCode = httpResponse.getStatusLine().getStatusCode();
     
      if (logger.isLoggable(Level.FINEST)) {
          logger.log(Level.FINEST, "OAuth2.0 network call to fetch token :" + getAccessTokenURL(), responseCode);
        }
     
      content = httpResponse.getEntity().getContent();
      BufferedReader reader = new BufferedReader(new InputStreamReader(content));
      try {
        responseBody = StreamUtil.readString(reader);
      } finally {
        StreamUtil.close(reader);
      }
    } catch (Exception e) {
      throw new OAuthException(e,"getAccessToken failed with Exception: <br>");
    } finally {
      if(content!=null) {
        content.close();
      }
    }
    if (responseCode != HttpStatus.SC_OK) {
      String exceptionDetail = buildErrorMessage(responseCode, responseBody);
      if (exceptionDetail != null) {
        String msg = "Unable to retrieve access token because \"{0}\". Please check the access token URL is valid, current value: {1}.";
        msg = MessageFormat.format(msg, exceptionDetail, getAccessTokenURL());
        throw new OAuthException(null, msg);
      }
    } else {
      setOAuthData(responseBody); //save the returned data
    }
  }
 

  @Override
  public String createAuthorizationHeader() {
    if (logger.isLoggable(Level.FINEST)) {
        logger.entering(sourceClass, "createAuthorizationHeader", new Object[] { });
        }
   
    if (logger.isLoggable(Level.FINEST)) {
        logger.log(Level.FINEST, "Security Header :" + "Bearer "+ accessToken);
      }
    return "Bearer "+ accessToken;
  }

  protected void setOAuthData(String responseBody) {
    accessToken = getTokenValue(responseBody, Configuration.OAUTH2_ACCESS_TOKEN);
    refreshToken = getTokenValue(responseBody, Configuration.OAUTH2_REFRESH_TOKEN);
    String issuedOnDate = getTokenValue(responseBody, Configuration.OAUTH2_ISSUEDON);
    try{
      issuedOn = new Date(Long.valueOf(issuedOnDate));
    }catch (Exception e) {}
    expiresIn = getTokenValue(responseBody, Configuration.OAUTH2_EXPIRESIN);
    tokenType = getTokenValue(responseBody, Configuration.OAUTH2_TOKENTYPE);
  }

    public String getAppId() {
        return appId;
    }
    public void setAppId(String appId) {
        this.appId = appId;
    }


  public String getClient_uri() {
    return client_uri;
  }

  public void setClient_uri(String client_uri) {
    this.client_uri = client_uri;
  }

  public String getAuthorization_code() {
    return authorization_code;
  }

  public void setAuthorization_code(String authorization_code) {
    this.authorization_code = authorization_code;
  }

  @Override
  public String getAccessToken() {
    return accessToken;
  }

  public void setAccessToken(String accessToken) {
    this.accessToken = accessToken;
  }
 
  public AccessToken getAccessTokenObject() {
    return accessTokenObject;
  }

  public void setAccessTokenObject(AccessToken accessTokenObject) {
    this.accessTokenObject = accessTokenObject;
  }

  public String getRefreshToken() {
    return refreshToken;
  }

  public void setRefreshToken(String refreshToken) {
    this.refreshToken = refreshToken;
  }

  public Date getIssuedOn() {
    return issuedOn;
  }

  public void setIssuedOn(Date issuedOn) {
    this.issuedOn = issuedOn;
  }

  public String getExpiresIn() {
    return expiresIn;
  }

  public void setExpiresIn(String expireIn) {
    this.expiresIn = expireIn;
  }

  public String getTokenType() {
    return tokenType;
  }

  public void setTokenType(String tokenType) {
    this.tokenType = tokenType;
  }

  @Override
  public String getAuthType() {
    return Configuration.AUTH_TYPE_OAUTH2;
  }
 
  public String getServicename() {
    return servicename;
  }

  public void setServicename(String servicename) {
    this.servicename = servicename;
  }
 
  public void setAuthorizationURL(String authorizationURL) {
    this.authorizationURL = authorizationURL;
  }

  @Override
  public String getAuthorizationURL() {
    return authorizationURL;
  }
 
  public String getAccessTokenURL() {
    return accessTokenURL;
  }

  public void setAccessTokenURL(String accessTokenURL) {
    this.accessTokenURL = accessTokenURL;
  }
 

    private void readConsumerToken() throws OAuthException {
        if(!storeRead) {
          try {
            CredentialStore factory = CredentialStoreFactory.getCredentialStore(getCredentialStore());
              if(factory!=null) {
                ConsumerToken consumerToken = (ConsumerToken) factory.load(getServiceName(), CONSUMER_TOKEN_STORE_TYPE, null);
                  if(consumerToken!=null) {
                    storeRead = true;
                      if(StringUtil.isNotEmpty(consumerToken.getConsumerKey())) {
                          setConsumerKey(consumerToken.getConsumerKey());
                      }
                      if(StringUtil.isNotEmpty(consumerToken.getConsumerSecret())) {
                          setConsumerSecret(consumerToken.getConsumerSecret());
                      }
                      if(StringUtil.isNotEmpty(consumerToken.getAuthorizationUri())) {
                          setAuthorizationURL(consumerToken.getAuthorizationUri());
                      }
                      if(StringUtil.isNotEmpty(consumerToken.getAccessTokenUri())) {
                          setAccessTokenURL(consumerToken.getAccessTokenUri());
                      }                  
                  }
              }
          } catch (CredentialStoreException cse) {
          throw new OAuthException(cse, cse.getMessage());
      }
        }
    }

  public void setCredentialStore(String credentialStore) {
    this.credentialStore = credentialStore;
  }

  public String getCredentialStore() {
    return credentialStore;
  }

  public void setServiceName(String serviceName) {
    this.serviceName = serviceName;
  }

  public String getServiceName() {
    return serviceName;
  }

  public void setConsumerSecret(String consumerSecret) {
    this.consumerSecret = consumerSecret;
  }

  public String getConsumerSecret() {
    return consumerSecret;
  }
 
  public void setConsumerKey(String consumerKey) {
    this.consumerKey = consumerKey;
  }
 
  public String getConsumerKey() {
    return consumerKey;
  }
 
 
  //Persistance related code
 
   
    public AccessToken acquireToken() throws OAuthException {
        return acquireToken(false);
    }

    public AccessToken acquireToken(boolean login) throws OAuthException {
        return acquireToken(login, false);
    }
    public AccessToken acquireToken(boolean login, boolean force) throws OAuthException {
        if (Profiler.isEnabled()) {
            ProfilerAggregator agg = Profiler.startProfileBlock(profilerAcquireToken, "");
            long ts = Profiler.getCurrentTime();
            try {
                return _acquireToken(login, force);
            } finally {
                Profiler.endProfileBlock(agg, ts);
            }
        } else {
            return _acquireToken(login, force);
        }
    }
   
    /*
     * This method searches for existing token in store.
     * It can also conditionally trigger the OAuth2 Dance to procure new tokens
     * When parameter force is True, we reperform the Oauth Dance.
     * When login is True, we reperform the Oauth dance only when tokens are not available in store or bean
     */
   
    public AccessToken _acquireToken(boolean login, boolean force) throws OAuthException {
      Context context = Context.get();
      AccessToken tk;
     
        // If force is used, then login must be requested
        if(force) {
            login = true;
        }

        String userId = getUserId();

        // Look for a token in the store
      // If the user is anonymous, then the token might had been stored in the session
        if(!force) {
         
          if (getAccessTokenObject() != null) {
          // read from the local bean if accesstoken is present
          tk = getAccessTokenObject();
        }else{
              tk = context.isCurrentUserAnonymous()
          ? (AccessToken)AnonymousCredentialStore.loadCredentials(context,getAppId(),getServiceName())
          : findTokenFromStore(context, userId);
        }

          // check if token needs to be renewed
            if(tk!=null) {
                if(shouldRenewToken(tk)) { //based on expiration date, check if token needs to be renewed.
                    return renewToken(tk);
                }
                return tk;
            }
        }
      if(login) {
        deleteToken();
        setAccessTokenObject(null);
        performOAuth2Dance();
      }
        return null;
    }
   
    protected AccessToken findTokenFromStore(Context context, String userId) throws OAuthException {
        if (Profiler.isEnabled()) {
            ProfilerAggregator agg = Profiler.startProfileBlock(profilerLoadCredentialStore, "");
            long ts = Profiler.getCurrentTime();
            try {
                return _findTokenFromStore(context, userId);
            } finally {
                Profiler.endProfileBlock(agg, ts);
            }
        } else {
            return _findTokenFromStore(context, userId);
        }
    }
    protected AccessToken _findTokenFromStore(Context context, String userId) throws OAuthException {
      readConsumerToken();
     
        if(StringUtil.isEmpty(userId)) {
            userId = getUserId();
            // Anonymous is not valid
            if(StringUtil.isEmpty(userId)) {
                return null;
            }
        }
        try {
          CredentialStore credStore = CredentialStoreFactory.getCredentialStore(getCredentialStore());
          if(credStore!=null) {
              // Find the token for this user
              AccessToken token = (AccessToken) credStore.load(getServiceName(), ACCESS_TOKEN_STORE_TYPE, userId);
              if(token!=null) {
                  return token;
              }
          }
        } catch (CredentialStoreException cse) {
        throw new OAuthException(cse, "Error finding credentials from the store");
    }
        return null;
    }
   
   
    // ==========================================================
    //  Delete token
    // ==========================================================
   
    public void deleteToken() throws OAuthException {
        if (Profiler.isEnabled()) {
            ProfilerAggregator agg = Profiler.startProfileBlock(profilerDeleteToken, "");
            long ts = Profiler.getCurrentTime();
            try {
                _deleteToken(Context.get(), null);
            } finally {
                Profiler.endProfileBlock(agg, ts);
            }
        } else {
            _deleteToken(Context.get(), null);
        }
    }
    protected void _deleteToken(Context context, String userId) throws OAuthException {
      readConsumerToken();
     
        if(StringUtil.isEmpty(userId)) {
            userId = getUserId();
            if(StringUtil.isEmpty(userId)) {
                return;
            }
           
        }
        if(StringUtil.equals(userId, "anonymous"))
    {
          AnonymousCredentialStore.deleteCredentials(context, getAppId(),getServiceName());
    }
        else {
           try {
               CredentialStore credStore = CredentialStoreFactory.getCredentialStore(getCredentialStore());
               if(credStore!=null) {
                 // Find the token for this user
                 credStore.remove(getServiceName(), ACCESS_TOKEN_STORE_TYPE, getUserId());
               }
           } catch (CredentialStoreException cse) {
         throw new OAuthException(cse, "Error trying to delete Token.");
       }
        }
    }
   
    //  Renew the token
    // ==========================================================

    public AccessToken renewToken() throws OAuthException {
        return renewToken(null);
    }

    public AccessToken renewToken(AccessToken token) throws OAuthException {
        if (Profiler.isEnabled()) {
            ProfilerAggregator agg = Profiler.startProfileBlock(profilerRenewToken, "");
            long ts = Profiler.getCurrentTime();
            try {
                return _renewToken(token);
            } finally {
                Profiler.endProfileBlock(agg, ts);
            }
        } else {
            return _renewToken(token);
        }
    }
   
    /*
     * This method uses the existing refresh token and renews the access token from access token url
     */
    protected AccessToken _renewToken(AccessToken token) throws OAuthException {
        HttpGet method = null;
        AccessToken renewedtoken = null;
        int responseCode = HttpStatus.SC_OK;
        String responseBody = null;
        InputStream content = null;
        try {
          HttpClient client = new DefaultHttpClient();
          if(forceTrustSSLCertificate)
            client = (DefaultHttpClient)SSLUtil.wrapHttpClient((DefaultHttpClient)client);
          StringBuilder url = new StringBuilder();
          url.append(getAccessTokenURL()).append('?');
          url.append(Configuration.OAUTH2_CLIENT_ID);
          url.append('=');
          url.append(URLEncoder.encode(token.getConsumerKey(), "UTF-8"));
          url.append('&');
          url.append(Configuration.OAUTH2_CLIENT_SECRET);
          url.append('=');
          url.append(URLEncoder.encode(token.getTokenSecret(), "UTF-8"));
          url.append('&');
          url.append(Configuration.OAUTH2_GRANT_TYPE);
          url.append('=');
          url.append(Configuration.OAUTH2_REFRESH_TOKEN);
          url.append('&');
          url.append(Configuration.OAUTH2_REFRESH_TOKEN);
          url.append('=');
          url.append(URLEncoder.encode(token.getRefreshToken(), "UTF-8"));
          method = new HttpGet(url.toString());
          HttpResponse httpResponse =client.execute(method);
          responseCode = httpResponse.getStatusLine().getStatusCode();
          content = httpResponse.getEntity().getContent();
          BufferedReader reader = new BufferedReader(new InputStreamReader(content));
          try {
            responseBody = StreamUtil.readString(reader);
          } finally {
            StreamUtil.close(reader);
          }
        } catch (Exception e) {
          throw new OAuthException(e ,"refreshAccessToken failed with Exception: <br>" + e);
        } finally {
          if (method != null){
          try {
            if(content!=null) {
              content.close();
            }
          } catch (IOException e) {
            throw new OAuthException(e ,"refreshAccessToken failed with Exception: <br>" + e);
          }
          }
        }
        if (responseCode != HttpStatus.SC_OK) {
            acquireToken(true, true); // Failed to renew token, get a new one
                  return null;
        } else {
          setOAuthData(responseBody);
          renewedtoken = createToken(getAppId(),getServiceName()); // Now create a new token and save that in the store       
          Context context = Context.get();
          setAccessTokenObject(renewedtoken);
          try {
                if(!context.isCurrentUserAnonymous()) {
                  CredentialStore credStore = findCredentialStore();
                  if (credStore != null) {
                // if the token is already present, and was expired due to which we have fetched a new
                // token, then we remove the token from the store first and then add this new token.
                deleteToken();
                credStore.store(getServiceName(), ACCESS_TOKEN_STORE_TYPE, getUserId(), token);
              }
                  } else {
                    AnonymousCredentialStore.storeCredentials(context, token, getAppId(), getServiceName()); // Store the token for anonymous user
                  }
          } catch (CredentialStoreException cse) {
            throw new OAuthException(cse, "Error trying to renew Token.");
          }
        }
        return renewedtoken;
    }
   
    public CredentialStore findCredentialStore() throws OAuthException {
      CredentialStore credStore = null;
    try {
      credStore = CredentialStoreFactory.getCredentialStore(getCredentialStore());
    } catch (CredentialStoreException cse) {
      throw new OAuthException(cse, "Error finding credentials from the store");
    }
    return credStore;
    }

  /*
   *  This method starts the Oauth2.0 Dance process.
   *  1. Make the call to fetch the authorization token.
   *  2. Host server redirect to OA2Callback.
   *  3. OA2Callback would try to fetch the access and refresh tokens.
   *  4. Interceptor from endpoint then takes care of inserting the required security headers
   */
  public synchronized void performOAuth2Dance(){
   
    setApplicationPage();
    Context context = Context.get();
   
    String callbackurl="";
    try {
      callbackurl = getCallbackUrl(context);
    } catch (OAuthException e1) {
      Platform.getInstance().log(e1);
    }
    setClient_uri(callbackurl);
   
    // Store the Oauth handler in session object
    context.getSessionMap().put(Configuration.OAUTH2_HANDLER, this);
   
    Object resp = Context.get().getHttpResponse();
    try {
        Context.get().sendRedirect(getAuthorizationNetworkUrl());
    } catch (Exception e) {
      Platform.getInstance().log(e);
    }
  }
 
 
  /*
   * This method sets the reference of page which initiated the secured call.
   * We need this to eventually navigate back to calling page
   */
 
  public void setApplicationPage() {
      // We just return to the same page
      Object _req = Context.get().getHttpRequest();
      if(_req instanceof HttpServletRequest) {
          HttpServletRequest request = (HttpServletRequest)_req;
        String url = UrlUtil.getRequestUrl(request);
        this.applicationPage=url;
      }
  }
 
  public String getApplicationPage() {
    return applicationPage;
  }
 
 
    public boolean shouldRenewToken() throws OAuthException {
        return shouldRenewToken(null);
    }
   
    /*
     * This method checks if the active token has expired based on the isvalidupto parameter from OADance,
     * Stored as  Expires parameter in AccessToken
     */
    public boolean shouldRenewToken(AccessToken token) throws OAuthException {
        // We do not automatically renew/acquire it - we just get it from the store
       if(token==null) {
            token = _findTokenFromStore(Context.get(), null);
            if(token==null) {
                throw new OAuthException(null,"No user token is available");
            }
        }
        return token.isExpired(getExpireThreshold());
    }

  public void setExpireThreshold(int expireThreshold) {
    this.expireThreshold = expireThreshold;
  }

  public int getExpireThreshold() {
    return expireThreshold;
  }
 
 
 
  
    // ==========================================================
    //  Utilities
    // ==========================================================
    /**
     * Read a token from an OAuthResponse
     * @param accessor
     * @param response
     * @return
     * @throws IOException
     *
     * This method creates a new token
     */
    public AccessToken createToken(String appId, String serviceName) throws OAuthException {
      try {
       
       
            long now = System.currentTimeMillis();
            String expirationinterval = getExpiresIn(); // we get the expires interval from server, convert this to a date object
            Date expiresIn = null;
            expiresIn = new Date(now+Long.parseLong(expirationinterval)*1000);
            return new AccessToken(
                        appId,
                        serviceName,
                        getConsumerKey(),
                        getAccessToken(),
                        getConsumerSecret(),
                        getUserId(),
                        expiresIn,
                        getRefreshToken()
            );
        } catch (Exception e) {
            throw new OAuthException(e);
        }
    }
   
    @Override
  public String getCallbackUrl(Context context) throws OAuthException {
      Object _req = context.getHttpRequest();
      if(_req instanceof HttpServletRequest) {
          HttpServletRequest request = (HttpServletRequest)_req;
            String proxyBaseUrl = PathUtil.concat(ServiceUtil.getProxyUrl(request),OA2Callback.URL_PATH,'/');
            return proxyBaseUrl;
      }
      return null;
    }

  @Override
  public void doPreAuthorizationFlow() throws Exception {
    // TODO Auto-generated method stub
   
  }

  @Override
  public void doPostAuthorizationFlow() throws Exception {
    // TODO Auto-generated method stub
    
  }
  public boolean isForceTrustSSLCertificate() {
    return forceTrustSSLCertificate;
  }

  public void setForceTrustSSLCertificate(boolean forceTrustSSLCertificate) {
    this.forceTrustSSLCertificate = forceTrustSSLCertificate;
  }

}
TOP

Related Classes of com.ibm.sbt.security.authentication.oauth.consumer.OAuth2Handler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.