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/05/14 16:09:02 UTC

svn commit: r1338211 - in /cxf/trunk/rt/rs/security/oauth-parent/oauth2/src: main/java/org/apache/cxf/rs/security/oauth2/client/ main/java/org/apache/cxf/rs/security/oauth2/common/ main/java/org/apache/cxf/rs/security/oauth2/provider/ main/java/org/apa...

Author: sergeyb
Date: Mon May 14 14:09:01 2012
New Revision: 1338211

URL: http://svn.apache.org/viewvc?rev=1338211&view=rev
Log:
[CXF-4309] Improving OAuthJSONProvider to write and read more token properties

Added:
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/OAuthJSONProviderTest.java   (with props)
Modified:
    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/ClientAccessToken.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/AccessTokenService.java
    cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/RedirectionBasedGrantService.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/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthUtils.java

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=1338211&r1=1338210&r2=1338211&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 Mon May 14 14:09:01 2012
@@ -182,25 +182,48 @@ public final class OAuthClientUtils {
             throw new ClientWebApplicationException(ex);
         }
         if (200 == response.getStatus()) {
-            if (map.containsKey(OAuthConstants.ACCESS_TOKEN)
-                && map.containsKey(OAuthConstants.ACCESS_TOKEN_TYPE)) {
-                String tokenType = map.get(OAuthConstants.ACCESS_TOKEN_TYPE);
-                
-                ClientAccessToken token = new ClientAccessToken(
-                                              tokenType,
-                                              map.get(OAuthConstants.ACCESS_TOKEN));
-                return token;
-            } else {
+            ClientAccessToken token = fromMapToClientToken(map);
+            if (token == null) {
                 throw new OAuthServiceException(OAuthConstants.SERVER_ERROR);
+            } else {
+                return token;
             }
         } else if (400 == response.getStatus() && map.containsValue(OAuthConstants.ERROR_KEY)) {
             OAuthError error = new OAuthError(map.get(OAuthConstants.ERROR_KEY),
                                               map.get(OAuthConstants.ERROR_DESCRIPTION_KEY));
+            error.setErrorUri(map.get(OAuthConstants.ERROR_URI_KEY));
             throw new OAuthServiceException(error);
         } 
         throw new OAuthServiceException(OAuthConstants.SERVER_ERROR);
     }
     
+    public static ClientAccessToken fromMapToClientToken(Map<String, String> map) {
+        if (map.containsKey(OAuthConstants.ACCESS_TOKEN)
+            && map.containsKey(OAuthConstants.ACCESS_TOKEN_TYPE)) {
+            ClientAccessToken token = new ClientAccessToken(
+                                          map.remove(OAuthConstants.ACCESS_TOKEN_TYPE),
+                                          map.remove(OAuthConstants.ACCESS_TOKEN));
+            
+            String refreshToken = map.remove(OAuthConstants.REFRESH_TOKEN);
+            if (refreshToken != null) {
+                token.setRefreshToken(refreshToken);
+            }
+            String expiresInStr = map.remove(OAuthConstants.ACCESS_TOKEN_EXPIRES_IN);
+            if (expiresInStr != null) {
+                token.setExpiresIn(Long.valueOf(expiresInStr));
+            }
+            String scope = map.remove(OAuthConstants.SCOPE);
+            if (scope != null) {
+                token.setApprovedScope(scope);
+            }
+            
+            token.setParameters(map);
+            return token;
+        } else {
+            return null;
+        }
+    }
+    
     /**
      * Creates OAuth Authorization header for accessing the end user's resources
      * @param consumer represents the registered client

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=1338211&r1=1338210&r2=1338211&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 Mon May 14 14:09:01 2012
@@ -30,6 +30,7 @@ public class ClientAccessToken extends A
 
     private String scope;
     private String rToken;
+    private long expiresIn = -1;
     
     public ClientAccessToken(String tokenType, String tokenKey) {
         super(tokenType, tokenKey);
@@ -71,4 +72,16 @@ public class ClientAccessToken extends A
         return rToken;
     }
 
+    /**
+     * The token lifetime
+     * @return the lifetime, -1 means no 'expires_in' parameter was returned
+     */
+    public long getExpiresIn() {
+        return expiresIn;
+    }
+
+    public void setExpiresIn(long expiresIn) {
+        this.expiresIn = expiresIn;
+    }
+
 }

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=1338211&r1=1338210&r2=1338211&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 Mon May 14 14:09:01 2012
@@ -38,6 +38,7 @@ import javax.ws.rs.ext.Provider;
 
 import org.apache.cxf.helpers.IOUtils;
 import org.apache.cxf.jaxrs.client.ClientWebApplicationException;
