You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2012/07/24 18:21:08 UTC

svn commit: r1365160 - in /cxf/trunk/rt/rs/security/oauth-parent/oauth2: ./ src/main/java/org/apache/cxf/rs/security/oauth2/client/ src/main/java/org/apache/cxf/rs/security/oauth2/common/ src/main/java/org/apache/cxf/rs/security/oauth2/filters/ src/mai...

Author: sergeyb
Date: Tue Jul 24 16:21:07 2012
New Revision: 1365160

URL: http://svn.apache.org/viewvc?rev=1365160&view=rev
Log:
[CXF-4431] Initial OAuth2 MAC token support, applying a modified patch from Sasi M - thanks

Added:
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/HttpRequestProperties.java   (with props)
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/HmacAlgorithm.java   (with props)
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/HmacUtils.java   (with props)
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/MacAccessToken.java   (with props)
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/MacAccessTokenValidator.java   (with props)
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/MacAuthorizationScheme.java   (with props)
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceVerifier.java   (with props)
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/token/
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/token/mac/
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/token/mac/MacAccessTokenValidatorTest.java   (with props)
Modified:
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/pom.xml
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/OAuthClientUtils.java
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessToken.java
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/ClientAccessToken.java
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/filters/AccessTokenValidatorClient.java
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AccessTokenValidator.java
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OAuthJSONProvider.java
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AbstractAccessTokenValidator.java
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AccessTokenService.java
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthConstants.java
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/OAuthJSONProviderTest.java

Modified: cxf/trunk/rt/rs/security/oauth-parent/oauth2/pom.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/pom.xml?rev=1365160&r1=1365159&r2=1365160&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/pom.xml (original)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/pom.xml Tue Jul 24 16:21:07 2012
@@ -53,6 +53,11 @@
             <artifactId>junit</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+            <scope>test</scope>
+        </dependency>  
     </dependencies>
     
 </project>

Added: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/HttpRequestProperties.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/HttpRequestProperties.java?rev=1365160&view=auto
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/HttpRequestProperties.java (added)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/HttpRequestProperties.java Tue Jul 24 16:21:07 2012
@@ -0,0 +1,71 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.rs.security.oauth2.client;
+
+import java.net.URI;
+
+import org.apache.cxf.jaxrs.client.WebClient;
+
+public class HttpRequestProperties {
+
+    private String hostName;
+    private int port;
+    private String httpMethod;
+    private String requestPath;
+    private String requestQuery;
+     
+    public HttpRequestProperties(WebClient wc, String httpMethod) {
+        this(wc.getCurrentURI(), httpMethod);
+    }
+    
+    public HttpRequestProperties(URI uri, String httpMethod) {
+        this(uri.getHost(), uri.getPort(), httpMethod,
+             uri.getRawPath(), uri.getRawQuery());
+    }
+    
+    public HttpRequestProperties(String hostName, int port, String httpMethod, String requestPath) {
+        this(hostName, port, httpMethod, requestPath, null);
+    }
+    
+    public HttpRequestProperties(String hostName, int port, String httpMethod, 
+                                 String requestPath, String requestQuery) {
+        this.requestPath = requestPath;
+        this.hostName = hostName;
+        this.port = port;
+        this.httpMethod = httpMethod;
+    }
+    
+    public String getRequestPath() {
+        return requestPath;
+    }
+    
+    public String getRequestQuery() {
+        return requestQuery;
+    }
+
+    public String getHostName() {
+        return hostName;
+    }
+    public int getPort() {
+        return port;
+    }
+    public String getHttpMethod() {
+        return httpMethod;
+    }
+}
\ No newline at end of file

Propchange: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/HttpRequestProperties.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/HttpRequestProperties.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/OAuthClientUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/OAuthClientUtils.java?rev=1365160&r1=1365159&r2=1365160&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/OAuthClientUtils.java (original)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/OAuthClientUtils.java Tue Jul 24 16:21:07 2012
@@ -36,6 +36,7 @@ import org.apache.cxf.rs.security.oauth2
 import org.apache.cxf.rs.security.oauth2.common.OAuthError;
 import org.apache.cxf.rs.security.oauth2.provider.OAuthJSONProvider;
 import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
