Package org.apache.shindig.social.sample.oauth

Source Code of org.apache.shindig.social.sample.oauth.SampleOAuthServlet

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.shindig.social.sample.oauth;

import com.google.inject.Inject;
import com.google.inject.name.Named;

import net.oauth.*;
import net.oauth.OAuth.Parameter;
import net.oauth.server.OAuthServlet;

import org.apache.shindig.auth.OAuthConstants;
import org.apache.shindig.common.servlet.HttpUtil;
import org.apache.shindig.common.servlet.InjectedServlet;
import org.apache.shindig.social.opensocial.oauth.OAuthEntry;
import org.apache.shindig.social.opensocial.oauth.OAuthDataStore;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URISyntaxException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* This is a sample class that demonstrates how oauth tokens can be handed out and authorized.
* This is most certainly not production code. Your server should have clear ui, require user
* login for creating consumer secrets and authorizing request tokens, do better patch dispatching,
* and use a non-in memory data store.
*/
public class SampleOAuthServlet extends InjectedServlet {
  public static final OAuthValidator VALIDATOR = new SimpleOAuthValidator();
  private OAuthDataStore dataStore;
  private String oauthAuthorizeAction;
  private boolean enableOAuth10;
  private boolean enableSignedCallbacks;

  @Inject
  public void setDataStore(OAuthDataStore dataStore) {
    this.dataStore = dataStore;
  }

  @Inject void setAuthorizeAction(@Named("shindig.oauth.authorize-action") String authorizeAction) {
     this.oauthAuthorizeAction = authorizeAction;
  }
 
  @Inject void setSupportOAuth10(@Named("shindig.oauth.enable-oauth-1.0") boolean enableOAuth10) {
    this.enableOAuth10 = enableOAuth10;
  }

  @Inject void setSupportSignedCallbacks(@Named("shindig.oauth.enable-signed-callbacks")
      boolean enableSignedCallbacks) {
    this.enableSignedCallbacks = enableSignedCallbacks;
  }

  @Override
  protected void doPost(HttpServletRequest servletRequest,
      HttpServletResponse servletResponse) throws ServletException, IOException {

    doGet(servletRequest, servletResponse);
  }

