You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by li...@apache.org on 2009/02/19 11:41:43 UTC

svn commit: r745809 - in /incubator/shindig/trunk/java: server/src/main/webapp/WEB-INF/ social-api/src/main/java/org/apache/shindig/social/core/oauth/ social-api/src/main/java/org/apache/shindig/social/opensocial/oauth/ social-api/src/main/java/org/apa...

Author: lindner
Date: Thu Feb 19 10:41:43 2009
New Revision: 745809

URL: http://svn.apache.org/viewvc?rev=745809&view=rev
Log:
SHINDIG-897 | Three Legged OAuth part 3 - remove consumer secret from entry class, add extensive error reporting, fix url encoding issue

Modified:
    incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/authorize.jsp
    incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/oauth/OAuthAuthenticationHandler.java
    incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/oauth/OAuthDataStore.java
    incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/oauth/OAuthEntry.java
    incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/sample/oauth/SampleOAuthDataStore.java
    incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/sample/oauth/SampleOAuthServlet.java

Modified: incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/authorize.jsp
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/authorize.jsp?rev=745809&r1=745808&r2=745809&view=diff
==============================================================================
--- incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/authorize.jsp (original)
+++ incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/authorize.jsp Thu Feb 19 10:41:43 2009
@@ -1,7 +1,9 @@
 <%@ page import="net.oauth.OAuthConsumer" %>
 <%@ page import="org.apache.shindig.social.opensocial.oauth.OAuthEntry" %>
 <%@ page import="org.apache.shindig.social.opensocial.oauth.OAuthDataStore" %>
+<%@ page import="java.net.URLEncoder" %>
 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
+
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">
 <%
@@ -41,7 +43,7 @@
 <form name="authZForm" action="authorize" method="POST">
   <input type="text" name="userId" value="" size="20"/><br>
   <input type="hidden" name="oauth_token" value="<%= token %>"/>
-  <input type="hidden" name="oauth_callback" value="<%= callback %>"/>
+  <input type="hidden" name="oauth_callback" value="<%= URLEncoder.encode(callback, "UTF-8") %>"/>
   <input type="submit" name="Authorize" value="Authorize"/>
 </form>
 

Modified: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/oauth/OAuthAuthenticationHandler.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/oauth/OAuthAuthenticationHandler.java?rev=745809&r1=745808&r2=745809&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/oauth/OAuthAuthenticationHandler.java (original)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/oauth/OAuthAuthenticationHandler.java Thu Feb 19 10:41:43 2009
@@ -84,7 +84,7 @@
 
     OAuthServiceProvider provider = new OAuthServiceProvider(null, null, null);
     OAuthAccessor accessor = new OAuthAccessor(new OAuthConsumer(null, entry.consumerKey,
-        entry.consumerSecret, provider));
+        store.getConsumer(entry.consumerKey).consumerSecret, provider));
 
     accessor.tokenSecret = entry.tokenSecret;
     accessor.accessToken = entry.token;

Modified: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/oauth/OAuthDataStore.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/oauth/OAuthDataStore.java?rev=745809&r1=745808&r2=745809&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/oauth/OAuthDataStore.java (original)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/oauth/OAuthDataStore.java Thu Feb 19 10:41:43 2009
@@ -52,8 +52,8 @@
    * for the given consumerKey. App specific checks like making sure the requested user has the
    * app installed should take place in this method.
    *
-   * @param consumerKey
-   * @param userId
+   * @param consumerKey A consumer key
+   * @param userId The userId to validate.
    * @return A valid Security Token
    */
   SecurityToken getSecurityTokenForConsumerRequest(String consumerKey, String userId);
@@ -85,7 +85,8 @@
    * Called when converting a request token to an access token.  This is called
    * in the final phase of 3-legged OAuth after the user authorizes the app.
    *
-   * @param entry
+   * @param entry The Entry to convert
+   * @return a new entry wiht type Type.ACCESS
    */
   OAuthEntry convertToAccessToken(OAuthEntry entry);
 

Modified: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/oauth/OAuthEntry.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/oauth/OAuthEntry.java?rev=745809&r1=745808&r2=745809&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/oauth/OAuthEntry.java (original)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/oauth/OAuthEntry.java Thu Feb 19 10:41:43 2009
@@ -31,7 +31,7 @@
   private static final long FIVE_MINUTES = 5 * 60 * 1000L;
 
   // Change this when incompatible changes occur..