+import org.apache.cxf.rs.security.oauth2.tokens.mac.MacAuthorizationScheme;
 import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
 
 /**
@@ -225,7 +226,7 @@ public final class OAuthClientUtils {
     }
     
     /**
-     * Creates OAuth Authorization header for accessing the end user's resources
+     * Creates OAuth Authorization header with Bearer scheme
      * @param consumer represents the registered client
      * @param accessToken the access token  
      * @return the header value
@@ -234,21 +235,46 @@ public final class OAuthClientUtils {
                                                    ClientAccessToken accessToken)
         throws OAuthServiceException {
         StringBuilder sb = new StringBuilder();
-        appendTokenData(sb, accessToken);  
+        appendTokenData(sb, accessToken, null);  
         return sb.toString();
     }
     
-
-    private static void appendTokenData(StringBuilder sb, ClientAccessToken token) 
+    /**
+     * Creates OAuth Authorization header with the scheme that
+     * may require an access to the current HTTP request properties
+     * @param consumer represents the registered client
+     * @param accessToken the access token  
+     * @param httpProps http request properties, can be null for Bearer tokens
+     * @return the header value
+     */
+    public static String createAuthorizationHeader(Consumer consumer,
+                                                   ClientAccessToken accessToken,
+                                                   HttpRequestProperties httpProps)
+        throws OAuthServiceException {
+        StringBuilder sb = new StringBuilder();
+        appendTokenData(sb, accessToken, httpProps);  
+        return sb.toString();
+    }
+    
+    private static void appendTokenData(StringBuilder sb, 
+                                        ClientAccessToken token,
+                                        HttpRequestProperties httpProps) 
         throws OAuthServiceException {
         // this should all be handled by token specific serializers
         if (OAuthConstants.BEARER_TOKEN_TYPE.equals(token.getTokenType())) {
             sb.append(OAuthConstants.BEARER_AUTHORIZATION_SCHEME);
             sb.append(" ");
             sb.append(token.getTokenKey());
+        } else if (OAuthConstants.MAC_TOKEN_TYPE.equals(token.getTokenType())) {
+            if (httpProps == null) {
+                throw new IllegalArgumentException("MAC scheme requires HTTP Request properties");
+            }
+            MacAuthorizationScheme macAuthData = new MacAuthorizationScheme(httpProps, token);
+            String macAlgo = token.getParameters().get(OAuthConstants.MAC_TOKEN_ALGORITHM);
+            String macSecret = token.getParameters().get(OAuthConstants.MAC_TOKEN_SECRET);
+            sb.append(macAuthData.toAuthorizationHeader(macAlgo, macSecret));
         } else {
-            // deal with MAC and other tokens
-            throw new OAuthServiceException("Unsupported token type");
+            throw new ClientWebApplicationException(new OAuthServiceException("Unsupported token type"));
         }
         
     }

Modified: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessToken.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessToken.java?rev=1365160&r1=1365159&r2=1365160&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessToken.java (original)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessToken.java Tue Jul 24 16:21:07 2012
@@ -18,7 +18,7 @@
  */
 package org.apache.cxf.rs.security.oauth2.common;
 
-import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.Map;
 
 /**
@@ -28,7 +28,9 @@ public abstract class AccessToken {
 
     private String tokenKey;
     private String tokenType;
-    private Map<String, String> parameters = Collections.emptyMap();
+    private String refreshToken;
+    
+    private Map<String, String> parameters = new LinkedHashMap<String, String>();
     
     protected AccessToken(String tokenType, String tokenKey) {
         this.tokenType = tokenType;
@@ -52,6 +54,24 @@ public abstract class AccessToken {
     }
 
     /**
+     * Sets the refresh token key the client can use to obtain a new
+     * access token
+     * @param refreshToken the refresh token
+     */
+    public void setRefreshToken(String refreshToken) {
+        this.refreshToken = refreshToken;
+    }
+
+    /**
+     * Gets the refresh token key the client can use to obtain a new
+     * access token
+     * @return the refresh token
+     */
+    public String getRefreshToken() {
+        return refreshToken;
+    }
+    
+    /**
      * Sets token parameters
      * @param parameters the token parameters
      */

