Author: [email protected]
Date: Mon Jul 11 10:09:34 2011
New Revision: 1210

Log:
[AMDATUAUTH-43] Added fixes to prevent session fixation attacks. 
oauth_verifier, oauth_callback and oauth_callback_confirmed parameter handling 
has been added according to the Revision A spec of 1.0.

Removed:
   
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthPluggableValidator.java
Modified:
   
trunk/amdatu-auth/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/OAuthServiceConsumerClient.java
   
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/OAuthTokenProvider.java
   
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthServerConfiguration.java
   
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthServerUtil.java
   
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthTokenProviderImpl.java
   
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/servlet/OAuthAccessTokenServletImpl.java
   
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/servlet/OAuthAuthorizeTokenServletImpl.java
   
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/servlet/OAuthRequestTokenServletImpl.java
   
trunk/amdatu-auth/test-integration/tests/src/test/java/org/amdatu/auth/test/integration/tests/AuthTest.java
   
trunk/amdatu-auth/test-integration/tests/src/test/java/org/amdatu/auth/test/integration/tests/OAuthThreeLeggedTest.java
   
trunk/amdatu-auth/test-integration/tests/src/test/java/org/amdatu/auth/test/integration/tests/OAuthTwoLeggedTest.java

Modified: 
trunk/amdatu-auth/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/OAuthServiceConsumerClient.java
==============================================================================
--- 
trunk/amdatu-auth/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/OAuthServiceConsumerClient.java
 (original)
+++ 
trunk/amdatu-auth/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/OAuthServiceConsumerClient.java
 Mon Jul 11 10:09:34 2011
@@ -18,8 +18,10 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -282,6 +284,18 @@
         }
     }
     
+    public String getVerifier(String callbackURL) throws MalformedURLException 
{
+        URL uri = new URL(callbackURL);
+        String args = uri.getQuery();
+        String[] qp = args.split("&");
+        for (String q : qp) {
+            if (q.split("=")[0].equals(OAuth.OAUTH_VERIFIER)) {
+                return q.split("=")[1];
+            }
+        }
+        return null;
+    }
+    
     public OAuthMessage invoke(OAuthHttpRequest httpRequest) throws 
OAuthException {
         OAuthAccessor accessor = httpRequest.getAccessor();
         String httpMethod = httpRequest.getHttpMethod();

Modified: 
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/OAuthTokenProvider.java
==============================================================================
--- 
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/OAuthTokenProvider.java
 (original)
+++ 
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/OAuthTokenProvider.java
 Mon Jul 11 10:09:34 2011
@@ -56,6 +56,16 @@
     String LAST_USED_TIMESTAMP_PROPERTY = "oauth_last_used";
 
     /**
+     * Indicates the callback URL associated with this request token.
+     */
+    String CALLBACK_URL_PROPERTY = "oauth_callback";
+    
+    /**
+     * Indicates the oauth_verifier associated with this request token.
+     */
+    String VERIFIER_PROPERTY = "oauth_verifier";
+    
+    /**
      * Indicates a request token.
      */
     String REQUEST_TOKEN_TYPE = "request";
@@ -147,14 +157,30 @@
      *         In case any exception occurred
      */
     void markAsAuthorized(Token token, String userId) throws OAuthException;
+    
+    /**
+     * Generates a new oath verifier, which is just a nonce. The nonce is 
associated with the 
+     * request token and also returned as additional query parameter in the 
callback URL. From the callback
+     * URL the consumer receives the oauth_verifier and sends it along with 
the exchange request for access 
+     * token request. The OAuth server receives the request token and verifier 
and verifies that the 
+     * provided verifier matches the verifier stored with the request token. 
This makes sure that the 
+     * user who authorized the request is the same as the one initiated the 
OAuth dance (preventing session
+     * fixation attacks).
+     * @param token The request token
+     * @return a newly generated verifier
+     * @throws OAuthException
+     */
+    String generateVerifier(Token token) throws OAuthException;
 
     /**
      * Exchange the request token for an access token. This call is typically 
invoked after a request token
      * has been authorized, however this method does not validate that. The 
token servlets are supposed to
      * perform all token validations.
+     * @param token The request token to exchange
+     * @param verifier The oauth_verifier provided by the service provider 
when the token was authorized
      * 
      * @throws OAuthException
      *         In case the oAuth token stored in the accessor is invalid.
      */
-    Token exchangeForAccessToken(Token token) throws OAuthException;
+    Token exchangeForAccessToken(Token token, String verifier) throws 
OAuthException;
 }

Modified: 
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthServerConfiguration.java
==============================================================================
--- 
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthServerConfiguration.java
   (original)
+++ 
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthServerConfiguration.java
   Mon Jul 11 10:09:34 2011
@@ -15,18 +15,52 @@
  */
 package org.amdatu.authentication.oauth.server.service;
 
+/**
+ * Provides the OAuth server configuration. This interface is not published as 
it should
+ * only be used internally by services of this bundle.
+ * 
+ * @author ivol
+ */
 public interface OAuthServerConfiguration {
+    /**
+     * Returns the hostname of the OAuth server.
+     * @return the hostname of the OAuth server.
+     */
     String getHostname();
 
+    /**
+     * Returns the portnr of the OAuth server.
+     * @return the portnr of the OAuth server.
+     */
     String getPortNr();
     
+    /**
+     * Returns the URL of the authorization process.
+     * @return the URL of the authorization process.
+     */
     String getAuthorizeUrl();
 
+    /**
+     * Returns the maximum age of request timestamps.
+     * @return the maximum age of request timestamps.
+     */
     long getRequestTimestampMaxAge();
 
+    /**
+     * Returns the maximum age of request tokens.
+     * @return the maximum age of request tokens.
+     */
     long getRequestTokenMaxAge();
 
+    /**
+     * Returns the maximum age of access tokens.
+     * @return the maximum age of access tokens.
+     */
     long getAccessTokenMaxAge();
 
+    /**
+     * Returns the timeout of access tokens.
+     * @return the timeout of access tokens.
+     */
     long getAccessTokenTimeout();
 }

Modified: 
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthServerUtil.java
==============================================================================
--- 
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthServerUtil.java
    (original)