+import org.apache.cxf.rs.security.oauth2.client.OAuthClientUtils;
 import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken;
 import org.apache.cxf.rs.security.oauth2.common.OAuthError;
 import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
@@ -46,7 +47,7 @@ import org.apache.cxf.rs.security.oauth2
 @Produces("application/json")
 @Consumes("application/json")
 public class OAuthJSONProvider implements MessageBodyWriter<Object>,
-    MessageBodyReader<Map<String, String>> {
+    MessageBodyReader<Object> {
 
     public long getSize(Object obj, Class<?> clt, Type t, Annotation[] anns, MediaType mt) {
         return -1;
@@ -74,7 +75,11 @@ public class OAuthJSONProvider implement
             sb.append(",");
             appendJsonPair(sb, OAuthConstants.ERROR_DESCRIPTION_KEY, obj.getErrorDescription());
         }
-        // etc
+        if (obj.getErrorUri() != null) {
+            sb.append(",");
+            appendJsonPair(sb, OAuthConstants.ERROR_URI_KEY, obj.getErrorUri());
+        }
+        
         sb.append("}");
         String result = sb.toString();
         os.write(result.getBytes("UTF-8"));
@@ -86,28 +91,65 @@ public class OAuthJSONProvider implement
         sb.append("{");
         appendJsonPair(sb, OAuthConstants.ACCESS_TOKEN, obj.getTokenKey());
         sb.append(",");
-        appendJsonPair(sb, OAuthConstants.ACCESS_TOKEN_TYPE, obj.getTokenType().toString());
-        // etc
+        appendJsonPair(sb, OAuthConstants.ACCESS_TOKEN_TYPE, obj.getTokenType());
+        if (obj.getExpiresIn() != -1) {
+            sb.append(",");
+            appendJsonPair(sb, OAuthConstants.ACCESS_TOKEN_EXPIRES_IN, obj.getExpiresIn(), false);
+        }
+        if (obj.getApprovedScope() != null) {
+            sb.append(",");
+            appendJsonPair(sb, OAuthConstants.SCOPE, obj.getApprovedScope());
+        }
+        if (obj.getRefreshToken() != null) {
+            sb.append(",");
+            appendJsonPair(sb, OAuthConstants.REFRESH_TOKEN, obj.getRefreshToken());
+        }
+        Map<String, String> parameters = obj.getParameters();
+        for (Map.Entry<String, String> entry : parameters.entrySet()) {
+            sb.append(",");
+            appendJsonPair(sb, entry.getKey(), entry.getValue());
+        }
         sb.append("}");
         String result = sb.toString();
         os.write(result.getBytes("UTF-8"));
         os.flush();
     }
 
-    private void appendJsonPair(StringBuilder sb, String key, String value) {
+    private void appendJsonPair(StringBuilder sb, String key, Object value) {
+        appendJsonPair(sb, key, value, true);
+    }
+    
+    private void appendJsonPair(StringBuilder sb, String key, Object value,
+                                boolean valueQuote) {
         sb.append("\"").append(key).append("\"");
         sb.append(":");
-        sb.append("\"").append(value).append("\"");
+        if (valueQuote) {
+            sb.append("\"");
+        }
+        sb.append(value);
+        if (valueQuote) {
+            sb.append("\"");
+        }
     }
     
     public boolean isReadable(Class<?> cls, Type t, Annotation[] anns, MediaType mt) {
-        return Map.class.isAssignableFrom(cls);
+        return Map.class.isAssignableFrom(cls) || ClientAccessToken.class.isAssignableFrom(cls);
     }
 
-    public Map<String, String> readFrom(Class<Map<String, String>> cls, Type t, Annotation[] anns, 
-                                        MediaType mt, MultivaluedMap<String, String> headers, InputStream is) 
+    public Object readFrom(Class<Object> cls, Type t, Annotation[] anns, 
+                           MediaType mt, MultivaluedMap<String, String> headers, InputStream is) 
         throws IOException, WebApplicationException {
-        return readJSONResponse(is);
+        Map<String, String> params = readJSONResponse(is);
+        if (Map.class.isAssignableFrom(cls)) {
+            return params;
+        }
+        ClientAccessToken token = OAuthClientUtils.fromMapToClientToken(params);
+        if (token == null) {
+            throw new WebApplicationException(500);
+        } else {
+            return token;
+        }
+        
     }
 
     public Map<String, String> readJSONResponse(InputStream is) throws IOException  {

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=1338211&r1=1338210&r2=1338211&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 Mon May 14 14:09:01 2012
@@ -36,6 +36,7 @@ import javax.ws.rs.core.SecurityContext;
 import org.apache.cxf.rs.security.oauth2.common.Client;
 import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken;
 import org.apache.cxf.rs.security.oauth2.common.OAuthError;
+import org.apache.cxf.rs.security.oauth2.common.OAuthPermission;
 import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken;
 import org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeDataProvider;
 import org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeGrantHandler;
@@ -43,6 +44,7 @@ import org.apache.cxf.rs.security.oauth2
 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;
+import org.apache.cxf.rs.security.oauth2.utils.OAuthUtils;
 
 /**
  * OAuth2 Access Token Service implementation
@@ -50,6 +52,11 @@ import org.apache.cxf.rs.security.oauth2
 @Path("/token")
 public class AccessTokenService extends AbstractOAuthService {
     private List<AccessTokenGrantHandler> grantHandlers = Collections.emptyList();
+    private boolean writeOptionalParameters = true;
+    
+    public void setWriteOptionalParameters(boolean write) {
+        writeOptionalParameters = write;
+    }
     
     /**
      * Sets the list of optional grant handlers
@@ -92,8 +99,16 @@ public class AccessTokenService extends 
         // Extract the information to be of use for the client
         ClientAccessToken clientToken = new ClientAccessToken(serverToken.getTokenType(),
                                                               serverToken.getTokenKey());
-        clientToken.setParameters(serverToken.getParameters());
+        if (writeOptionalParameters) {
+            clientToken.setExpiresIn(serverToken.getLifetime());
+            List<OAuthPermission> perms = serverToken.getScopes();
+            if (!perms.isEmpty()) {
+                clientToken.setApprovedScope(OAuthUtils.convertPermissionsToScope(perms));    
+            }
+            clientToken.setParameters(serverToken.getParameters());
+        }
         
+        //TODO: also set a refresh token if any
         
         // Return it to the client
         return Response.ok(clientToken)

Modified: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/RedirectionBasedGrantService.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/RedirectionBasedGrantService.java?rev=1338211&r1=1338210&r2=1338211&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/RedirectionBasedGrantService.java (original)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/RedirectionBasedGrantService.java Mon May 14 14:09:01 2012
@@ -169,16 +169,7 @@ public abstract class RedirectionBasedGr
         addAuthenticityTokenToSession(secData);
                 
         secData.setPermissions(perms);
-        
-        StringBuilder sb = new StringBuilder();
-        for (OAuthPermission perm : perms) {
-            if (sb.length() > 0) {
-                sb.append(" ");
-            }
-            sb.append(perm.getPermission());
-        }
-        secData.setProposedScope(sb.toString());
-        
+        secData.setProposedScope(OAuthUtils.convertPermissionsToScope(perms));
         secData.setClientId(client.getClientId());
         secData.setRedirectUri(params.getFirst(OAuthConstants.REDIRECT_URI));
         secData.setState(params.getFirst(OAuthConstants.STATE));

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=1338211&r1=1338210&r2=1338211&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 Mon May 14 14:09:01 2012
@@ -31,9 +31,11 @@ public final class OAuthConstants {
     public static final String STATE = "state";
     public static final String ACCESS_TOKEN = "access_token";
     public static final String ACCESS_TOKEN_TYPE = "token_type";
+    public static final String ACCESS_TOKEN_EXPIRES_IN = "expires_in";
     public static final String GRANT_TYPE = "grant_type";
     public static final String RESPONSE_TYPE = "response_type";
     public static final String TOKEN_RESPONSE_TYPE = "token";
+    public static final String REFRESH_TOKEN = "refresh_token";
     
     // Well-known grant types
     public static final String AUTHORIZATION_CODE_GRANT = "authorization_code";
@@ -60,6 +62,7 @@ public final class OAuthConstants {
     // Error constants
     public static final String ERROR_KEY = "error";
     public static final String ERROR_DESCRIPTION_KEY = "error_description";
+    public static final String ERROR_URI_KEY = "error_uri";
     
     public static final String SERVER_ERROR = "server_error";
     public static final String INVALID_REQUEST = "invalid_request";

Modified: cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthUtils.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/OAuthUtils.java?rev=1338211&r1=1338210&r2=1338211&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthUtils.java (original)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthUtils.java Mon May 14 14:09:01 2012
@@ -28,6 +28,7 @@ import org.apache.cxf.common.util.String
 import org.apache.cxf.jaxrs.impl.MetadataMap;
 import org.apache.cxf.jaxrs.model.URITemplate;
 import org.apache.cxf.rs.security.oauth2.common.Client;
+import org.apache.cxf.rs.security.oauth2.common.OAuthPermission;
 import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
 
 /**
@@ -38,6 +39,17 @@ public final class OAuthUtils {
     private OAuthUtils() {
     }
 
+    public static String convertPermissionsToScope(List<OAuthPermission> perms) {
+        StringBuilder sb = new StringBuilder();
+        for (OAuthPermission perm : perms) {
+            if (sb.length() > 0) {
+                sb.append(" ");
+            }
+            sb.append(perm.getPermission());
+        }
+        return sb.toString();
+    }
+    
     public static boolean isGrantSupportedForClient(Client client, 
                                                     boolean isConfidential, 
                                                     String grantType) {

Added: 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=1338211&view=auto
==============================================================================
--- cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/OAuthJSONProviderTest.java (added)
+++ cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/provider/OAuthJSONProviderTest.java Mon May 14 14:09:01 2012
@@ -0,0 +1,94 @@
+/**
+ * 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.provider;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.lang.annotation.Annotation;
+import java.util.Collections;
+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.junit.Assert;
+import org.junit.Test;
+
+public class OAuthJSONProviderTest extends Assert {
+
+    @Test
+    public void testWriteClientAccessToken() throws Exception {
+        ClientAccessToken token = new ClientAccessToken("bearer", "1234");
+        token.setExpiresIn(12345);
+        token.setRefreshToken("5678");
+        token.setApprovedScope("read");
+        token.setParameters(Collections.singletonMap("my_parameter", "abc"));
+        
+        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());
+    }
+    
+    @Test
+    public void testReadClientAccessToken() throws Exception {
+        String response = 
+            "{"
+            + "\"access_token\":\"1234\","
+            + "\"token_type\":\"bearer\","
+            + "\"refresh_token\":\"5678\","
+            + "\"expires_in\":12345,"
+            + "\"scope\":\"read\","
+            + "\"my_parameter\":\"abc\""
+            + "}";
+        doReadClientAccessToken(response);
+    }
+    
+    @SuppressWarnings({
+        "unchecked", "rawtypes"
+    })
+    public void doReadClientAccessToken(String response) throws Exception {
+        OAuthJSONProvider provider = new OAuthJSONProvider();
+        ClientAccessToken token = (ClientAccessToken)provider.readFrom((Class)ClientAccessToken.class, 
+                          ClientAccessToken.class, 
+                          new Annotation[]{}, 
+                          MediaType.APPLICATION_JSON_TYPE, 
+                          new MetadataMap<String, String>(), 
+                          new ByteArrayInputStream(response.getBytes()));
+        assertEquals("1234", token.getTokenKey());
+        assertEquals("bearer", token.getTokenType());
+        assertEquals("5678", token.getRefreshToken());
+        assertEquals(12345, token.getExpiresIn());
+        assertEquals("read", token.getApprovedScope());
+        Map<String, String> extraParams = token.getParameters();
+        assertEquals(1, extraParams.size());
+        assertEquals("abc", extraParams.get("my_parameter"));
+    }
+    
+    
+    
+}

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

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