Modified: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/ClientAccessToken.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/ClientAccessToken.java?rev=1365160&r1=1365159&r2=1365160&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/ClientAccessToken.java (original)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/ClientAccessToken.java Tue Jul 24 16:21:07 2012
@@ -29,7 +29,6 @@ package org.apache.cxf.rs.security.oauth
 public class ClientAccessToken extends AccessToken {
 
     private String scope;
-    private String rToken;
     private long expiresIn = -1;
     
     public ClientAccessToken(String tokenType, String tokenKey) {
@@ -54,23 +53,7 @@ public class ClientAccessToken extends A
         return scope;
     }
 
-    /**
-     * Sets the refresh token key the client can use to obtain a new
-     * access token
-     * @param refreshToken the refresh token
-     */
-    public void setRefreshToken(String refreshToken) {
-        this.rToken = refreshToken;
-    }
-
-    /**
-     * Gets the refresh token key the client can use to obtain a new
-     * access token
-     * @return the refresh token
-     */
-    public String getRefreshToken() {
-        return rToken;
-    }
+    
 
     /**
      * The token lifetime

Modified: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/filters/AccessTokenValidatorClient.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/filters/AccessTokenValidatorClient.java?rev=1365160&r1=1365159&r2=1365160&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/filters/AccessTokenValidatorClient.java (original)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/filters/AccessTokenValidatorClient.java Tue Jul 24 16:21:07 2012
@@ -24,6 +24,7 @@ import java.util.List;
 import javax.ws.rs.core.HttpHeaders;
 
 import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.jaxrs.ext.MessageContext;
 import org.apache.cxf.rs.security.oauth2.common.AccessTokenValidation;
 import org.apache.cxf.rs.security.oauth2.provider.AccessTokenValidator;
 import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
@@ -37,7 +38,9 @@ public class AccessTokenValidatorClient 
         return Collections.singletonList(OAuthConstants.ALL_AUTH_SCHEMES);
     }
 
-    public AccessTokenValidation validateAccessToken(String authScheme, String authSchemeData) 
+    public AccessTokenValidation validateAccessToken(MessageContext mc,
+                                                     String authScheme, 
+                                                     String authSchemeData) 
         throws OAuthServiceException {
         WebClient client = WebClient.fromClient(tokenValidatorClient, true);
         client.header(HttpHeaders.AUTHORIZATION, authScheme + " " + authSchemeData);

Modified: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AccessTokenValidator.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AccessTokenValidator.java?rev=1365160&r1=1365159&r2=1365160&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AccessTokenValidator.java (original)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AccessTokenValidator.java Tue Jul 24 16:21:07 2012
@@ -21,10 +21,13 @@ package org.apache.cxf.rs.security.oauth
 
 import java.util.List;
 
+import org.apache.cxf.jaxrs.ext.MessageContext;
 import org.apache.cxf.rs.security.oauth2.common.AccessTokenValidation;
 
 public interface AccessTokenValidator {
     List<String> getSupportedAuthorizationSchemes();
-    AccessTokenValidation validateAccessToken(String authScheme, String authSchemeData)
+    AccessTokenValidation validateAccessToken(MessageContext mc,
+                                              String authScheme, 
+                                              String authSchemeData)
         throws OAuthServiceException;
 }

Modified: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OAuthJSONProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OAuthJSONProvider.java?rev=1365160&r1=1365159&r2=1365160&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OAuthJSONProvider.java (original)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OAuthJSONProvider.java Tue Jul 24 16:21:07 2012
@@ -24,7 +24,7 @@ import java.io.OutputStream;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
 import java.util.Collections;
-import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.Map;
 
 import javax.ws.rs.Consumes;
@@ -160,7 +160,7 @@ public class OAuthJSONProvider implement
         if (!str.startsWith("{") || !str.endsWith("}")) {
             throw new ClientWebApplicationException("JSON Sequence is broken");
         }
-        Map<String, String> map = new HashMap<String, String>();
+        Map<String, String> map = new LinkedHashMap<String, String>();
         
         str = str.substring(1, str.length() - 1).trim();
         String[] jsonPairs = str.split(",");

Modified: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AbstractAccessTokenValidator.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AbstractAccessTokenValidator.java?rev=1365160&r1=1365159&r2=1365160&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AbstractAccessTokenValidator.java (original)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AbstractAccessTokenValidator.java Tue Jul 24 16:21:07 2012
@@ -103,7 +103,7 @@ public abstract class AbstractAccessToke
         if (handler != null) {
             try {
                 // Convert the HTTP Authorization scheme data into a token
-                accessTokenV = handler.validateAccessToken(authScheme, authSchemeData);
+                accessTokenV = handler.validateAccessToken(mc, authScheme, authSchemeData);
             } catch (OAuthServiceException ex) {
                 AuthorizationUtils.throwAuthorizationFailure(
                     Collections.singleton(authScheme));
@@ -136,9 +136,5 @@ public abstract class AbstractAccessToke
         return accessTokenV;
     }
     
-    @Deprecated
-    public void setGrantHandlers(List<AccessTokenValidator> validators) {
-        setTokenValidators(validators);
-    }
     
 }

Modified: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AccessTokenService.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AccessTokenService.java?rev=1365160&r1=1365159&r2=1365160&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AccessTokenService.java (original)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AccessTokenService.java Tue Jul 24 16:21:07 2012
@@ -108,6 +108,7 @@ public class AccessTokenService extends 
         // Extract the information to be of use for the client
         ClientAccessToken clientToken = new ClientAccessToken(serverToken.getTokenType(),
                                                               serverToken.getTokenKey());
+        clientToken.setRefreshToken(serverToken.getRefreshToken());
         if (writeOptionalParameters) {
             clientToken.setExpiresIn(serverToken.getLifetime());
             List<OAuthPermission> perms = serverToken.getScopes();
@@ -117,8 +118,6 @@ public class AccessTokenService extends 
             clientToken.setParameters(serverToken.getParameters());
         }
         
-        //TODO: also set a refresh token if any
-        
         // Return it to the client
         return Response.ok(clientToken)
                        .header(HttpHeaders.CACHE_CONTROL, "no-store")

Added: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/HmacAlgorithm.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/HmacAlgorithm.java?rev=1365160&view=auto
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/HmacAlgorithm.java (added)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/HmacAlgorithm.java Tue Jul 24 16:21:07 2012
@@ -0,0 +1,52 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.rs.security.oauth2.tokens.mac;
+
+import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
+
+public enum HmacAlgorithm {
+    HmacSHA1(OAuthConstants.MAC_TOKEN_ALGO_HMAC_SHA_1),
+    HmacSHA256(OAuthConstants.MAC_TOKEN_ALGO_HMAC_SHA_256);
+
+    private final String oauthName;
+
+    private HmacAlgorithm(String oauthName) {
+        this.oauthName = oauthName;
+    }
+
+    public String getOAuthName() {
+        return oauthName;
+    }
+
+    public String getJavaName() {
+        return name();
+    }
+
+    public static HmacAlgorithm toHmacAlgorithm(String value) {
+        if (OAuthConstants.MAC_TOKEN_ALGO_HMAC_SHA_1.equals(value)) {
+            return HmacSHA1;
+        }
+        if (OAuthConstants.MAC_TOKEN_ALGO_HMAC_SHA_256.equals(value)) {
+            return HmacSHA256;
+        }
+        return null;
+    }
+    
+}
\ No newline at end of file

Propchange: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/HmacAlgorithm.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/HmacAlgorithm.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/HmacUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/HmacUtils.java?rev=1365160&view=auto
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/HmacUtils.java (added)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/HmacUtils.java Tue Jul 24 16:21:07 2012
@@ -0,0 +1,103 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.rs.security.oauth2.tokens.mac;
+
+import java.io.UnsupportedEncodingException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
+import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
+
+public final class HmacUtils {
+    private HmacUtils() {
+        
+    }
+    
+    public static String computeSignature(String macAlgoOAuthName, String macSecret, String data) {
+        HmacAlgorithm theAlgo = HmacAlgorithm.toHmacAlgorithm(macAlgoOAuthName);
+        return HmacUtils.computeHmacString(macSecret, 
+                                           theAlgo.getJavaName(), 
+                                           data);
+    }
+    
+    /**
+      * Computes HMAC value using the given parameters.
+      * 
+      * @param macSecret
+      * @param macAlgorithm Should be one of HmacSHA1 or HmacSHA256
+      * @param data
+      * @return Base64 encoded string representation of the computed hmac value
+      */
+    public static String computeHmacString(String macSecret, String macAlgoJavaName, String data) {
+        return new String(Base64Utility.encode(computeHmac(macSecret, macAlgoJavaName, data)));
+    }
+    
+    /**
+     * Computes HMAC value using the given parameters.
+     * 
+     * @param macKey
+     * @param macAlgorithm
+     * @param data
+     * @return Computed HMAC value.
+     */
+    public static byte[] computeHmac(String key, HmacAlgorithm algo, String data) {
+        return computeHmac(key, algo.getJavaName(), data);
+    }
+    
+    /**
+      * Computes HMAC value using the given parameters.
+      * 
+      * @param macKey
+      * @param macAlgorithm
+      * @param data
+      * @return Computed HMAC value.
+      */
+    public static byte[] computeHmac(String key, String macAlgoJavaName, String data) {
+        try {
+            Mac hmac = Mac.getInstance(macAlgoJavaName);
+            SecretKeySpec secretKey = new SecretKeySpec(key.getBytes("UTF-8"), macAlgoJavaName);
+            hmac.init(secretKey);
+            return hmac.doFinal(data.getBytes());
+        } catch (NoSuchAlgorithmException e) {
+            throw new OAuthServiceException(OAuthConstants.INVALID_REQUEST, e);
+        } catch (InvalidKeyException e) {
+            throw new OAuthServiceException(OAuthConstants.INVALID_REQUEST, e);
+        } catch (UnsupportedEncodingException e) {
+            throw new OAuthServiceException(OAuthConstants.INVALID_REQUEST, e);
+        }
+    }
+    
+    public static String generateSecret(HmacAlgorithm algo) {
+        try {
+            KeyGenerator keyGen = KeyGenerator.getInstance(algo.name());
+            return Base64Utility.encode(keyGen.generateKey().getEncoded());
+        } catch (NoSuchAlgorithmException e) {
+            throw new OAuthServiceException(OAuthConstants.SERVER_ERROR, e);
+        }
+    }
+    
+       
+       
+}