+++ 
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthServerUtil.java
    Mon Jul 11 10:09:34 2011
@@ -42,7 +42,7 @@
         realm += request.getLocalName();
         OAuthServlet.handleException(response, e, realm, sendBody);
     }
-    
+
     public static OAuthConsumer copy(final OAuthServiceConsumer 
serviceConsumer, OAuthServiceProvider serviceProvider) {
         String name = serviceConsumer.getName();
         String callbackUrl = serviceConsumer.getCallbackUrl();
@@ -57,15 +57,35 @@
         return consumer;
     }
 
+    public static OAuthProblemException createException(String problem, String 
reason) {
+        OAuthProblemException e = new OAuthProblemException(problem);
+        e.setParameter("reason", reason);
+        return e;
+    }
+
+    public static OAuthProblemException createException(String problem, String 
reason, Exception e) {
+        OAuthProblemException exc = createException(problem, reason);
+        exc.setStackTrace(e.getStackTrace());
+        return exc;
+    }
+
     public static OAuthProblemException createException(Exception e, 
OAuthMessage requestMessage) {
+        return createException(e, requestMessage, null);
+    }
+
+    public static OAuthProblemException createException(Exception e, 
OAuthMessage requestMessage, String msg) {
         OAuthProblemException exc = new OAuthProblemException(e.toString());
         exc.setParameter("method", requestMessage.method);
         exc.setParameter("URL", requestMessage.URL);
+        if (msg != null) {
+            exc.setParameter("reason", msg);
+        }
         try {
             exc.setParameter("parameters", requestMessage.getParameters());
         }
-        catch (IOException e1) {}
-        exc.fillInStackTrace();
+        catch (IOException e1) {
+            exc.setStackTrace(e1.getStackTrace());
+        }
         return exc;
     }
 }

Modified: 
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthTokenProviderImpl.java
==============================================================================
--- 
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthTokenProviderImpl.java
     (original)
+++ 
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/service/OAuthTokenProviderImpl.java
     Mon Jul 11 10:09:34 2011
@@ -79,33 +79,45 @@
             // try to load from local cache if not throw exception
             String consumerKey = requestMessage.getConsumerKey();
             if (consumerKey == null || "".equals(consumerKey)) {
-                throw new 
OAuthProblemException(OAuth.Problems.CONSUMER_KEY_REJECTED);
+                String msg = "No oauth_consumer parameter send along with the 
OAuth request";
+                throw 
OAuthServerUtil.createException(OAuth.Problems.CONSUMER_KEY_REJECTED, msg);
             }
-            OAuthServiceConsumer serviceConsumer = 
m_consumerRegistry.getConsumer(consumerKey);
-            if (serviceConsumer == null) {
-                throw new 
OAuthProblemException(OAuth.Problems.CONSUMER_KEY_UNKNOWN);
+            try {
+                OAuthServiceConsumer serviceConsumer = 
m_consumerRegistry.getConsumer(consumerKey);
+                if (serviceConsumer == null) {
+                    String msg =
+                        "The oauth_consumer with key '" + consumerKey + "' 
does not exist in the consumer registry";
+                    throw 
OAuthServerUtil.createException(OAuth.Problems.CONSUMER_KEY_UNKNOWN, msg);
+                }
+                return OAuthServerUtil.copy(serviceConsumer, 
m_serviceProvider);
+            }
+            catch (ConsumerRegistryStorageException e) {
+                String msg =
+                    "Could not load oauth_consumer with key '" + 
requestMessage.getConsumerKey()
+                        + "' from the consumer registry";
+                throw OAuthServerUtil.createException(e, requestMessage, msg);
             }
-            return OAuthServerUtil.copy(serviceConsumer, m_serviceProvider);
-        }
-        catch (ConsumerRegistryStorageException e) {
-            throw OAuthServerUtil.createException(e, requestMessage);
         }
         catch (IOException e) {
-            throw OAuthServerUtil.createException(e, requestMessage);
+            String msg = "Could not load oauth_consumer from the consumer 
registry";
+            throw OAuthServerUtil.createException(e, requestMessage, msg);
         }
     }
 
     public synchronized OAuthConsumer getConsumer(final Token token) throws 
OAuthException {
+        String consumerKey = 
token.getProperty(OAuthTokenProvider.CONSUMER_PROPERTY);
         try {
-            String consumerKey = 
token.getProperty(OAuthTokenProvider.CONSUMER_PROPERTY);
             OAuthServiceConsumer serviceConsumer = 
m_consumerRegistry.getConsumer(consumerKey);
             if (serviceConsumer == null) {
-                throw new 
OAuthProblemException(OAuth.Problems.CONSUMER_KEY_UNKNOWN);
+                String msg = "The oauth_consumer with key '" + consumerKey + 
"' stored in the request token "
+                    + "does not exist in the consumer registry";
+                throw 
OAuthServerUtil.createException(OAuth.Problems.CONSUMER_KEY_UNKNOWN, msg);
             }
             return OAuthServerUtil.copy(serviceConsumer, m_serviceProvider);
         }
         catch (ConsumerRegistryStorageException e) {
-            throw new OAuthException(e.toString());
+            String msg = "Could not load oauth_consumer with key '" + 
consumerKey + "' from the consumer registry";
+            throw 
OAuthServerUtil.createException(OAuth.Problems.CONSUMER_KEY_UNKNOWN, msg, e);
         }
     }
 
@@ -118,16 +130,20 @@
             }
 
             // Check if the token is not expired in the meantime