-  static final long serialVersionUID = 1;
+  static final long serialVersionUID = 2;
 
   public static enum Type {
     REQUEST, ACCESS
@@ -46,7 +46,6 @@
   public boolean authorized;
 
   public String consumerKey;
-  public String consumerSecret;
 
   public Type type;
   public Date issueTime;
@@ -68,7 +67,6 @@
     this.tokenSecret= old.tokenSecret;
     this.authorized = old.authorized;
     this.consumerKey = old.consumerKey;
-    this.consumerSecret = old.consumerSecret;
     this.type = old.type;
     this.issueTime = old.issueTime;
     this.domain = old.domain;
@@ -76,6 +74,11 @@
   }
 
   public boolean isExpired() {
+    Date currentDate = new Date();
+    return currentDate.compareTo(this.expiresAt()) > 0;
+  }
+
+  public Date expiresAt() {
     long expirationTime = issueTime.getTime();
     switch (type) {
       case REQUEST:
@@ -86,7 +89,6 @@
         break;
     }
 
-    Date currentDate = new Date();
-    return currentDate.getTime() > expirationTime;
+    return new Date(expirationTime);
   }
 }

Modified: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/sample/oauth/SampleOAuthDataStore.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/sample/oauth/SampleOAuthDataStore.java?rev=745809&r1=745808&r2=745809&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/sample/oauth/SampleOAuthDataStore.java (original)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/sample/oauth/SampleOAuthDataStore.java Thu Feb 19 10:41:43 2009
@@ -64,7 +64,9 @@
           return null;
       // null below is for the callbackUrl, which we don't have in the db
       OAuthConsumer consumer = new OAuthConsumer(null, consumerKey, consumerSecret, SERVICE_PROVIDER);