Propchange: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/HmacUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/HmacUtils.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/MacAccessToken.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/MacAccessToken.java?rev=1365160&view=auto
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/MacAccessToken.java (added)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/MacAccessToken.java Tue Jul 24 16:21:07 2012
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.rs.security.oauth2.tokens.mac;
+
+import org.apache.cxf.rs.security.oauth2.common.Client;
+import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken;
+import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
+import org.apache.cxf.rs.security.oauth2.utils.OAuthUtils;
+
+public class MacAccessToken extends ServerAccessToken {
+    public MacAccessToken(Client client, 
+                          String macAuthAlgo,
+                          long lifetime) {
+        this(client, HmacAlgorithm.toHmacAlgorithm(macAuthAlgo), lifetime);
+    }
+    
+    public MacAccessToken(Client client, 
+                          HmacAlgorithm macAlgo,
+                          long lifetime) {
+        this(client, 
+             macAlgo,
+             OAuthUtils.generateRandomTokenKey(), 
+             lifetime, 
+             System.currentTimeMillis() / 1000);
+    }
+    public MacAccessToken(Client client,
+                          HmacAlgorithm algo,
+                          String tokenKey,
+                          long lifetime, 
+                          long issuedAt) {
+        super(client, OAuthConstants.MAC_TOKEN_TYPE, tokenKey, lifetime, issuedAt);
+        this.setExtraParameters(algo);
+    }
+    
+    private void setExtraParameters(HmacAlgorithm algo) {
+        super.getParameters().put(OAuthConstants.MAC_TOKEN_SECRET,
+                                  HmacUtils.generateSecret(algo));
+        super.getParameters().put(OAuthConstants.MAC_TOKEN_ALGORITHM,
+                                  algo.getOAuthName());
+    }
+    
+    public String getMacKey() {
+        return super.getTokenKey();
+    }
+    
+    public String getMacSecret() {
+        return super.getParameters().get(OAuthConstants.MAC_TOKEN_SECRET);
+    }
+    
+    public String getMacAlgorithm() {
+        return super.getParameters().get(OAuthConstants.MAC_TOKEN_ALGORITHM);
+    }
+}