-            if 
(REQUEST_TOKEN_TYPE.equals(token.getProperty(TOKEN_TYPE_PROPERTY)) && 
token.isExpired(m_config.getRequestTokenMaxAge())) {
+            if 
(REQUEST_TOKEN_TYPE.equals(token.getProperty(TOKEN_TYPE_PROPERTY))
+                && token.isExpired(m_config.getRequestTokenMaxAge())) {
                 m_tokenStore.removeToken(token);
-                throw new OAuthProblemException(OAuth.Problems.TOKEN_EXPIRED);
-            } else if 
(ACCESS_TOKEN_TYPE.equals(token.getProperty(TOKEN_TYPE_PROPERTY))) {
+                String msg = "The request token is expired (maximum age is " + 
m_config.getRequestTokenMaxAge() + " ms)";
+                throw 
OAuthServerUtil.createException(OAuth.Problems.TOKEN_EXPIRED, msg);
+            }
+            else if 
(ACCESS_TOKEN_TYPE.equals(token.getProperty(TOKEN_TYPE_PROPERTY))) {
                 boolean expired = false;
                 if (token.isExpired(m_config.getAccessTokenMaxAge())) {
                     expired = true;
-                } else if (m_config.getAccessTokenTimeout() >= 0) {
+                }
+                else if (m_config.getAccessTokenTimeout() >= 0) {
                     // Access token timeout is a special case. The timestamp 
is set when the access token is created and
-                    // updated each time the token is used, but when it is not 
used for more then the timeout period, 
+                    // updated each time the token is used, but when it is not 
used for more then the timeout period,
                     // it expires. We store this timestamp in a special 
property.
                     long lastUsed = 
Long.parseLong(token.getProperty(OAuthTokenProvider.LAST_USED_TIMESTAMP_PROPERTY));
                     if (lastUsed < (System.currentTimeMillis() - 
m_config.getAccessTokenTimeout())) {
@@ -136,16 +152,17 @@
                 }
                 if (expired) {
                     m_tokenStore.removeToken(token);
-                    throw new 
OAuthProblemException(OAuth.Problems.TOKEN_EXPIRED);
+                    String msg = "The access token is expired";
+                    throw 
OAuthServerUtil.createException(OAuth.Problems.TOKEN_EXPIRED, msg);
                 }
             }
 
             return token;
         }
         catch (IOException e) {
-            m_logService.log(LogService.LOG_ERROR, "Could not parse request 
token from OAuth request message", e);
+            String msg = "Could not read request or access token from the 
request";
+            throw 
OAuthServerUtil.createException(OAuth.Problems.TOKEN_REJECTED, msg);
         }
-        return null;
     }
 
     public synchronized Token validateOAuthMessage(final OAuthMessage 
requestMessage) throws OAuthException {
@@ -157,19 +174,23 @@
                 String tokenType = 
token.getProperty(OAuthTokenProvider.TOKEN_TYPE_PROPERTY);
                 if (OAuthTokenProvider.REQUEST_TOKEN_TYPE.equals(tokenType)) {
                     accessor.requestToken = token.getToken();
-                } else if 
(OAuthTokenProvider.ACCESS_TOKEN_TYPE.equals(tokenType)) {
+                }
+                else if 
(OAuthTokenProvider.ACCESS_TOKEN_TYPE.equals(tokenType)) {
                     accessor.accessToken = token.getToken();
-                } 
+                }
                 accessor.tokenSecret = token.getTokenSecret();
             }
             m_oAuthValidator.validateMessage(requestMessage, accessor);
+
             return token;
         }
         catch (IOException e) {
-            throw OAuthServerUtil.createException(e, requestMessage);
+            String msg = "Could not validate OAuth message";
+            throw OAuthServerUtil.createException(e, requestMessage, msg);
         }
         catch (URISyntaxException e) {
-            throw OAuthServerUtil.createException(e, requestMessage);
+            String msg = "Could not validate OAuth message";
+            throw OAuthServerUtil.createException(e, requestMessage, msg);
         }
     }
 
@@ -191,7 +212,25 @@
         token.setProperty(OAuthTokenProvider.USERID_PROPERTY, userId);
     }
 
-    public Token exchangeForAccessToken(Token requestToken) throws 
OAuthException {
+    public String generateVerifier(Token token) throws OAuthException {
+        String verifier = generateToken();
+        token.setProperty(OAuthTokenProvider.VERIFIER_PROPERTY, verifier);
+        return verifier;
+    }
+
+    public Token exchangeForAccessToken(Token requestToken, String verifier) 
throws OAuthException {
+        // Verify the oauth_verifier, this check is only applicable for OAuth 
flows in which actually
+        // a token was authorized by a user (so not in case of 2-legged 
OAuth). Hence this validation
+        // is not part of the regular validateOAuthMessage process.
+        if (verifier == null) {
+            String msg =  "The OAuth server did not receive an oauth_verifier";
+            throw 
OAuthServerUtil.createException(OAuth.Problems.OAUTH_PARAMETERS_REJECTED, msg); 
              
+        }
+        if 
(!verifier.equals(requestToken.getProperty(OAuthTokenProvider.VERIFIER_PROPERTY)))
 {
+            String msg = "The OAuth server received an invalid oauth_verifier";
+            
OAuthServerUtil.createException(OAuth.Problems.OAUTH_PARAMETERS_REJECTED, msg);
+        }
+
         // First we generate a new access token
         String token = generateToken();
         String tokenSecret = generateToken();
@@ -202,7 +241,8 @@
             accessToken.setProperty(key, requestToken.getProperty(key));
         }
         accessToken.setProperty(OAuthTokenProvider.TOKEN_TYPE_PROPERTY, 
OAuthTokenProvider.ACCESS_TOKEN_TYPE);
-        
accessToken.setProperty(OAuthTokenProvider.LAST_USED_TIMESTAMP_PROPERTY, new 
Long(System.currentTimeMillis()).toString());
+        
accessToken.setProperty(OAuthTokenProvider.LAST_USED_TIMESTAMP_PROPERTY,
+            new Long(System.currentTimeMillis()).toString());
 
         // Now remove the request token
         m_tokenStore.removeToken(requestToken);
@@ -217,6 +257,7 @@
      * Generates a nonce with default bytesize (32). A nonce is an 
abbreviation of number used once, and is a
      * unique randomly generated number. It is used by authentication 
protocols to ensure that old
      * requests cannot be used in replay attacks.
