You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by li...@apache.org on 2009/04/23 09:40:08 UTC
svn commit: r767835 - in /incubator/shindig/trunk/java:
server/src/main/webapp/WEB-INF/
social-api/src/main/java/org/apache/shindig/social/opensocial/oauth/
social-api/src/main/java/org/apache/shindig/social/sample/oauth/
Author: lindner
Date: Thu Apr 23 07:40:07 2009
New Revision: 767835
URL: http://svn.apache.org/viewvc?rev=767835&view=rev
Log:
SHINDIG-1027 | Address problems with three-legged OAuth
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/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=767835&r1=767834&r2=767835&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 Apr 23 07:40:07 2009
@@ -29,16 +29,15 @@
// Bounce back to the servlet to handle redirecting to the callback URL
request.getRequestDispatcher("/oauth/authorize?oauth_token=" + token + "&oauth_callback=" + callback)
.forward(request,response);
+ } else if (request.getParameter("Deny") != null) {
+ dataStore.removeToken(entry);
}
-
// Gather some data
- String appTitle =(String)consumer.getProperty("title");
- String appDesc = (String)consumer.getProperty("description");
- if (appDesc == null)
- appDesc = consumer.consumerKey;
+ pageContext.setAttribute("appTitle", consumer.getProperty("title") , PageContext.PAGE_SCOPE);
+ pageContext.setAttribute("appDesc", consumer.getProperty("description"), PageContext.PAGE_SCOPE);
- String appIcon = (String)consumer.getProperty("icon");
- String appThumbnail = (String)consumer.getProperty("thumbnail");
+ pageContext.setAttribute("appIcon", consumer.getProperty("icon"));
+ pageContext.setAttribute("appThumbnail", consumer.getProperty("thumbnail"));
%>
<html>
<head>
@@ -50,13 +49,21 @@
The following application wants to access your account information<br/><br/>
-<h3><img src="<%= appIcon %>"/><%=appTitle %>" is trying to access your information.</h3>
-<img src="<%= appThumbnail%>" align="left" width="120" height="60"/>
-<c:out value="appDesc" default=""/>
+<h3><img src="${appIcon}"/> <b><c:out value="${appTitle}"/></b> is trying to access your information.</h3>
+<img src="${appThumbnail}" align="left" width="120" height="60"/>
+<c:out value="${appDesc}" default=""/>
<br/>
+<c:if test="${SECURITY_THREAT_2009_1}">
+ <font color="red"><b>POSSIBLE SECURITY RISK</b> -
+ Deny this request unless you directly initiated it from the Official
+ <i><c:out value="${appTitle}"/></i> web site
+ </font>
+</c:if>
+
<form name="authZForm" action="authorize" method="POST">
<input type="hidden" name="oauth_token" value="<%= token %>"/>
<input type="hidden" name="oauth_callback" value="<%= URLEncoder.encode(callback, "UTF-8") %>"/>
+ <input type="submit" name="Authorize" value="Deny"/>
<input type="submit" name="Authorize" value="Authorize"/>
</form>
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=767835&r1=767834&r2=767835&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 Apr 23 07:40:07 2009
@@ -79,7 +79,7 @@
* @return An OAuthEntry containing a valid request token.
* @throws OAuthProblemException when the implementing class wants to control the error response
*/
- OAuthEntry generateRequestToken(String consumerKey) throws OAuthProblemException;
+ OAuthEntry generateRequestToken(String consumerKey, String oauthVersion) throws OAuthProblemException;
/**
@@ -101,4 +101,19 @@
* @throws OAuthProblemException when the implementing class wants to control the error response
*/
void authorizeToken(OAuthEntry entry, String userId) throws OAuthProblemException;
+
+ /**
+ * Mark a token DISABLED and store it.
+ *
+ * @param entry A valid OAuthEntry
+ */
+ void disableToken(OAuthEntry entry);
+
+ /**
+ * Remove a token
+ *
+ * @param entry A valid OAuthEntry
+ */
+ void removeToken(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=767835&r1=767834&r2=767835&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 Apr 23 07:40:07 2009
@@ -32,7 +32,7 @@
static final long serialVersionUID = 2;
public static enum Type {
- REQUEST, ACCESS
+ REQUEST, ACCESS, DISABLED
}
public String appId;
@@ -50,6 +50,7 @@
public String domain;
public String container;
+ public String oauthVersion;
public OAuthEntry() {}
@@ -69,6 +70,7 @@
this.issueTime = old.issueTime;
this.domain = old.domain;
this.container = old.container;
+ this.oauthVersion = old.oauthVersion;
}
public boolean isExpired() {
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=767835&r1=767834&r2=767835&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 Apr 23 07:40:07 2009
@@ -85,7 +85,7 @@
}
// Generate a valid requestToken for the given consumerKey
- public OAuthEntry generateRequestToken(String consumerKey) {
+ public OAuthEntry generateRequestToken(String consumerKey, String oauthVersion) {
OAuthEntry entry = new OAuthEntry();
entry.appId = consumerKey;
entry.consumerKey = consumerKey;
@@ -97,6 +97,7 @@
entry.type = OAuthEntry.Type.REQUEST;
entry.issueTime = new Date();
+ entry.oauthVersion = oauthVersion;
oauthEntries.put(entry.token, entry);
return entry;
@@ -115,7 +116,6 @@
accessEntry.type = OAuthEntry.Type.ACCESS;
accessEntry.issueTime = new Date();
-
oauthEntries.remove(entry.token);
oauthEntries.put(accessEntry.token, accessEntry);
@@ -129,6 +129,19 @@
entry.userId = Preconditions.checkNotNull(userId);
}
+ public void disableToken(OAuthEntry entry) {
+ Preconditions.checkNotNull(entry);
+ entry.type = OAuthEntry.Type.DISABLED;
+
+ oauthEntries.put(entry.token, entry);
+ }
+
+ public void removeToken(OAuthEntry entry) {
+ Preconditions.checkNotNull(entry);
+
+ oauthEntries.remove(entry.token);
+ }
+
// Return the proper security token for a 2 legged oauth request that has been validated
// for the given consumerKey. App specific checks like making sure the requested user has the
// app installed should take place in this method
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=767835&r1=767834&r2=767835&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 Apr 23 07:40:07 2009
@@ -92,7 +92,7 @@
String consumerKey = requestMessage.getConsumerKey();
if (consumerKey == null) {
OAuthProblemException e = new OAuthProblemException(OAuth.Problems.PARAMETER_ABSENT);
- e.setParameter(OAuth.Problems.OAUTH_PARAMETERS_ABSENT, "oauth_consumer_key");
+ e.setParameter(OAuth.Problems.OAUTH_PARAMETERS_ABSENT, OAuth.OAUTH_CONSUMER_KEY);
throw e;
}
OAuthConsumer consumer = dataStore.getConsumer(consumerKey);
@@ -104,7 +104,7 @@
VALIDATOR.validateMessage(requestMessage, accessor);
// generate request_token and secret
- OAuthEntry entry = dataStore.generateRequestToken(consumerKey);
+ OAuthEntry entry = dataStore.generateRequestToken(consumerKey, requestMessage.getParameter(OAuth.OAUTH_VERSION));
sendResponse(servletResponse, OAuth.newList(OAuth.OAUTH_TOKEN, entry.token,
OAuth.OAUTH_TOKEN_SECRET, entry.tokenSecret));
@@ -131,12 +131,35 @@
}
OAuthConsumer consumer = dataStore.getConsumer(entry.consumerKey);
- String callback = requestMessage.getParameter("oauth_callback");
+
+ // 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.oauthVersion == null || OAuth.VERSION_1_0.equals(entry.oauthVersion));
+
+ // 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..
@@ -153,16 +176,18 @@
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 out of band.
+ // If we're here then the entry has been authorized
- // redirect to callback param oauth_callback
+ // redirect to callback
if (callback == null) {
+ // consumer did not specify a callback
servletResponse.setContentType("text/plain");
OutputStream out = servletResponse.getOutputStream();
out.write("Token successfully authorized.".getBytes());
@@ -188,7 +213,10 @@
throw new OAuthProblemException(OAuth.Problems.TOKEN_REJECTED);
if (!entry.authorized) {
- throw new ServletException("additional_authorization_required");
+ // 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
@@ -218,7 +246,7 @@
if (requestMessage.getConsumerKey() == null) {
OAuthProblemException e = new OAuthProblemException(OAuth.Problems.PARAMETER_ABSENT);
- e.setParameter(OAuth.Problems.OAUTH_PARAMETERS_ABSENT, "oauth_consumer");
+ e.setParameter(OAuth.Problems.OAUTH_PARAMETERS_ABSENT, OAuth.OAUTH_CONSUMER_KEY);
throw e;
}