Propchange: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/MacAccessToken.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/MacAccessToken.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/MacAccessTokenValidator.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/MacAccessTokenValidator.java?rev=1365160&view=auto
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/MacAccessTokenValidator.java (added)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/MacAccessTokenValidator.java Tue Jul 24 16:21:07 2012
@@ -0,0 +1,110 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.rs.security.oauth2.tokens.mac;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cxf.common.util.Base64Exception;
+import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.jaxrs.ext.MessageContext;
+import org.apache.cxf.rs.security.oauth2.client.HttpRequestProperties;
+import org.apache.cxf.rs.security.oauth2.common.AccessTokenValidation;
+import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken;
+import org.apache.cxf.rs.security.oauth2.provider.AccessTokenValidator;
+import org.apache.cxf.rs.security.oauth2.provider.OAuthDataProvider;
+import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
+import org.apache.cxf.rs.security.oauth2.utils.AuthorizationUtils;
+import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
+
+public class MacAccessTokenValidator implements AccessTokenValidator {
+    private OAuthDataProvider dataProvider;
+    private NonceVerifier nonceVerifier;
+    
+    public List<String> getSupportedAuthorizationSchemes() {
+        return Collections.singletonList(OAuthConstants.MAC_AUTHORIZATION_SCHEME);
+    }
+
+    public AccessTokenValidation validateAccessToken(MessageContext mc,
+                                                     String authScheme, 
+                                                     String authSchemeData) throws OAuthServiceException {
+        HttpRequestProperties httpProps = new HttpRequestProperties(mc.getUriInfo().getRequestUri(),
+                                                                    mc.getHttpServletRequest().getMethod()); 
+        Map<String, String> schemeParams = getSchemeParameters(authSchemeData);
+        MacAuthorizationScheme macAuthInfo = new MacAuthorizationScheme(httpProps, schemeParams);
+        
+        MacAccessToken macAccessToken = validateSchemeData(macAuthInfo,
+                                                           schemeParams.get(OAuthConstants.MAC_TOKEN_SIGNATURE));
+        validateTimestampNonce(macAccessToken, macAuthInfo.getTimestamp(), macAuthInfo.getNonce());
+        return new AccessTokenValidation(macAccessToken);
+    }
+    
+    private static Map<String, String> getSchemeParameters(String authData) {
+        String[] attributePairs = authData.split(",");
+        Map<String, String> attributeMap = new HashMap<String, String>();
+        for (String pair : attributePairs) {
+            String[] pairValues = pair.trim().split("=", 2);
+            attributeMap.put(pairValues[0].trim(), pairValues[1].trim().replaceAll("\"", ""));
+        }
+        return attributeMap;
+    }
+    
+    protected void validateTimestampNonce(MacAccessToken token, String ts, String nonce) {
+        // (http://tools.ietf.org/html/draft-ietf-oauth-v2-http-mac-01#section-4.1)
+        if (nonceVerifier != null) {
+            nonceVerifier.verifyNonce(token.getTokenKey(), nonce, ts);
+        }
+    }
+    
+    private MacAccessToken validateSchemeData(MacAuthorizationScheme macAuthInfo,
+                                              String clientMacString) {
+        String macKey = macAuthInfo.getMacKey();
+        
+        ServerAccessToken accessToken = dataProvider.getAccessToken(macKey);
+        if (!(accessToken instanceof MacAccessToken)) {
+            throw new OAuthServiceException(OAuthConstants.SERVER_ERROR);
+        }
+        MacAccessToken macAccessToken = (MacAccessToken)accessToken;
+        
+        String normalizedString = macAuthInfo.getNormalizedRequestString();
+        try {
+            HmacAlgorithm hmacAlgo = HmacAlgorithm.toHmacAlgorithm(macAccessToken.getMacAlgorithm());
+            byte[] serverMacData = HmacUtils.computeHmac(
+                macAccessToken.getMacSecret(), hmacAlgo, normalizedString); 
+                                                         
+            byte[] clientMacData = Base64Utility.decode(clientMacString);
+            boolean validMac = Arrays.equals(serverMacData, clientMacData);
+            if (!validMac) {
+                AuthorizationUtils.throwAuthorizationFailure(Collections
+                    .singleton(OAuthConstants.MAC_AUTHORIZATION_SCHEME));
+            }
+        } catch (Base64Exception e) {
+            throw new OAuthServiceException(OAuthConstants.SERVER_ERROR, e);
+        }
+        return macAccessToken;
+    }
+    
+    public void setDataProvider(OAuthDataProvider dataProvider) {
+        this.dataProvider = dataProvider;
+    }
+
+}