+     * 
      * @return A random generated nonce.
      */
     private BigInteger generateNonce() {
@@ -227,7 +268,9 @@
      * Generates a nonce with the specified bytesize. A nonce is an 
abbreviation of number used once, and is a
      * unique randomly generated number. It is used by authentication 
protocols to ensure that old
      * requests cannot be used in replay attacks.
-     * @param byteSize the number of bytes from which the nonce is generated
+     * 
+     * @param byteSize
+     *        the number of bytes from which the nonce is generated
      * @return A random generated nonce.
      */
     private BigInteger generateNonce(int byteSize) {
@@ -238,13 +281,14 @@
     }
 
     /**
-     * Generates a unique random token. The token is generated from a 32-bits 
nonce and converted to a String 
+     * Generates a unique random token. The token is generated from a 32-bits 
nonce and converted to a String
      * representation (with numbers 0-9 and letters a-z).
+     * 
      * @return A new randomly generated token.
      */
     private String generateToken() {
         // Generate a nonce and convert it to a String representation (using 
numbers 0-9 and letters a-z)
         BigInteger nonce = generateNonce();
         return nonce.toString(36);
-    }    
+    }
 }

Modified: 
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/servlet/OAuthAccessTokenServletImpl.java
==============================================================================
--- 
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/servlet/OAuthAccessTokenServletImpl.java
        (original)
+++ 
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/servlet/OAuthAccessTokenServletImpl.java
        Mon Jul 11 10:09:34 2011
@@ -25,7 +25,6 @@
 
 import net.oauth.OAuth;
 import net.oauth.OAuthMessage;
-import net.oauth.OAuthProblemException;
 import net.oauth.server.OAuthServlet;
 
 import org.amdatu.authentication.oauth.server.OAuthAccessTokenServlet;
@@ -76,19 +75,24 @@
             
             // Make sure a request token was send along with the request
             if (requestToken == null) {
-                throw new OAuthProblemException(OAuth.Problems.TOKEN_REJECTED);
+                String msg = "The OAuth server did not receive the request 
token in the request "
+                    + "(the oauth_token parameter is missing)";
+                throw 
OAuthServerUtil.createException(OAuth.Problems.TOKEN_REJECTED, msg);
             }
             
             // Validate that this is a request token that was marked as 
authorized
             if 
(!OAuthTokenProvider.REQUEST_TOKEN_TYPE.equals(requestToken.getProperty(OAuthTokenProvider.TOKEN_TYPE_PROPERTY)))
 {
-                throw new OAuthProblemException(OAuth.Problems.TOKEN_REJECTED);
+                String msg = "The token received is not a request token but an 
access token";
+                throw 
OAuthServerUtil.createException(OAuth.Problems.TOKEN_REJECTED, msg);
             }
