Author: lindner
Date: Fri Mar 27 00:58:35 2009
New Revision: 758949
URL: http://svn.apache.org/viewvc?rev=758949&view=rev
Log:
SHINDIG-995 | Use OAuthProblemException to allow fine-grained error control
Modified:
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AuthenticationServletFilter.java
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/test/java/org/apache/shindig/social/core/oauth/OAuthAuthenticationHanderTest.java
Modified:
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AuthenticationServletFilter.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AuthenticationServletFilter.java?rev=758949&r1=758948&r2=758949&view=diff
==============================================================================
---
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AuthenticationServletFilter.java
(original)
+++
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AuthenticationServletFilter.java
Fri Mar 27 00:58:35 2009
@@ -96,7 +96,9 @@
// We did not find a security token so we will just pass null
callChain(chain, req, resp);
} catch (AuthenticationHandler.InvalidAuthenticationException iae) {
- logger.log(Level.INFO, iae.getMessage(), iae.getCause());
+ Throwable cause = iae.getCause();
+ logger.log(Level.INFO, iae.getMessage(), cause);
+
if (iae.getAdditionalHeaders() != null) {
for (Map.Entry<String,String> entry :
iae.getAdditionalHeaders().entrySet()) {
resp.addHeader(entry.getKey(), entry.getValue());
@@ -105,7 +107,10 @@
if (iae.getRedirect() != null) {
resp.sendRedirect(iae.getRedirect());
} else {
- resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, iae.getMessage());
+ // For now append the cause message if set, this allows us to send any
underlying oauth errors
+ String message = (cause==null) ? iae.getMessage() : iae.getMessage() +
cause.getMessage();
+
+ resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, message);
}
}
}
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=758949&r1=758948&r2=758949&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
Fri Mar 27 00:58:35 2009
@@ -27,6 +27,7 @@
import net.oauth.OAuthMessage;
import net.oauth.OAuthServiceProvider;
import net.oauth.SimpleOAuthValidator;
+import net.oauth.OAuthProblemException;
import net.oauth.server.OAuthServlet;
import org.apache.commons.codec.binary.Base64;
@@ -87,7 +88,7 @@
}
try {
return verifyMessage(message);
- } catch (InvalidAuthenticationException iae) {
+ } catch (OAuthProblemException oauthException) {
// Legacy body signing is intended for backwards compatability with
opensocial clients
// that assumed they could use the raw request body as a pseudo query
param to get
// body signing. This assumption was born out of the limitations of the
OAuth 1.0 spec which
@@ -103,16 +104,18 @@
try {
message.addParameter(readBodyString(request), "");
return verifyMessage(message);
- } catch (IOException ioe) {
- throw iae;
+ } catch (OAuthProblemException ioe) {
+ // ignore, let original exception be thrown
+ } catch (IOException e) {
+ // also ignore;
}
}
- throw iae;
+ throw new InvalidAuthenticationException("OAuth Authentication Failure",
oauthException);
}
}
protected SecurityToken verifyMessage(OAuthMessage message)
- throws InvalidAuthenticationException {
+ throws OAuthProblemException {
OAuthEntry entry = getOAuthEntry(message);
OAuthConsumer authConsumer = getConsumer(message);
@@ -128,43 +131,46 @@
try {
message.validateMessage(accessor, new SimpleOAuthValidator());
} catch (OAuthException e) {
- throw new InvalidAuthenticationException("Unable to verify OAuth
request", e);
+ throw new OAuthProblemException();
} catch (IOException e) {
- throw new InvalidAuthenticationException("Unable to verify OAuth
request", e);
+ throw new OAuthProblemException();
} catch (URISyntaxException e) {
- throw new InvalidAuthenticationException("Unable to verify OAuth
request", e);
+ throw new OAuthProblemException();
}
return getTokenFromVerifiedRequest(message, entry, authConsumer);
}
- protected OAuthEntry getOAuthEntry(OAuthMessage message) throws
InvalidAuthenticationException {
+ protected OAuthEntry getOAuthEntry(OAuthMessage message) throws
OAuthProblemException {
OAuthEntry entry = null;
String token = getParameter(message, OAuth.OAUTH_TOKEN);
if (!StringUtils.isEmpty(token)) {
entry = store.getEntry(token);
if (entry == null) {
- throw new InvalidAuthenticationException("No oauth entry for token: "
+ token, null);
+ OAuthProblemException e = new
OAuthProblemException(OAuth.Problems.TOKEN_REJECTED);
+ e.setParameter(OAuth.Problems.OAUTH_PROBLEM_ADVICE, "cannot find
token");
+ throw e;
} else if (entry.type != OAuthEntry.Type.ACCESS) {
- throw new InvalidAuthenticationException("token is not an access
token.", null);
+ OAuthProblemException e = new
OAuthProblemException(OAuth.Problems.TOKEN_REJECTED);
+ e.setParameter(OAuth.Problems.OAUTH_PROBLEM_ADVICE, "token is not an
access token");
+ throw e;
} else if (entry.isExpired()) {
- throw new InvalidAuthenticationException("access token has expired.",
null);
+ throw new OAuthProblemException(OAuth.Problems.TOKEN_EXPIRED);
}
}
return entry;
}
- protected OAuthConsumer getConsumer(OAuthMessage message) throws
InvalidAuthenticationException {
+ protected OAuthConsumer getConsumer(OAuthMessage message) throws
OAuthProblemException {
String consumerKey = getParameter(message, OAuth.OAUTH_CONSUMER_KEY);
OAuthConsumer authConsumer = store.getConsumer(consumerKey);
if (authConsumer == null) {
- throw new InvalidAuthenticationException("No consumer registered for key
" + consumerKey,
- null);
+ throw new OAuthProblemException(OAuth.Problems.CONSUMER_KEY_UNKNOWN);
}
return authConsumer;
}
protected SecurityToken getTokenFromVerifiedRequest(OAuthMessage message,
OAuthEntry entry,
- OAuthConsumer authConsumer) {
+ OAuthConsumer authConsumer) throws OAuthProblemException {
if (entry != null) {
return new OAuthSecurityToken(entry.userId, entry.callbackUrl,
entry.appId,
entry.domain, entry.container);
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=758949&r1=758948&r2=758949&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
Fri Mar 27 00:58:35 2009
@@ -18,6 +18,7 @@
package org.apache.shindig.social.opensocial.oauth;
import net.oauth.OAuthConsumer;
+import net.oauth.OAuthProblemException;
import org.apache.shindig.auth.SecurityToken;
@@ -43,11 +44,15 @@
* for the given consumerKey. App specific checks like making sure the
requested user has the
* app installed should take place in this method.
*
+ * Returning null may allow for other authentication schemes to be used.
Throwing an
+ * OAuthProblemException will allows errors to be returned to the caller.
+ *
* @param consumerKey A consumer key
* @param userId The userId to validate.
* @return A valid Security Token
+ * @throws OAuthProblemException when there are errors
*/
- SecurityToken getSecurityTokenForConsumerRequest(String consumerKey, String
userId);
+ SecurityToken getSecurityTokenForConsumerRequest(String consumerKey, String
userId) throws OAuthProblemException;
/**
* Lookup consumers. Generally this corresponds to an opensocial Application
@@ -58,18 +63,23 @@
* plus you should consider setting properties that correspond to the
metadata
* in the opensocial app like icon, description, etc.
*
+ * Returning null will inform the client that the consumer key does not
exist. If you
+ * want to control the error response throw an OAuthProblemException
+ *
* @param consumerKey A valid, non-null ConsumerKey
* @return the consumer object corresponding to the specified key.
+ * @throws OAuthProblemException when the implementing class wants to signal
errors
*/
- OAuthConsumer getConsumer(String consumerKey);
+ OAuthConsumer getConsumer(String consumerKey) throws OAuthProblemException;
/**
* Generate a valid requestToken for the given consumerKey.
*
* @param consumerKey A valid consumer key
* @return An OAuthEntry containing a valid request token.
+ * @throws OAuthProblemException when the implementing class wants to
control the error response
*/
- OAuthEntry generateRequestToken(String consumerKey);
+ OAuthEntry generateRequestToken(String consumerKey) throws
OAuthProblemException;
/**
@@ -77,9 +87,10 @@
* in the final phase of 3-legged OAuth after the user authorizes the app.
*
* @param entry The Entry to convert
- * @return a new entry wiht type Type.ACCESS
+ * @return a new entry with type Type.ACCESS
+ * @throws OAuthProblemException when the implementing class wants to
control the error response
*/
- OAuthEntry convertToAccessToken(OAuthEntry entry);
+ OAuthEntry convertToAccessToken(OAuthEntry entry) throws
OAuthProblemException;
/**
@@ -87,6 +98,7 @@
*
* @param entry A valid OAuthEntry
* @param userId A user id
+ * @throws OAuthProblemException when the implementing class wants to
control the error response
*/
- void authorizeToken(OAuthEntry entry, String userId);
+ void authorizeToken(OAuthEntry entry, String userId) throws
OAuthProblemException;
}
Modified:
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/core/oauth/OAuthAuthenticationHanderTest.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/core/oauth/OAuthAuthenticationHanderTest.java?rev=758949&r1=758948&r2=758949&view=diff
==============================================================================
---
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/core/oauth/OAuthAuthenticationHanderTest.java
(original)
+++
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/core/oauth/OAuthAuthenticationHanderTest.java
Fri Mar 27 00:58:35 2009
@@ -20,6 +20,7 @@
import net.oauth.OAuth;
import net.oauth.OAuthConsumer;
import net.oauth.OAuthServiceProvider;
+import net.oauth.OAuthProblemException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
@@ -92,17 +93,25 @@
}
private void expectConsumer() {
- EasyMock.expect(mockStore.getConsumer(
- EasyMock.eq(FakeOAuthRequest.CONSUMER_KEY))).
- andReturn(new OAuthConsumer(null, FakeOAuthRequest.CONSUMER_KEY,
+ try {
+ EasyMock.expect(mockStore.getConsumer(
+ EasyMock.eq(FakeOAuthRequest.CONSUMER_KEY))).
+ andReturn(new OAuthConsumer(null, FakeOAuthRequest.CONSUMER_KEY,
FakeOAuthRequest.CONSUMER_SECRET, new OAuthServiceProvider(null,
null, null)))
- .anyTimes();
+ .anyTimes();
+ } catch (OAuthProblemException e) {
+
+ }
}
private void expectSecurityToken() {
- EasyMock.expect(mockStore.getSecurityTokenForConsumerRequest(
- EasyMock.eq(FakeOAuthRequest.CONSUMER_KEY),
EasyMock.eq(FakeOAuthRequest.REQUESTOR))).
- andReturn(new AnonymousSecurityToken());
+ try {
+ EasyMock.expect(mockStore.getSecurityTokenForConsumerRequest(
+ EasyMock.eq(FakeOAuthRequest.CONSUMER_KEY),
EasyMock.eq(FakeOAuthRequest.REQUESTOR))).
+ andReturn(new AnonymousSecurityToken());
+ } catch (OAuthProblemException e) {
+
+ }
}
@Test