Propchange: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/MacAccessTokenValidator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/MacAccessTokenValidator.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/MacAuthorizationScheme.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/MacAuthorizationScheme.java?rev=1365160&view=auto
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/MacAuthorizationScheme.java (added)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/MacAuthorizationScheme.java Tue Jul 24 16:21:07 2012
@@ -0,0 +1,117 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.rs.security.oauth2.tokens.mac;
+
+import java.security.SecureRandom;
+import java.util.Map;
+
+import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.rs.security.oauth2.client.HttpRequestProperties;
+import org.apache.cxf.rs.security.oauth2.common.AccessToken;
+import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
+
+public class MacAuthorizationScheme {
+    private static final String SEPARATOR = "\n";
+    
+    private HttpRequestProperties props;
+    private String macKey;
+    private String timestamp;
+    private String nonce;
+    
+    public MacAuthorizationScheme(HttpRequestProperties props,
+                                  AccessToken token) {
+        this.props = props;
+        this.macKey = token.getTokenKey();
+        this.timestamp = Long.toString(System.currentTimeMillis());
+        this.nonce = generateNonce();
+    }
+    
+    public MacAuthorizationScheme(HttpRequestProperties props,
+                                  Map<String, String> schemeParams) {
+        this.props = props;
+        this.macKey = schemeParams.get(OAuthConstants.MAC_TOKEN_KEY);
+        this.timestamp = schemeParams.get(OAuthConstants.MAC_TOKEN_TIMESTAMP);
+        this.nonce = schemeParams.get(OAuthConstants.MAC_TOKEN_NONCE);
+    }
+    
+    public String getMacKey() {
+        return macKey;
+    }
+    
+    public String getTimestamp() {
+        return timestamp;
+    }
+    
+    public String getNonce() {
+        return nonce;
+    }
+    
+    public String toAuthorizationHeader(String macAlgo, String macSecret) {
+        
+        String data = getNormalizedRequestString();
+        String signature = HmacUtils.computeSignature(macAlgo, macSecret, data);
+        
+        StringBuilder sb = new StringBuilder();
+        sb.append(OAuthConstants.MAC_AUTHORIZATION_SCHEME).append(" ");
+        addParameter(sb, OAuthConstants.MAC_TOKEN_KEY, macKey, false);
+        addParameter(sb, OAuthConstants.MAC_TOKEN_TIMESTAMP, timestamp, false);
+        addParameter(sb, OAuthConstants.MAC_TOKEN_NONCE, nonce, false);
+        addParameter(sb, OAuthConstants.MAC_TOKEN_SIGNATURE, signature, true);
+        
+        return sb.toString();
+    }
+    
+    private static void addParameter(StringBuilder sb, String name, String value, boolean last) {
+        sb.append(name).append('=')
+          .append('\"').append(value).append('\"');
+        if (!last) {
+            sb.append(',');
+        }
+    }
+    
+    public String getNormalizedRequestString() {
+        
+        String value = macKey + SEPARATOR 
+            + timestamp + SEPARATOR 
+            + nonce + SEPARATOR 
+            + props.getHttpMethod().toUpperCase() + SEPARATOR 
+            + props.getHostName() + SEPARATOR 
+            + props.getPort() + SEPARATOR
+            + props.getRequestPath() + SEPARATOR;
+
+        if (!StringUtils.isEmpty(props.getRequestQuery())) {
+            value += normalizeQuery(props.getRequestQuery()) + SEPARATOR;
+        }
+            
+        value += SEPARATOR;
+        return value;
+    }
+    
+    private static String normalizeQuery(String query) {  
+        return query;
+    }
+    
+    private static String generateNonce() {
+        byte[] randomBytes = new byte[20];
+        new SecureRandom().nextBytes(randomBytes);
+        return Base64Utility.encode(randomBytes);
+    }
+
+}

Propchange: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/MacAuthorizationScheme.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/MacAuthorizationScheme.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceVerifier.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceVerifier.java?rev=1365160&view=auto
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceVerifier.java (added)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceVerifier.java Tue Jul 24 16:21:07 2012
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.rs.security.oauth2.tokens.mac;
+
+import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
+
+public interface NonceVerifier {
+    void verifyNonce(String tokenKey, String clientNonce, String clientTimestamp) 
+        throws OAuthServiceException;
+}