  @Override
  protected void doGet(HttpServletRequest servletRequest,
      HttpServletResponse servletResponse) throws ServletException, IOException {
    HttpUtil.setNoCache(servletResponse);
    String path = servletRequest.getPathInfo();

    try {
      // dispatch
      if (path.endsWith("requestToken")) {
        createRequestToken(servletRequest, servletResponse);
      } else if (path.endsWith("authorize")) {
        authorizeRequestToken(servletRequest, servletResponse);
      } else if (path.endsWith("accessToken")) {
        createAccessToken(servletRequest, servletResponse);
      } else {
        servletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, "unknown Url");
      }
    } catch (OAuthException e) {
      handleException(e, servletRequest, servletResponse, true);
    } catch (URISyntaxException e) {
      handleException(e, servletRequest, servletResponse, true);
    }
  }

  // Hand out a request token if the consumer key and secret are valid
  private void createRequestToken(HttpServletRequest servletRequest,
      HttpServletResponse servletResponse) throws IOException, OAuthException, URISyntaxException {
    OAuthMessage requestMessage = OAuthServlet.getMessage(servletRequest, null);

    String consumerKey = requestMessage.getConsumerKey();
    if (consumerKey == null) {
      OAuthProblemException e = new OAuthProblemException(OAuth.Problems.PARAMETER_ABSENT);
      e.setParameter(OAuth.Problems.OAUTH_PARAMETERS_ABSENT, OAuth.OAUTH_CONSUMER_KEY);
      throw e;
    }
    OAuthConsumer consumer = dataStore.getConsumer(consumerKey);

    if (consumer == null)
      throw new OAuthProblemException(OAuth.Problems.CONSUMER_KEY_UNKNOWN);

    OAuthAccessor accessor = new OAuthAccessor(consumer);
    VALIDATOR.validateMessage(requestMessage, accessor);

    String callback = null;
    if (enableSignedCallbacks) {
      callback = requestMessage.getParameter(OAuth.OAUTH_CALLBACK);
    }
    if (callback == null && !enableOAuth10) {
      OAuthProblemException e = new OAuthProblemException(OAuth.Problems.PARAMETER_ABSENT);
      e.setParameter(OAuth.Problems.OAUTH_PARAMETERS_ABSENT, OAuth.OAUTH_CALLBACK);
      throw e;
    }
  
    // generate request_token and secret
    OAuthEntry entry = dataStore.generateRequestToken(consumerKey,
        requestMessage.getParameter(OAuth.OAUTH_VERSION), callback);

    List<Parameter> responseParams = OAuth.newList(OAuth.OAUTH_TOKEN, entry.token,
        OAuth.OAUTH_TOKEN_SECRET, entry.tokenSecret);
    if (callback != null) {
      responseParams.add(new Parameter(OAuthConstants.OAUTH_CALLBACK_CONFIRMED, "true"));
    }
    sendResponse(servletResponse, responseParams);
  }


  /////////////////////
  // deal with authorization request
  private void authorizeRequestToken(HttpServletRequest servletRequest,
      HttpServletResponse servletResponse) throws ServletException, IOException, OAuthException, URISyntaxException {

    OAuthMessage requestMessage = OAuthServlet.getMessage(servletRequest, null);

    if (requestMessage.getToken() == null) {
      // MALFORMED REQUEST
      servletResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "Authentication token not found");
      return;
    }
    OAuthEntry entry = dataStore.getEntry(requestMessage.getToken());

    if (entry == null) {
      servletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, "OAuth Entry not found");
      return;
    }

    OAuthConsumer consumer = dataStore.getConsumer(entry.consumerKey);

    // Extremely rare case where consumer dissappears
    if (consumer == null) {
      servletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, "consumer for entry not found");
      return;
    }
   
    // A flag to deal with protocol flaws in OAuth/1.0
    Boolean securityThreat_2009_1 = !entry.callbackUrlSigned;

    // Check for a callback in the oauth entry
    String callback = entry.callbackUrl;

    if (callback == null) {
      // see if there's a callback in the url params
      callback = requestMessage.getParameter(OAuth.OAUTH_CALLBACK);
    }

    if (callback == null) {
      // see if the consumer has a callback
      callback = consumer.callbackURL;
    }

    // The token is disabled if you try to convert to an access token prior to authorization
    if (entry.type == OAuthEntry.Type.DISABLED) {
      servletResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "This token is disabled, please reinitate login");
      return;
    }

    // Redirect to a UI flow if the token is not authorized
    if (!entry.authorized) {
      // TBD -- need to decode encrypted payload somehow..
      if (this.oauthAuthorizeAction.startsWith("http")) {
        // Redirect to authorization page with params
        // Supply standard set of params
        // TBD
      } else {
        // Use internal forward to a jsp page
        servletRequest.setAttribute("OAUTH_DATASTORE",  dataStore);
       
        servletRequest.setAttribute("OAUTH_ENTRY",  entry);
        servletRequest.setAttribute("CALLBACK", callback);

        servletRequest.setAttribute("TOKEN", entry.token);
        servletRequest.setAttribute("CONSUMER", consumer);
        servletRequest.setAttribute("SECURITY_THREAT_2009_1", securityThreat_2009_1);
       
        servletRequest.getRequestDispatcher(oauthAuthorizeAction).forward(servletRequest,servletResponse);
      }
      return;
    }

    // If we're here then the entry has been authorized

    // redirect to callback
    if (callback == null || "oob".equals(callback)) {
      // consumer did not specify a callback
      servletResponse.setContentType("text/plain");
      PrintWriter out = servletResponse.getWriter();
      out.write("Token successfully authorized.\n");     
      if (entry.callbackToken != null) {
        // Usability fail.
        out.write("Please enter code " + entry.callbackToken + " at the consumer.");
      }
    } else {
      callback = OAuth.addParameters(callback, OAuth.OAUTH_TOKEN, entry.token);
      // Add user_id to the callback
      callback = OAuth.addParameters(callback, "user_id", entry.userId);
      if (entry.callbackToken != null) {
        callback = OAuth.addParameters(callback, OAuthConstants.OAUTH_VERIFIER,
            entry.callbackToken);
      }

      servletResponse.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
      servletResponse.setHeader("Location", callback);
    }
  }

  // Hand out an access token if the consumer key and secret are valid and the user authorized
  // the requestToken
  private void createAccessToken(HttpServletRequest servletRequest,
      HttpServletResponse servletResponse) throws ServletException, IOException, OAuthException, URISyntaxException {
    OAuthMessage requestMessage = OAuthServlet.getMessage(servletRequest, null);

    OAuthEntry entry = getValidatedEntry(requestMessage);
    if (entry == null)
      throw new OAuthProblemException(OAuth.Problems.TOKEN_REJECTED);

    if (entry.callbackToken != null) {
      // We're using the fixed protocol
      String clientCallbackToken = requestMessage.getParameter(OAuthConstants.OAUTH_VERIFIER);
      if (!entry.callbackToken.equals(clientCallbackToken)) {
        dataStore.disableToken(entry);
        servletResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "This token is not authorized");
        return;
      }
    } else if (!entry.authorized) {
      // Old protocol.  Catch consumers trying to convert a token to one that's not authorized
      dataStore.disableToken(entry);
      servletResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "This token is not authorized");
      return;
    }

    // turn request token into access token
    OAuthEntry accessEntry = dataStore.convertToAccessToken(entry);

    sendResponse(servletResponse, OAuth.newList(
        OAuth.OAUTH_TOKEN, accessEntry.token,
        OAuth.OAUTH_TOKEN_SECRET, accessEntry.tokenSecret,
        "user_id", entry.userId));
  }


  private OAuthEntry getValidatedEntry(OAuthMessage requestMessage)
      throws IOException, ServletException, OAuthException, URISyntaxException {

    OAuthEntry entry = dataStore.getEntry(requestMessage.getToken());
    if (entry == null)
      throw new OAuthProblemException(OAuth.Problems.TOKEN_REJECTED);

    if (entry.type != OAuthEntry.Type.REQUEST)
      throw new OAuthProblemException(OAuth.Problems.TOKEN_USED);

    if (entry.isExpired())
      throw new OAuthProblemException(OAuth.Problems.TOKEN_EXPIRED);

    // find consumer key, compare with supplied value, if present.

    if  (requestMessage.getConsumerKey() == null) {
      OAuthProblemException e = new OAuthProblemException(OAuth.Problems.PARAMETER_ABSENT);
      e.setParameter(OAuth.Problems.OAUTH_PARAMETERS_ABSENT, OAuth.OAUTH_CONSUMER_KEY);
      throw e;
    }

    String consumerKey = entry.consumerKey;
    if (!consumerKey.equals(requestMessage.getConsumerKey()))
        throw new OAuthProblemException(OAuth.Problems.CONSUMER_KEY_REFUSED);

    OAuthConsumer consumer = dataStore.getConsumer(consumerKey);

    if (consumer == null)
      throw new OAuthProblemException(OAuth.Problems.CONSUMER_KEY_UNKNOWN);
   
    OAuthAccessor accessor = new OAuthAccessor(consumer);

    accessor.requestToken = entry.token;
    accessor.tokenSecret = entry.tokenSecret;

    VALIDATOR.validateMessage(requestMessage, accessor);

    return entry;
  }

  private void sendResponse(HttpServletResponse servletResponse, List<OAuth.Parameter> parameters)
      throws IOException {
    servletResponse.setContentType("text/plain");
    OutputStream out = servletResponse.getOutputStream();
    OAuth.formEncode(parameters, out);
    out.close();
  }

  private static void handleException(Exception e, HttpServletRequest request,
      HttpServletResponse response, boolean sendBody)
      throws IOException, ServletException {
    String realm = (request.isSecure()) ? "https://" : "http://";

    if (request.getHeader("Host") != null) {
      realm += request.getHeader("Host");
    } else {
      realm += request.getLocalName();
    }
    OAuthServlet.handleException(response, e, realm, sendBody);
  }

}
TOP

Related Classes of org.apache.shindig.social.sample.oauth.SampleOAuthServlet

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.