-      consumer.setProperty("samplecontainer-attribute", "value");
+      if (consumer != null)
+        consumer.setProperty("samplecontainer-attribute", "value");
+
       return consumer;
 
     } catch (JSONException e) {
@@ -77,7 +79,6 @@
     OAuthEntry entry = new OAuthEntry();
     entry.appId = consumerKey;
     entry.consumerKey = consumerKey;
-    entry.consumerSecret = getConsumer(consumerKey).consumerSecret;
     entry.domain = "samplecontainer.com";
     entry.container = "default";
 

Modified: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/sample/oauth/SampleOAuthServlet.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/sample/oauth/SampleOAuthServlet.java?rev=745809&r1=745808&r2=745809&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/sample/oauth/SampleOAuthServlet.java (original)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/sample/oauth/SampleOAuthServlet.java Thu Feb 19 10:41:43 2009
@@ -20,13 +20,7 @@
 import com.google.inject.Inject;
 import com.google.inject.name.Named;
 
-import net.oauth.OAuth;
-import net.oauth.OAuthAccessor;
-import net.oauth.OAuthConsumer;
-import net.oauth.OAuthException;
-import net.oauth.OAuthMessage;
-import net.oauth.OAuthValidator;
-import net.oauth.SimpleOAuthValidator;
+import net.oauth.*;
 import net.oauth.server.OAuthServlet;
 import org.apache.shindig.common.servlet.InjectedServlet;
 import org.apache.shindig.social.opensocial.oauth.OAuthEntry;
@@ -72,30 +66,42 @@
       HttpServletResponse servletResponse) throws ServletException, IOException {
     String path = servletRequest.getPathInfo();
 
-    if (path.endsWith("requestToken")) {
-      createRequestToken(servletRequest, servletResponse);
-    } else if (path.endsWith("authorize")) {
-      authorizeRequestToken(servletRequest, servletResponse);
-    } else if (path.endsWith("accessToken")) {
-      createAccessToken(servletRequest, servletResponse);
+    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(servletResponse.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 ServletException, IOException {
+      HttpServletResponse servletResponse) throws IOException, OAuthException, URISyntaxException {
     OAuthMessage requestMessage = OAuthServlet.getMessage(servletRequest, null);
 
     String consumerKey = requestMessage.getConsumerKey();
+    if (consumerKey == null) {
+      OAuthProblemException e = new OAuthProblemException("parameter_absent");
+      e.setParameter("oauth_paramaeters_absent", "oauth_consumer_key");
+      throw e;
+    }
     OAuthConsumer consumer = dataStore.getConsumer(consumerKey);
+
+    if (consumer == null)
+      throw new OAuthProblemException("consumer_key_unknown");
+
     OAuthAccessor accessor = new OAuthAccessor(consumer);
-    try {
-      VALIDATOR.validateMessage(requestMessage, accessor);
-    } catch (OAuthException e) {
-      handleException(e, servletRequest, servletResponse, true);
-    } catch (URISyntaxException e) {
-      handleException(e, servletRequest, servletResponse, true);
-    }
+    VALIDATOR.validateMessage(requestMessage, accessor);
 
     // generate request_token and secret
     OAuthEntry entry = dataStore.generateRequestToken(consumerKey);
@@ -108,14 +114,15 @@
   /////////////////////
   // deal with authorization request
   private void authorizeRequestToken(HttpServletRequest servletRequest,
-      HttpServletResponse servletResponse) throws ServletException, IOException {
+      HttpServletResponse servletResponse) throws ServletException, IOException, OAuthException, URISyntaxException {
 
     OAuthMessage requestMessage = OAuthServlet.getMessage(servletRequest, null);
-    OAuthEntry entry = getToken(servletRequest, servletResponse, requestMessage, false);
+    OAuthEntry entry = dataStore.getEntry(requestMessage.getToken());
+
+    if (entry == null) {
+      servletResponse.sendError(servletResponse.SC_NOT_FOUND, "Authentication Token not found");
+    }
 
-    if (entry == null)
-       return;
-    
     OAuthConsumer consumer = dataStore.getConsumer(entry.consumerKey);
     String callback = requestMessage.getParameter("oauth_callback");
     if (callback == null) {
@@ -165,12 +172,15 @@
   // 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 {
+      HttpServletResponse servletResponse) throws ServletException, IOException, OAuthException, URISyntaxException {
     OAuthMessage requestMessage = OAuthServlet.getMessage(servletRequest, null);
 
-    OAuthEntry entry = getToken(servletRequest, servletResponse, requestMessage, true);
+    OAuthEntry entry = getValidatedEntry(requestMessage);
+    if (entry == null)
+      throw new OAuthProblemException("token_rejected");
+
     if (!entry.authorized) {
-      throw new ServletException("permission denied. request token has not been authorized.");
+      throw new ServletException("additional_authorization_required");
     }
 
     // turn request token into access token
@@ -183,39 +193,43 @@
   }
 
 
-  private OAuthEntry getToken(HttpServletRequest servletRequest,
-      HttpServletResponse servletResponse, OAuthMessage requestMessage, boolean validate)
-      throws IOException, ServletException {
+  private OAuthEntry getValidatedEntry(OAuthMessage requestMessage)
+      throws IOException, ServletException, OAuthException, URISyntaxException {
 
     OAuthEntry entry = dataStore.getEntry(requestMessage.getToken());
-    if (entry == null || entry.type != OAuthEntry.Type.REQUEST || entry.isExpired()) {
-      throw new ServletException("permission denied. token is invalid.");
-    }
+    if (entry == null)
+      throw new OAuthProblemException("token_rejected");
+
+    if (entry.type != OAuthEntry.Type.REQUEST)
+      throw new OAuthProblemException("token_used");
+
+    if (entry.isExpired())
+      throw new OAuthProblemException("token_expired");
 
     // find consumer key, compare with supplied value, if present.
-    String consumerKey = entry.consumerKey;
-    if (requestMessage.getConsumerKey() != null && !consumerKey.equals(requestMessage.getConsumerKey())) {
-        throw new ServletException("permission denied. consumer keys don't match.");
+
+    if  (requestMessage.getConsumerKey() == null) {
+      OAuthProblemException e = new OAuthProblemException("parameter_absent");
+      e.setParameter("oauth_paramaeters_absent", "oauth_consumer");
+      throw e;
     }
 
+    String consumerKey = entry.consumerKey;
+    if (!consumerKey.equals(requestMessage.getConsumerKey()))
+        throw new OAuthProblemException("consumer_key_refused");
+
     OAuthConsumer consumer = dataStore.getConsumer(consumerKey);
 
+    if (consumer == null)
+      throw new OAuthProblemException("consumer_key_unknown");
+    
     OAuthAccessor accessor = new OAuthAccessor(consumer);
 
     accessor.requestToken = entry.token;
     accessor.tokenSecret = entry.tokenSecret;
 
-    if (validate) {
-      try {
-        VALIDATOR.validateMessage(requestMessage, accessor);
-      } catch (OAuthException e) {
-        handleException(e, servletRequest, servletResponse, true);
-        return null;
-      } catch (URISyntaxException e) {
-        handleException(e, servletRequest, servletResponse, true);
-        return null;
-      }
-    }
+    VALIDATOR.validateMessage(requestMessage, accessor);
+
     return entry;
   }