Propchange: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceVerifier.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceVerifier.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthConstants.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthConstants.java?rev=1365160&r1=1365159&r2=1365160&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthConstants.java (original)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthConstants.java Tue Jul 24 16:21:07 2012
@@ -48,11 +48,25 @@ public final class OAuthConstants {
     public static final String BEARER_TOKEN_TYPE = "bearer";
     public static final String MAC_TOKEN_TYPE = "mac";
     
+    // MAC token parameters
+    // Set by Access Token Service
+    public static final String MAC_TOKEN_SECRET = "secret";
+    public static final String MAC_TOKEN_ALGORITHM = "algorithm";
+    public static final String MAC_TOKEN_ALGO_HMAC_SHA_1 = "hmac-sha-1";
+    public static final String MAC_TOKEN_ALGO_HMAC_SHA_256 = "hmac-sha-256";
+    
+    // Set in Authorization header
+    public static final String MAC_TOKEN_KEY = "token";
+    public static final String MAC_TOKEN_TIMESTAMP = "timestamp";
+    public static final String MAC_TOKEN_NONCE = "nonce";
+    public static final String MAC_TOKEN_SIGNATURE = "signature";
+    
     // Token Authorization schemes
     public static final String BEARER_AUTHORIZATION_SCHEME = "Bearer";
-    public static final String MAC_AUTHORIZATION_SCHEME = "Mac";
+    public static final String MAC_AUTHORIZATION_SCHEME = "MAC";
     public static final String ALL_AUTH_SCHEMES = "*";
 
+    
     // Default Client Authentication Scheme
     public static final String BASIC_SCHEME = "Basic";
     

Modified: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/OAuthJSONProviderTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/OAuthJSONProviderTest.java?rev=1365160&r1=1365159&r2=1365160&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/OAuthJSONProviderTest.java (original)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/OAuthJSONProviderTest.java Tue Jul 24 16:21:07 2012
@@ -22,12 +22,14 @@ import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.lang.annotation.Annotation;
 import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.Map;
 
 import javax.ws.rs.core.MediaType;
 
 import org.apache.cxf.jaxrs.impl.MetadataMap;
 import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken;
+import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
 
 import org.junit.Assert;
 import org.junit.Test;
@@ -35,8 +37,8 @@ import org.junit.Test;
 public class OAuthJSONProviderTest extends Assert {
 
     @Test
-    public void testWriteClientAccessToken() throws Exception {
-        ClientAccessToken token = new ClientAccessToken("bearer", "1234");
+    public void testWriteBearerClientAccessToken() throws Exception {
+        ClientAccessToken token = new ClientAccessToken(OAuthConstants.BEARER_TOKEN_TYPE, "1234");
         token.setExpiresIn(12345);
         token.setRefreshToken("5678");
         token.setApprovedScope("read");
@@ -51,11 +53,11 @@ public class OAuthJSONProviderTest exten
                          MediaType.APPLICATION_JSON_TYPE, 
                          new MetadataMap<String, Object>(), 
                          bos);
-        doReadClientAccessToken(bos.toString());
+        doReadClientAccessToken(bos.toString(), OAuthConstants.BEARER_TOKEN_TYPE, token.getParameters());
     }
     
     @Test
-    public void testReadClientAccessToken() throws Exception {
+    public void testReadBearerClientAccessToken() throws Exception {
         String response = 
             "{"
             + "\"access_token\":\"1234\","
@@ -65,13 +67,17 @@ public class OAuthJSONProviderTest exten
             + "\"scope\":\"read\","
             + "\"my_parameter\":\"abc\""
             + "}";
-        doReadClientAccessToken(response);
+        doReadClientAccessToken(response, OAuthConstants.BEARER_TOKEN_TYPE,
+                                Collections.singletonMap("my_parameter", "abc"));
     }
     
     @SuppressWarnings({
         "unchecked", "rawtypes"
     })
-    public void doReadClientAccessToken(String response) throws Exception {
+    
+    public ClientAccessToken doReadClientAccessToken(String response, 
+                                        String expectedTokenType,
+                                        Map<String, String> expectedParams) throws Exception {
         OAuthJSONProvider provider = new OAuthJSONProvider();
         ClientAccessToken token = (ClientAccessToken)provider.readFrom((Class)ClientAccessToken.class, 
                           ClientAccessToken.class, 
@@ -80,15 +86,54 @@ public class OAuthJSONProviderTest exten
                           new MetadataMap<String, String>(), 
                           new ByteArrayInputStream(response.getBytes()));
         assertEquals("1234", token.getTokenKey());
-        assertEquals("bearer", token.getTokenType());
+        assertEquals(expectedTokenType, token.getTokenType());
         assertEquals("5678", token.getRefreshToken());
         assertEquals(12345, token.getExpiresIn());
         assertEquals("read", token.getApprovedScope());
         Map<String, String> extraParams = token.getParameters();
-        assertEquals(1, extraParams.size());
+        if (expectedParams != null) {
+            assertEquals(expectedParams, extraParams);
+        }
         assertEquals("abc", extraParams.get("my_parameter"));
+        
+        return token;
+        
     }
     
+    @Test
+    public void testWriteMacClientAccessToken() throws Exception {
+        ClientAccessToken token = new ClientAccessToken("mac", "1234");
+        token.setExpiresIn(12345);
+        token.setRefreshToken("5678");
+        token.setApprovedScope("read");
+        Map<String, String> params = new LinkedHashMap<String, String>();
+        params.put(OAuthConstants.MAC_TOKEN_SECRET, "test_mac_secret");
+        params.put(OAuthConstants.MAC_TOKEN_ALGORITHM, OAuthConstants.MAC_TOKEN_ALGO_HMAC_SHA_1);
+        params.put("my_parameter", "abc");
+        
+        token.setParameters(params);
+        
+        OAuthJSONProvider provider = new OAuthJSONProvider();
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        provider.writeTo(token, ClientAccessToken.class, ClientAccessToken.class, new Annotation[] {},
+                         MediaType.APPLICATION_JSON_TYPE, new MetadataMap<String, Object>(), bos);
+        doReadClientAccessToken(bos.toString(), 
+                                OAuthConstants.MAC_TOKEN_TYPE,
+                                params);
+        
+    }
     
+    @Test
+    public void testReadMacClientAccessToken() throws Exception {
+        String response = "{" + "\"access_token\":\"1234\"," + "\"token_type\":\"mac\","
+            + "\"refresh_token\":\"5678\"," + "\"expires_in\":12345," + "\"scope\":\"read\","
+            + "\"secret\":\"adijq39jdlaska9asud\"," + "\"algorithm\":\"hmac-sha-256\","
+            + "\"my_parameter\":\"abc\"" + "}";
+        ClientAccessToken macToken = doReadClientAccessToken(response, "mac", null);
+        assertEquals("adijq39jdlaska9asud", 
+                     macToken.getParameters().get(OAuthConstants.MAC_TOKEN_SECRET));
+        assertEquals("hmac-sha-256",
+                     macToken.getParameters().get(OAuthConstants.MAC_TOKEN_ALGORITHM));
+    }
     
 }

Added: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/token/mac/MacAccessTokenValidatorTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/token/mac/MacAccessTokenValidatorTest.java?rev=1365160&view=auto
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/token/mac/MacAccessTokenValidatorTest.java (added)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/token/mac/MacAccessTokenValidatorTest.java Tue Jul 24 16:21:07 2012
@@ -0,0 +1,97 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.rs.security.oauth2.token.mac;
+
+import java.net.URI;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.cxf.jaxrs.ext.MessageContext;
+import org.apache.cxf.rs.security.oauth2.client.HttpRequestProperties;
+import org.apache.cxf.rs.security.oauth2.common.AccessTokenValidation;
+import org.apache.cxf.rs.security.oauth2.common.Client;
+import org.apache.cxf.rs.security.oauth2.provider.OAuthDataProvider;
+import org.apache.cxf.rs.security.oauth2.tokens.mac.HmacAlgorithm;
+import org.apache.cxf.rs.security.oauth2.tokens.mac.MacAccessToken;
+import org.apache.cxf.rs.security.oauth2.tokens.mac.MacAccessTokenValidator;
+import org.apache.cxf.rs.security.oauth2.tokens.mac.MacAuthorizationScheme;
+import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
+import org.easymock.EasyMock;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class MacAccessTokenValidatorTest extends Assert {
+
+    private MacAccessTokenValidator validator = new MacAccessTokenValidator();
+    private OAuthDataProvider dataProvider = EasyMock.createMock(OAuthDataProvider.class);
+    private MessageContext messageContext = EasyMock.createMock(MessageContext.class);
+    
+    @Before
+    public void setUp() {
+        validator.setDataProvider(dataProvider);
+    }
+    
+    @Test
+    public void testValidateAccessToken() throws Exception {
+        MacAccessToken macAccessToken = new MacAccessToken(new Client("testClientId", "testClientSecret",
+                                                                          false), 
+                                                                          HmacAlgorithm.HmacSHA256, -1);
+        HttpServletRequest httpRequest = mockHttpRequest();
+        UriInfo uriInfo = mockUriInfo();
+        
+        EasyMock.expect(dataProvider.getAccessToken(macAccessToken.getTokenKey())).andReturn(macAccessToken);
+        EasyMock.expect(messageContext.getHttpServletRequest()).andReturn(httpRequest);
+        EasyMock.expect(messageContext.getUriInfo()).andReturn(uriInfo);
+        EasyMock.replay(dataProvider, messageContext, httpRequest, uriInfo);
+    
+        String authData = getClientAuthHeader(macAccessToken);
+        AccessTokenValidation tokenValidation = validator
+            .validateAccessToken(messageContext, 
+                                 OAuthConstants.MAC_AUTHORIZATION_SCHEME, 
+                                 authData.split(" ")[1]);
+        assertNotNull(tokenValidation);
+        EasyMock.verify(dataProvider, messageContext, httpRequest);
+    }
+    
+    private static String getClientAuthHeader(MacAccessToken macAccessToken) {
+        String address = "http://localhost:8080/appContext/oauth2/testResource";
+        HttpRequestProperties props = new HttpRequestProperties(URI.create(address), "GET");
+        
+        return new MacAuthorizationScheme(props, macAccessToken)
+            .toAuthorizationHeader(macAccessToken.getMacAlgorithm(),
+                                   macAccessToken.getMacSecret());
+    }
+    
+    private static HttpServletRequest mockHttpRequest() {
+        HttpServletRequest httpRequest = EasyMock.createMock(HttpServletRequest.class);
+        EasyMock.expect(httpRequest.getMethod()).andReturn("GET");
+        return httpRequest;
+    }
+    
+    private static UriInfo mockUriInfo() {
+        UriInfo ui = EasyMock.createMock(UriInfo.class);
+        EasyMock.expect(ui.getRequestUri()).andReturn(
+            URI.create("http://localhost:8080/appContext/oauth2/testResource"));
+        return ui;
+    }
+
+}

Propchange: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/token/mac/MacAccessTokenValidatorTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/token/mac/MacAccessTokenValidatorTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date