-            if 
(!"true".equals(requestToken.getProperty(OAuthTokenProvider.TOKEN_AUTHORIZED_PROPERTY)))
 {
-                throw new 
OAuthProblemException(OAuth.Problems.PERMISSION_DENIED);
+            if 
(!"true".equals(requestToken.getProperty(OAuthTokenProvider.TOKEN_AUTHORIZED_PROPERTY)))
 {
+                String msg = "The user did not authorize the service consumer";
+                throw 
OAuthServerUtil.createException(OAuth.Problems.PERMISSION_DENIED, msg);
             }
             
-            // Now exchange the request token for an access token and secret
-            Token accessToken = 
m_tokenProvider.exchangeForAccessToken(requestToken);
+            // Now exchange the request token for an access token and secret
+            String verifier = 
requestMessage.getParameter(OAuth.OAUTH_VERIFIER);  
+            Token accessToken = 
m_tokenProvider.exchangeForAccessToken(requestToken, verifier);
 
             response.setContentType("text/plain");
             OutputStream out = null;

Modified: 
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/servlet/OAuthAuthorizeTokenServletImpl.java
==============================================================================
--- 
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/servlet/OAuthAuthorizeTokenServletImpl.java
     (original)
+++ 
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/servlet/OAuthAuthorizeTokenServletImpl.java
     Mon Jul 11 10:09:34 2011
@@ -13,10 +13,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.amdatu.authentication.oauth.server.servlet;
-
+package org.amdatu.authentication.oauth.server.servlet;
+
 import java.io.IOException;
-import java.io.PrintWriter;
 import java.util.Map;
 
 import javax.servlet.ServletException;
@@ -26,8 +25,8 @@
 
 import net.oauth.OAuth;
 import net.oauth.OAuthConsumer;
+import net.oauth.OAuthException;
 import net.oauth.OAuthMessage;
-import net.oauth.OAuthProblemException;
 import net.oauth.server.OAuthServlet;
 
 import org.amdatu.authentication.oauth.api.OAuthServiceProvider;
@@ -44,151 +43,135 @@
 import org.apache.felix.dm.DependencyManager;
 import org.osgi.framework.Constants;
 import org.osgi.service.log.LogService;
-
-public class OAuthAuthorizeTokenServletImpl extends HttpServlet implements 
OAuthAuthorizeTokenServlet {
-    // The serial version UID of this servlet
-    private static final long serialVersionUID = -3589350956712947896L;
-
-    // Service dependencies, injected by the Felix dependency manager
-    private volatile LogService m_logService;
-    private volatile TokenProvider m_tokenProvider;
-    private volatile OAuthTokenProvider m_oAuthTokenProvider;
-    private volatile OAuthServiceProvider m_serviceProvider;
-    private volatile DependencyManager m_dependencyManager;
-
-    private String m_tenantId;
-
-    public void init(final Component component) {
-        m_tenantId = 
component.getServiceProperties().get(Tenant.TENANT_ID_SERVICEPROPERTY).toString();
-
-        // Create a service dependency on the token provider for 'our' tenant
-        String tenantFilter =
-            "(&(" + Tenant.TENANT_ID_SERVICEPROPERTY + "=" + m_tenantId + ")(" 
+ Constants.OBJECTCLASS
-                + "=" + TokenProvider.class.getName() + "))";
-        component.add(m_dependencyManager.createServiceDependency()
-                .setService(TokenProvider.class, 
tenantFilter).setRequired(true).setInstanceBound(true));
-    }
-
-    public void start() {
-        m_logService.log(LogService.LOG_DEBUG, "OAuth Authorize Token servlet 
started for tenant '" + m_tenantId + "'");
-    }
-
-    @Override
-    public void doGet(final HttpServletRequest request, final 
HttpServletResponse response) throws IOException,
-        ServletException {
-        try {
+
+public class OAuthAuthorizeTokenServletImpl extends HttpServlet implements 
OAuthAuthorizeTokenServlet {
+    // The serial version UID of this servlet
+    private static final long serialVersionUID = -3589350956712947896L;
+
+    // Service dependencies, injected by the Felix dependency manager
+    private volatile LogService m_logService;
+    private volatile TokenProvider m_tokenProvider;
+    private volatile OAuthTokenProvider m_oAuthTokenProvider;
+    private volatile OAuthServiceProvider m_serviceProvider;
+    private volatile DependencyManager m_dependencyManager;
+
+    private String m_tenantId;
+
+    public void init(final Component component) {
+        m_tenantId = 
component.getServiceProperties().get(Tenant.TENANT_ID_SERVICEPROPERTY).toString();
+
+        // Create a service dependency on the token provider for 'our' tenant
+        String tenantFilter =
+            "(&(" + Tenant.TENANT_ID_SERVICEPROPERTY + "=" + m_tenantId + ")(" 
+ Constants.OBJECTCLASS
+                + "=" + TokenProvider.class.getName() + "))";
+        component.add(m_dependencyManager.createServiceDependency()
+                .setService(TokenProvider.class, 
tenantFilter).setRequired(true).setInstanceBound(true));
+    }
+
+    public void start() {
+        m_logService.log(LogService.LOG_DEBUG, "OAuth Authorize Token servlet 
started for tenant '" + m_tenantId + "'");
+    }
+
+    @Override
+    public void doGet(final HttpServletRequest request, final 
HttpServletResponse response) throws IOException,
+        ServletException {
+        try {
             OAuthMessage requestMessage = OAuthServlet.getMessage(request, 
null);
             OAuthConsumer consumer = 
m_oAuthTokenProvider.getConsumer(requestMessage);
             Token token = m_oAuthTokenProvider.getToken(requestMessage);
-            
-            if 
("true".equalsIgnoreCase(token.getProperty(OAuthTokenProvider.TOKEN_AUTHORIZED_PROPERTY)))
 {
-                // already authorized send the user back
-                m_logService.log(LogService.LOG_DEBUG, "Token authorized, 
redirecting user to callback url");
-                returnToConsumer(request, response, token, consumer);
-            }
-            else {
-                m_logService.log(LogService.LOG_DEBUG,
-                    "Authorize token request received, redirecting user to 
authorization page");
-                sendToAuthorizePage(request, response, token, consumer);
-            }
-        }
-        catch (Exception e) {
-            OAuthServerUtil.handleException(e, request, response, true);
-        }
-    }
-
-    @Override
-    public void doPost(final HttpServletRequest request, final 
HttpServletResponse response) throws IOException,
-        ServletException {
-        try {
-            OAuthMessage requestMessage = OAuthServlet.getMessage(request, 
null);
-            String userId = getUserId(request);
-            if (userId == null) {
-                // If there is no user id available now, we throw a permission 
denied as it won't happen
-                // in a normal situation! Maybe it's a hack attempt.
-                OAuthProblemException problem = new 
OAuthProblemException("permission_denied");
-                throw problem;
+
+            if 
("true".equalsIgnoreCase(token.getProperty(OAuthTokenProvider.TOKEN_AUTHORIZED_PROPERTY)))
 {
+                // already authorized send the user back
+                m_logService.log(LogService.LOG_DEBUG, "Token authorized, 
redirecting user to callback url");
+                returnToConsumer(response, token);
+            }
+            else {
+                m_logService.log(LogService.LOG_DEBUG,
+                    "Authorize token request received, redirecting user to 
authorization page");
+                sendToAuthorizePage(request, response, token, consumer);
+            }
+        }
+        catch (Exception e) {
+            OAuthServerUtil.handleException(e, request, response, true);
+        }
+    }
+
+    @Override
+    public void doPost(final HttpServletRequest request, final 
HttpServletResponse response) throws IOException,
+        ServletException {
+        try {
+            OAuthMessage requestMessage = OAuthServlet.getMessage(request, 
null);
+            String userId = getUserId(request);
+            if (userId == null) {
+                // If there is no user id available now, we throw a permission 
denied as it won't happen
+                // in a normal situation! Maybe it's a hack attempt.
+                String msg = "No userid send along with the authorize request";
+                throw 
OAuthServerUtil.createException(OAuth.Problems.PERMISSION_DENIED, msg);
             }
-            
+
             // Retrieve the request token and consumer
             Token token = m_oAuthTokenProvider.getToken(requestMessage);
-            OAuthConsumer consumer = m_oAuthTokenProvider.getConsumer(token);
-            
-            // Now set the userId as property of the request token and mark it 
as authorized
-            m_oAuthTokenProvider.markAsAuthorized(token, userId);
-            returnToConsumer(request, response, token, consumer);
-        }
-        catch (Exception e) {
-            OAuthServerUtil.handleException(e, request, response, true);
-        }
-    }
-
-    private void sendToAuthorizePage(final HttpServletRequest request, final 
HttpServletResponse response,
-        final Token token, final OAuthConsumer consumer)
-        throws IOException, ServletException {
-        String callback = request.getParameter(OAuth.OAUTH_CALLBACK);
-        if (callback == null || callback.length() <= 0) {
-            callback = "none";
-        }
-        String consumerDescription = (String) consumer.getProperty("name");
-        request.setAttribute("CONS_DESC", consumerDescription);
-        request.setAttribute("CALLBACK", callback);
-        request.setAttribute("TOKEN", token.getToken());
-        m_logService.log(LogService.LOG_DEBUG,
-            "Forwarding authorize token request to " + 
m_serviceProvider.getAuthorizeTokenURL()
-                + ", token=" + token.getToken() + ", callback=" + callback);
-
+
+            // Now set the userId as property of the request token and mark it 
as authorized
+            m_oAuthTokenProvider.markAsAuthorized(token, userId);
+            returnToConsumer(response, token);
+        }
+        catch (Exception e) {
+            OAuthServerUtil.handleException(e, request, response, true);
+        }
+    }
+
+    private void sendToAuthorizePage(final HttpServletRequest request, final 
HttpServletResponse response,
+        final Token token, final OAuthConsumer consumer)
+        throws IOException, ServletException {
+        String callback = request.getParameter(OAuth.OAUTH_CALLBACK);
+        if (callback == null || callback.length() <= 0) {
+            callback = "none";
+        }
+        String consumerDescription = (String) consumer.getProperty("name");
+        request.setAttribute("CONS_DESC", consumerDescription);
+        request.setAttribute("CALLBACK", callback);
+        request.setAttribute("TOKEN", token.getToken());
+        m_logService.log(LogService.LOG_DEBUG,
+            "Forwarding authorize token request to " + 
m_serviceProvider.getAuthorizeTokenURL()
+                + ", token=" + token.getToken() + ", callback=" + callback);
+
         // Dispatch the request to the authorize JSP
-        // The authorize URL
-        request.getRequestDispatcher(((OAuthServiceProviderImpl) 
m_serviceProvider).getAuthorizeURL()).forward(request, response);
-    }
-
-    private void returnToConsumer(final HttpServletRequest request,
-        final HttpServletResponse response, final Token token, final 
OAuthConsumer consumer)
-        throws IOException, ServletException {
-        // send the user back to site's callBackUrl
-        String callback = request.getParameter(OAuth.OAUTH_CALLBACK);
-        if ("none".equals(callback)
-            && consumer.callbackURL != null
-            && consumer.callbackURL.length() > 0) {
-            // first check if we have something in our properties file
-            callback = request.getContextPath() + consumer.callbackURL;
-        }
-
-        if ("none".equals(callback)) {
-            // no call back it must be a client
-            response.setContentType("text/plain");
-            PrintWriter out = response.getWriter();
-            out.println("You have successfully authorized '"
-                + consumer.getProperty("description")
-                + "'. Please close this browser window and click continue"
-                + " in the client.");
-            out.close();
-        }
-        else {
-            // if callback is not passed in, use the callback from config
-            if (callback == null || callback.length() <= 0) {
-                callback = request.getContextPath() + consumer.callbackURL;
-            }
-           
-            callback = OAuth.addParameters(callback, OAuth.OAUTH_TOKEN, 
token.getToken());
-
-            // FIXME: we should generate and append an oauth_verifier here!
-            
-            response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
-            response.setHeader("Location", callback);
-        }
-    }
-
-    private String getUserId(final HttpServletRequest request) throws 
TokenProviderException, InvalidTokenException {
-        // Get the token, retrieve attributes stored in it and get the 
USERNAME from it
-        String token = m_tokenProvider.getTokenFromRequest(request);
-        if (token != null) {
-            Map<String, String> attributes = 
m_tokenProvider.verifyToken(token);
-            return attributes.get(TokenProvider.USERNAME);
-        }
-        else {
-            return null;
-        }
-    }
-}
+        // The authorize URL
+        request.getRequestDispatcher(((OAuthServiceProviderImpl) 
m_serviceProvider).getAuthorizeURL()).forward(request,
+            response);
+    }
+
+    private void returnToConsumer(final HttpServletResponse response, final 
Token token) throws IOException,
+        OAuthException {
+        // Send the user back to site's callBackUrl
+        String callback = 
token.getProperty(OAuthTokenProvider.CALLBACK_URL_PROPERTY);
+
+        // FIXME: we should also support OOB mode here (check if the callback 
url equals 'oob')
+        // See http://jira.amdatu.org/jira/browse/AMDATUAUTH-69
+        if ("oob".equalsIgnoreCase(callback)) {
+            String msg = "The current OAuth server version does not implement 
Out Of Band mode";
+            throw 
OAuthServerUtil.createException(OAuth.Problems.PARAMETER_REJECTED, msg);
+        }
+
+        // Now append the oauth token and a new oauth_verifier to the callback 
URL
+        String verifier = m_oAuthTokenProvider.generateVerifier(token);
+        callback = OAuth.addParameters(callback, OAuth.OAUTH_TOKEN, 
token.getToken());
+        callback = OAuth.addParameters(callback, OAuth.OAUTH_VERIFIER, 
verifier);
+
+        response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
+        response.setHeader("Location", callback);
+    }
+
+    private String getUserId(final HttpServletRequest request) throws 
TokenProviderException, InvalidTokenException {
+        // Get the token, retrieve attributes stored in it and get the 
USERNAME from it
+        String token = m_tokenProvider.getTokenFromRequest(request);
+        if (token != null) {
+            Map<String, String> attributes = 
m_tokenProvider.verifyToken(token);
+            return attributes.get(TokenProvider.USERNAME);
+        }
+        else {
+            return null;
+        }
+    }
+}

Modified: 
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/servlet/OAuthRequestTokenServletImpl.java
==============================================================================
--- 
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/servlet/OAuthRequestTokenServletImpl.java
       (original)
+++ 
trunk/amdatu-auth/oauth-server/src/main/java/org/amdatu/authentication/oauth/server/servlet/OAuthRequestTokenServletImpl.java
       Mon Jul 11 10:09:34 2011
@@ -85,8 +85,27 @@
             // and signature)
             m_tokenProvider.validateOAuthMessage(requestMessage);
 
-            // Generate a brand new request token
+            // According to OAuth Core 1.0 Revision A, we must determine the 
callback URL at this moment,
+            // instead of allowing the callback URL to be provided by the 
consumer. So we read the
+            // oauth_callback parameter from the request. If none was send, we 
use the callback URL
+            // defined for the consumer in the consumer registry. If both are 
empty, we throw a
+            // VERSION_REJECTED exception as in that case we would be 
vulnerable to session fixation
+            // attacks, as described on 
http://hueniverse.com/2009/04/explaining-the-oauth-session-fixation-attack/
+            String callback = 
requestMessage.getParameter(OAuth.OAUTH_CALLBACK);
+            if (callback == null || "".equalsIgnoreCase(callback)) {
+                callback = consumer.callbackURL;
+                if (callback == null || "".equalsIgnoreCase(callback)) {
+                    String errorMsg = "The consumer '" + consumer.consumerKey 
+ "' did not send the "
+                        + "oauth_callback parameter (which is required 
according to the OAuth Core 1.0 "
+                        + "Revision A spec) and no callback URL is defined for 
this consumer in "
+                        + "the consumer registry. To prevent session fixation 
attacks providing a "
+                        + "callback URL (while retrieving the request token or 
by defining the "
+                        + "callback URL in the consumer registry for this 
consumer) is required.";
+                    throw 
OAuthServerUtil.createException(OAuth.Problems.VERSION_REJECTED, errorMsg);
+                }
+            }
             Token requestToken = 
m_tokenProvider.generateRequestToken(consumer);
+            requestToken.setProperty(OAuthTokenProvider.CALLBACK_URL_PROPERTY, 
callback);
 
             m_logService.log(LogService.LOG_DEBUG, "Request token '" + 
requestToken.getToken()
                 + "' generated for consumer '" + consumer.consumerKey + "'");

Modified: 
trunk/amdatu-auth/test-integration/tests/src/test/java/org/amdatu/auth/test/integration/tests/AuthTest.java
==============================================================================
--- 
trunk/amdatu-auth/test-integration/tests/src/test/java/org/amdatu/auth/test/integration/tests/AuthTest.java
 (original)
+++ 
trunk/amdatu-auth/test-integration/tests/src/test/java/org/amdatu/auth/test/integration/tests/AuthTest.java
 Mon Jul 11 10:09:34 2011
@@ -28,6 +28,8 @@
 
 import javax.servlet.Servlet;
 
+import net.oauth.OAuthException;
+
 import org.amdatu.auth.test.integration.base.AuthFixture;
 import org.amdatu.auth.test.integration.tests.util.AuthTestBase;
 import org.amdatu.auth.test.integration.tests.util.AuthUtils;
@@ -61,25 +63,25 @@
 
 @RunWith(JUnit4TestRunner.class)
 @ExamReactorStrategy(AllConfinedStagedReactorFactory.class)
-public class AuthTest {    
+public class AuthTest {
     public final static String TEST_USERNAME = "georged";
     public final static String TEST_PASSWORD = "georged";
-    
+
     public final static String ADMIN_USERNAME = "Administrator";
     public final static String ADMIN_PASSWORD = "Administrator";
-    
+
     // Fixtures used by the Auth integration tests
     private CoreFixture m_coreFixture = new CoreFixture();
     private WebFixture m_webFixture = new WebFixture();
     private AuthFixture m_authFixture = new AuthFixture();
-    
+
     private DependencyManager m_dependencyManager;
     private LogService m_logService;
     private OAuthServiceProvider m_oAuthServiceProvider;
     private OAuthServiceConsumerRegistry m_consumerRegistry;
     private UserAdmin m_userAdmin;
     private TenantManagementService m_tenantService;
-    
+
     @Configuration
     public Option[] config() {
         return options(
@@ -92,7 +94,7 @@
     public TestContext testContextSetUp(BundleContext bundleContext) throws 
Exception {
         assertThat(bundleContext, is(notNullValue()));
         TestContext testContext = new TestContext(bundleContext);
-        
+
         // FIXME quickfix to let startlevel complete to
         // prevent felix bundle locking issues
         Thread.sleep(1000);
@@ -107,7 +109,7 @@
 
         return testContext;
     }
-    
+
     // FIXME: [AMDATU-379] This method is here since TestContext.getService 
doesn't (always) work.
     // For optimal performance we do this in 3 steps:
     // 1. Try to get the service directly using getAllServiceReferences, 
return it if available
@@ -120,19 +122,19 @@
         if (servRef != null && servRef.length > 0) {
             return (T) 
bundleContext.getService(getServiceRefWithHighestRank(servRef));
         }
-        
+
         T service = testContext.getService(clazz);
         if (service != null) {
             return service;
         }
-       
+
         servRef = bundleContext.getAllServiceReferences(clazz.getName(), null);
         if (servRef != null && servRef.length > 0) {
             return (T) 
bundleContext.getService(getServiceRefWithHighestRank(servRef));
         }
         return null;
     }
-    
+
     private ServiceReference getServiceRefWithHighestRank(ServiceReference[] 
servRefs) {
         int maxRank = -1;
         if (servRefs.length == 1) {
@@ -144,9 +146,11 @@
             int rank;
             if (prop == null) {
                 rank = 0;
-            } else if (prop instanceof Integer) {
+            }
+            else if (prop instanceof Integer) {
                 rank = (Integer) 
servRef.getProperty(Constants.SERVICE_RANKING);
-            } else {
+            }
+            else {
                 rank = 
Integer.parseInt(servRef.getProperty(Constants.SERVICE_RANKING).toString());
             }
             if (rank >= maxRank) {
@@ -156,7 +160,7 @@
         }
         return maxServRef;
     }
-    
+
     private <T> T assertAvailable(TestContext testContext, Class<T> 
serviceClass) throws Exception {
         T service = getService(testContext, serviceClass);
         assertThat("Expected a " + serviceClass.getName(), service, 
is(notNullValue()));
@@ -167,10 +171,10 @@
     public void runTest(BundleContext bundleContext) throws Exception {
         // Setup test context
         TestContext testContext = testContextSetUp(bundleContext);
-        
+
         // Create the dependency manager
         m_dependencyManager = new 
DependencyManager(testContext.getBundleContext());
-        
+
         // Initialize services
         m_logService = assertAvailable(testContext, LogService.class);
         assertAvailable(testContext, OAuthRequestTokenServlet.class);
@@ -178,47 +182,60 @@
         assertAvailable(testContext, OAuthAccessTokenServlet.class);
         m_consumerRegistry = assertAvailable(testContext, 
OAuthServiceConsumerRegistry.class);
         assertAvailable(testContext, HttpService.class);
-        m_userAdmin =  assertAvailable(testContext, UserAdmin.class);
+        m_userAdmin = assertAvailable(testContext, UserAdmin.class);
         m_oAuthServiceProvider = assertAvailable(testContext, 
OAuthServiceProvider.class);
         m_tenantService = assertAvailable(testContext, 
TenantManagementService.class);
-            
+
         // Register an oAuth protected test servlet we need during the tests
         registerTestResource();
-        
+
         // Wait for the oAuth servlets to become available
         waitForOAuthServlets();
-        
+
         // Execute the tests
-        test(OAuthServiceConsumerRegistryTest.class);
-        test(OAuthSignedRequestsTest.class);
-        test(OAuthThreeLeggedTest.class);
-        test(OAuthTwoLeggedTest.class);
-        test(UserAdminRESTTest.class);
-        
+        try {
+            test(OAuthServiceConsumerRegistryTest.class);
+            test(OAuthSignedRequestsTest.class);
+            test(OAuthThreeLeggedTest.class);
+            test(OAuthTwoLeggedTest.class);
+            test(UserAdminRESTTest.class);
+        }
+        catch (OAuthException e) {
+            System.out.println(e.toString());
+            e.printStackTrace();
+            throw e;
+        }
+
         // And we are done
         testContext.tearDown();
     }
-    
+
     private void registerTestResource() {
         // Now register a test servlet
         OAuthProtectedTestServlet m_testServlet = new 
OAuthProtectedTestServlet();
         Dictionary<String, String> servletProperties = new Hashtable<String, 
String>();
         servletProperties.put("alias", 
OAuthProtectedTestServlet.SERVLET_ALIAS);
-        Component servletComponent = m_dependencyManager.createComponent()
-        .setImplementation(m_testServlet)
-        .setInterface(new String[] { Servlet.class.getName() }, 
servletProperties)
-        
.add(m_dependencyManager.createServiceDependency().setService(LogService.class).setRequired(true))
-        
.add(m_dependencyManager.createServiceDependency().setService(OAuthServiceConsumerRegistry.class).setRequired(true))
-        
.add(m_dependencyManager.createServiceDependency().setService(OAuthTokenProvider.class).setRequired(true));
+        Component servletComponent =
+            m_dependencyManager
+                .createComponent()
+                .setImplementation(m_testServlet)
+                .setInterface(new String[] {Servlet.class.getName()}, 
servletProperties)
+                
.add(m_dependencyManager.createServiceDependency().setService(LogService.class).setRequired(true))
+                .add(
+                    
m_dependencyManager.createServiceDependency().setService(OAuthServiceConsumerRegistry.class)
+                        .setRequired(true))
+                .add(
+                    
m_dependencyManager.createServiceDependency().setService(OAuthTokenProvider.class)
+                        .setRequired(true));
         m_dependencyManager.add(servletComponent);
     }
-    
+
     private <T extends AuthTestBase> void test(Class<T> testClass) throws 
Exception {
         T test = testClass.newInstance();
         init(test);
         test.execute();
     }
-    
+
     private void init(AuthTestBase test) {
         test.setLogService(m_logService);
         test.setUserAdmin(m_userAdmin);
@@ -226,7 +243,7 @@
         test.setOAuthServiceConsumerRegistry(m_consumerRegistry);
         test.setTenantService(m_tenantService);
     }
-    
+
     protected void waitForOAuthServlets() throws MalformedURLException, 
IOException {
         // First wait for the request servlet to become available
         m_logService.log(LogService.LOG_DEBUG, "Waiting for '" + 
m_oAuthServiceProvider.getRequestTokenURL()

Modified: 
trunk/amdatu-auth/test-integration/tests/src/test/java/org/amdatu/auth/test/integration/tests/OAuthThreeLeggedTest.java
==============================================================================
--- 
trunk/amdatu-auth/test-integration/tests/src/test/java/org/amdatu/auth/test/integration/tests/OAuthThreeLeggedTest.java
     (original)
+++ 
trunk/amdatu-auth/test-integration/tests/src/test/java/org/amdatu/auth/test/integration/tests/OAuthThreeLeggedTest.java
     Mon Jul 11 10:09:34 2011
@@ -18,6 +18,7 @@
 import static 
org.amdatu.auth.test.integration.tests.util.OAuthProtectedTestServlet.OAUTH_TYPE_PARAM;
 import static 
org.amdatu.auth.test.integration.tests.util.OAuthProtectedTestServlet.OAUTH_TYPE_THREE_LEGGED;
 import junit.framework.Assert;
+import net.oauth.OAuth;
 import net.oauth.OAuthMessage;
 
 import org.amdatu.auth.test.integration.base.AuthFixture;
@@ -75,6 +76,8 @@
 
         // Step 6: Exchange our request token for an access token
         m_logService.log(LogService.LOG_DEBUG, "*** Step 6: Get access token 
***");
+        String verifier = consumerClient.getVerifier(callback);
+        accessor.setProperty(OAuth.OAUTH_VERIFIER, verifier);
         OAuthMessage message = 
consumerClient.exchangeRequestTokenForAccessToken(accessor);
         accessor.accessToken = message.getToken();
         accessor.tokenSecret = message.getParameter("oauth_token_secret");

Modified: 
trunk/amdatu-auth/test-integration/tests/src/test/java/org/amdatu/auth/test/integration/tests/OAuthTwoLeggedTest.java
==============================================================================
--- 
trunk/amdatu-auth/test-integration/tests/src/test/java/org/amdatu/auth/test/integration/tests/OAuthTwoLeggedTest.java
       (original)
+++ 
trunk/amdatu-auth/test-integration/tests/src/test/java/org/amdatu/auth/test/integration/tests/OAuthTwoLeggedTest.java
       Mon Jul 11 10:09:34 2011
@@ -69,10 +69,12 @@
 
         // Step 3d: Authorize the request token for a user we define
         m_logService.log(LogService.LOG_DEBUG, "*** Step 3d: Authorize the 
request token ***");
-        userClient.authorizeToken(accessor, getCookieHeader());
-
+        String callbackURL = userClient.authorizeToken(accessor, 
getCookieHeader());
+        String verifier = consumerClient.getVerifier(callbackURL);
+        
         // Step 3e: Exchange our request token for an access token
         m_logService.log(LogService.LOG_DEBUG, "*** Step 3e: Get access token 
***");
+        accessor.setProperty(OAuth.OAUTH_VERIFIER, verifier);
         OAuthMessage message = 
consumerClient.exchangeRequestTokenForAccessToken(accessor);
         accessor.accessToken = message.getToken();
         accessor.tokenSecret = message.getParameter(OAuth.OAUTH_TOKEN_SECRET);
_______________________________________________
Amdatu-commits mailing list
[email protected]
http://lists.amdatu.org/mailman/listinfo/amdatu-commits

Reply via email to