cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From serg...@apache.org
Subject [1/2] Moving crypto related OAuth2 utility classes to a subpackage to minimize the noise
Date Thu, 08 May 2014 11:46:08 GMT
Repository: cxf
Updated Branches:
  refs/heads/master 21bfb9ab9 -> 0e4633198


http://git-wip-us.apache.org/repos/asf/cxf/blob/0e463319/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/KeyProperties.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/KeyProperties.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/KeyProperties.java
new file mode 100644
index 0000000..8a473d8
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/KeyProperties.java
@@ -0,0 +1,88 @@
+/**
+ * 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.utils.crypto;
+
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+
+public class KeyProperties {
+    private String keyAlgo;
+    private int keySize;
+    private int blockSize = -1;
+    private byte[] additionalData;
+    private SecureRandom secureRandom;
+    private AlgorithmParameterSpec algoSpec;
+    private boolean compressionSupported;
+    
+    public KeyProperties() {
+    }
+    
+    public KeyProperties(String keyAlgo) {
+        this(keyAlgo, -1);
+    }
+    public KeyProperties(String keyAlgo, int keySize) {
+        this.keyAlgo = keyAlgo;
+        this.keySize = keySize;
+    }
+    public String getKeyAlgo() {
+        return keyAlgo;
+    }
+    public void setKeyAlgo(String keyAlgo) {
+        this.keyAlgo = keyAlgo;
+    }
+    public int getKeySize() {
+        return keySize;
+    }
+    public void setKeySize(int keySize) {
+        this.keySize = keySize;
+    }
+    public SecureRandom getSecureRandom() {
+        return secureRandom;
+    }
+    public void setSecureRandom(SecureRandom secureRandom) {
+        this.secureRandom = secureRandom;
+    }
+    public AlgorithmParameterSpec getAlgoSpec() {
+        return algoSpec;
+    }
+    public void setAlgoSpec(AlgorithmParameterSpec algoSpec) {
+        this.algoSpec = algoSpec;
+    }
+    public int getBlockSize() {
+        return blockSize;
+    }
+    public void setBlockSize(int blockSize) {
+        this.blockSize = blockSize;
+    }
+    public boolean isCompressionSupported() {
+        return compressionSupported;
+    }
+    public void setCompressionSupported(boolean compressionSupported) {
+        this.compressionSupported = compressionSupported;
+    }
+    public byte[] getAdditionalData() {
+        return additionalData;
+    }
+    public void setAdditionalData(byte[] additionalData) {
+        this.additionalData = additionalData;
+    }
+    
+    
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/0e463319/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/MessageDigestUtils.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/MessageDigestUtils.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/MessageDigestUtils.java
new file mode 100644
index 0000000..78058b7
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/MessageDigestUtils.java
@@ -0,0 +1,80 @@
+/**
+ * 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.utils.crypto;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
+
+/**
+ * The utility Message Digest generator which can be used for generating
+ * random values
+ */
+public final class MessageDigestUtils {
+    
+    public static final String ALGO_SHA_1 = "SHA-1";
+    public static final String ALGO_SHA_256 = "SHA-256";
+    public static final String ALGO_MD5 = "MD5";
+    
+    private MessageDigestUtils() {
+        
+    }
+        
+    public static String generate(byte[] input) throws OAuthServiceException {
+        return generate(input, ALGO_MD5);
+    }   
+    
+    public static String generate(byte[] input, String algo) throws OAuthServiceException {    
+        if (input == null) {
+            throw new OAuthServiceException("You have to pass input to Token Generator");
+        }
+
+        try {
+            byte[] messageDigest = createDigest(input, algo);
+            StringBuffer hexString = new StringBuffer();
+            for (int i = 0; i < messageDigest.length; i++) {
+                hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
+            }
+
+            return hexString.toString();
+        } catch (NoSuchAlgorithmException e) {
+            throw new OAuthServiceException("server_error", e);
+        }
+    }
+
+    public static byte[] createDigest(String input, String algo) {
+        try {
+            return createDigest(input.getBytes("UTF-8"), algo);
+        } catch (UnsupportedEncodingException e) {
+            throw new OAuthServiceException("server_error", e);
+        } catch (NoSuchAlgorithmException e) {
+            throw new OAuthServiceException("server_error", e);
+        }   
+    }
+    
+    public static byte[] createDigest(byte[] input, String algo) throws NoSuchAlgorithmException { 
+        MessageDigest md = MessageDigest.getInstance(algo);
+        md.reset();
+        md.update(input);
+        return md.digest();
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/0e463319/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/ModelEncryptionSupport.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/ModelEncryptionSupport.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/ModelEncryptionSupport.java
new file mode 100644
index 0000000..c19de17
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/ModelEncryptionSupport.java
@@ -0,0 +1,493 @@
+/**
+ * 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.utils.crypto;
+
+import java.security.Key;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.crypto.SecretKey;
+
+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.common.ServerAccessToken;
+import org.apache.cxf.rs.security.oauth2.common.UserSubject;
+import org.apache.cxf.rs.security.oauth2.grants.code.ServerAuthorizationCodeGrant;
+import org.apache.cxf.rs.security.oauth2.provider.OAuthDataProvider;
+import org.apache.cxf.rs.security.oauth2.tokens.refresh.RefreshToken;
+
+
+/**
+ * Default Model Encryption helpers
+ */
+public final class ModelEncryptionSupport {
+    private static final String SEP = "|";
+    private ModelEncryptionSupport() {
+    }
+    
+    public static String encryptClient(Client client, Key secretKey) throws EncryptionException {
+        return encryptClient(client, secretKey, null);
+    }
+     
+    public static String encryptClient(Client client, Key secretKey,
+                                       KeyProperties props) throws EncryptionException {
+        String tokenSequence = tokenizeClient(client);
+        return EncryptionUtils.encryptSequence(tokenSequence, secretKey, props);
+    }
+    
+    public static String encryptAccessToken(ServerAccessToken token, Key secretKey) throws EncryptionException {
+        return encryptAccessToken(token, secretKey, null);
+    }
+    
+    public static String encryptAccessToken(ServerAccessToken token, Key secretKey,
+                                            KeyProperties props) throws EncryptionException {
+        String tokenSequence = tokenizeServerToken(token);
+        return EncryptionUtils.encryptSequence(tokenSequence, secretKey, props);
+    }
+    
+    public static String encryptRefreshToken(RefreshToken token, Key secretKey) throws EncryptionException {
+        return encryptRefreshToken(token, secretKey, null);
+    }
+    
+    public static String encryptRefreshToken(RefreshToken token, Key secretKey,
+                                             KeyProperties props) throws EncryptionException {
+        String tokenSequence = tokenizeRefreshToken(token);
+        
+        return EncryptionUtils.encryptSequence(tokenSequence, secretKey, props);
+    }
+    
+    public static String encryptCodeGrant(ServerAuthorizationCodeGrant grant, Key secretKey) 
+        throws EncryptionException {
+        return encryptCodeGrant(grant, secretKey, null);
+    }
+    
+    public static String encryptCodeGrant(ServerAuthorizationCodeGrant grant, Key secretKey,
+                                          KeyProperties props) throws EncryptionException {
+        String tokenSequence = tokenizeCodeGrant(grant);
+        
+        return EncryptionUtils.encryptSequence(tokenSequence, secretKey, props);
+    }
+    
+    public static Client decryptClient(String encodedSequence, String encodedSecretKey) 
+        throws EncryptionException {
+        return decryptClient(encodedSequence, encodedSecretKey, new KeyProperties("AES"));
+    }
+    
+    public static Client decryptClient(String encodedSequence, String encodedSecretKey,
+                                       KeyProperties props) throws EncryptionException {
+        SecretKey key = EncryptionUtils.decodeSecretKey(encodedSecretKey, props.getKeyAlgo());
+        return decryptClient(encodedSequence, key, props);
+    }
+    
+    public static Client decryptClient(String encodedSequence, Key secretKey) throws EncryptionException {
+        return decryptClient(encodedSequence, secretKey, null);
+    }
+    
+    public static Client decryptClient(String encodedData, Key secretKey, 
+                                       KeyProperties props) throws EncryptionException {
+        String decryptedSequence = EncryptionUtils.decryptSequence(encodedData, secretKey, props);
+        return recreateClient(decryptedSequence);
+    }
+    
+    public static ServerAccessToken decryptAccessToken(OAuthDataProvider provider,
+                                                 String encodedToken, 
+                                                 String encodedSecretKey) throws EncryptionException {
+        return decryptAccessToken(provider, encodedToken, encodedSecretKey, new KeyProperties("AES"));
+    }
+    
+    public static ServerAccessToken decryptAccessToken(OAuthDataProvider provider,
+                                                 String encodedToken, 
+                                                 String encodedSecretKey,
+                                                 KeyProperties props) throws EncryptionException {
+        SecretKey key = EncryptionUtils.decodeSecretKey(encodedSecretKey, props.getKeyAlgo());
+        return decryptAccessToken(provider, encodedToken, key, props);
+    }
+    
+    public static ServerAccessToken decryptAccessToken(OAuthDataProvider provider,
+                                                 String encodedToken, 
+                                                 Key secretKey) throws EncryptionException {
+        return decryptAccessToken(provider, encodedToken, secretKey, null);
+    }
+    
+    public static ServerAccessToken decryptAccessToken(OAuthDataProvider provider,
+                                                 String encodedData, 
+                                                 Key secretKey, 
+                                                 KeyProperties props) throws EncryptionException {
+        String decryptedSequence = EncryptionUtils.decryptSequence(encodedData, secretKey, props);
+        return recreateAccessToken(provider, encodedData, decryptedSequence);
+    }
+    
+    public static RefreshToken decryptRefreshToken(OAuthDataProvider provider,
+                                                   String encodedToken, 
+                                                   String encodedSecretKey) throws EncryptionException {
+        return decryptRefreshToken(provider, encodedToken, encodedSecretKey, new KeyProperties("AES"));
+    }
+    
+    public static RefreshToken decryptRefreshToken(OAuthDataProvider provider,
+                                                  String encodedToken, 
+                                                  String encodedSecretKey,
+                                                  KeyProperties props) throws EncryptionException {
+        SecretKey key = EncryptionUtils.decodeSecretKey(encodedSecretKey, props.getKeyAlgo());
+        return decryptRefreshToken(provider, encodedToken, key, props);
+    }
+    
+    public static RefreshToken decryptRefreshToken(OAuthDataProvider provider,
+                                                   String encodedToken, 
+                                                   Key key) throws EncryptionException {
+        return decryptRefreshToken(provider, encodedToken, key, null);
+    }
+    
+    public static RefreshToken decryptRefreshToken(OAuthDataProvider provider,
+                                                   String encodedData, 
+                                                   Key key, 
+                                                   KeyProperties props) throws EncryptionException {
+        String decryptedSequence = EncryptionUtils.decryptSequence(encodedData, key, props);
+        return recreateRefreshToken(provider, encodedData, decryptedSequence);
+    }
+    
+    public static ServerAuthorizationCodeGrant decryptCodeGrant(OAuthDataProvider provider,
+                                                   String encodedToken, 
+                                                   String encodedSecretKey) throws EncryptionException {
+        return decryptCodeGrant(provider, encodedToken, encodedSecretKey, new KeyProperties("AES"));
+    }
+    
+    public static ServerAuthorizationCodeGrant decryptCodeGrant(OAuthDataProvider provider,
+                                                  String encodedToken, 
+                                                  String encodedSecretKey,
+                                                  KeyProperties props) throws EncryptionException {
+        SecretKey key = EncryptionUtils.decodeSecretKey(encodedSecretKey, props.getKeyAlgo());
+        return decryptCodeGrant(provider, encodedToken, key, props);
+    }
+    
+    public static ServerAuthorizationCodeGrant decryptCodeGrant(OAuthDataProvider provider,
+                                                   String encodedToken, 
+                                                   Key key) throws EncryptionException {
+        return decryptCodeGrant(provider, encodedToken, key, null);
+    }
+    
+    public static ServerAuthorizationCodeGrant decryptCodeGrant(OAuthDataProvider provider,
+                                                   String encodedData, 
+                                                   Key key, 
+                                                   KeyProperties props) throws EncryptionException {
+        String decryptedSequence = EncryptionUtils.decryptSequence(encodedData, key, props);
+        return recreateCodeGrant(provider, decryptedSequence);
+    }
+    
+    public static ServerAccessToken recreateAccessToken(OAuthDataProvider provider,
+                                                  String newTokenKey,
+                                                  String decryptedSequence) throws EncryptionException {
+        return recreateAccessToken(provider, newTokenKey, getParts(decryptedSequence));
+    }
+    
+    public static RefreshToken recreateRefreshToken(OAuthDataProvider provider,
+                                                    String newTokenKey,
+                                                    String decryptedSequence) throws EncryptionException {
+        String[] parts = getParts(decryptedSequence);
+        ServerAccessToken token = recreateAccessToken(provider, newTokenKey, parts);
+        return new RefreshToken(token, 
+                                newTokenKey, 
+                                parseSimpleList(parts[parts.length - 1]));
+    }
+    
+    public static ServerAuthorizationCodeGrant recreateCodeGrant(OAuthDataProvider provider,
+        String decryptedSequence) throws EncryptionException {
+        return recreateCodeGrantInternal(provider, decryptedSequence);
+    }
+    
+    public static Client recreateClient(String sequence) throws EncryptionException {
+        return recreateClientInternal(sequence);
+    }
+    
+    private static ServerAccessToken recreateAccessToken(OAuthDataProvider provider,
+                                                  String newTokenKey,
+                                                  String[] parts) {
+        
+        
+        @SuppressWarnings("serial")
+        final ServerAccessToken newToken = new ServerAccessToken(provider.getClient(parts[4]),
+                                                                 parts[1],
+                                                                 newTokenKey == null ? parts[0] : newTokenKey,
+                                                                 Long.valueOf(parts[2]),
+                                                                 Long.valueOf(parts[3])) {
+        };  
+        
+        newToken.setRefreshToken(getStringPart(parts[5]));
+        newToken.setGrantType(getStringPart(parts[6]));
+        newToken.setAudience(getStringPart(parts[7]));
+        newToken.setParameters(parseSimpleMap(parts[8]));
+        
+        // Permissions
+        if (!parts[9].trim().isEmpty()) {
+            List<OAuthPermission> perms = new LinkedList<OAuthPermission>(); 
+            String[] allPermParts = parts[9].split("\\.");
+            for (int i = 0; i + 4 < allPermParts.length; i = i + 5) {
+                OAuthPermission perm = new OAuthPermission(allPermParts[i], allPermParts[i + 1]);
+                perm.setDefault(Boolean.valueOf(allPermParts[i + 2]));
+                perm.setHttpVerbs(parseSimpleList(allPermParts[i + 3]));
+                perm.setUris(parseSimpleList(allPermParts[i + 4]));
+                perms.add(perm);
+            }
+            newToken.setScopes(perms);
+        }
+        //UserSubject:
+        newToken.setSubject(recreateUserSubject(parts[10]));
+                
+        return newToken;
+    }
+    
+    private static String tokenizeRefreshToken(RefreshToken token) {
+        String seq = tokenizeServerToken(token);
+        return seq + SEP + token.getAccessTokens().toString();
+    }
+    
+    private static String tokenizeServerToken(ServerAccessToken token) {
+        StringBuilder state = new StringBuilder();
+        // 0: key
+        state.append(tokenizeString(token.getTokenKey()));
+        // 1: type
+        state.append(SEP);
+        state.append(tokenizeString(token.getTokenType()));
+        // 2: expiresIn 
+        state.append(SEP);
+        state.append(token.getExpiresIn());
+        // 3: issuedAt
+        state.append(SEP);
+        state.append(token.getIssuedAt());
+        // 4: client id
+        state.append(SEP);
+        state.append(tokenizeString(token.getClient().getClientId()));
+        // 5: refresh token
+        state.append(SEP);
+        state.append(tokenizeString(token.getRefreshToken()));
+        // 6: grant type
+        state.append(SEP);
+        state.append(tokenizeString(token.getGrantType()));
+        // 7: audience
+        state.append(SEP);
+        state.append(tokenizeString(token.getAudience()));
+        // 8: other parameters
+        state.append(SEP);
+        // {key=value, key=value}
+        state.append(token.getParameters().toString());
+        // 9: permissions
+        state.append(SEP);
+        if (token.getScopes().isEmpty()) {
+            state.append(" ");
+        } else {
+            for (OAuthPermission p : token.getScopes()) {
+                // 9.1
+                state.append(tokenizeString(p.getPermission()));
+                state.append(".");
+                // 9.2
+                state.append(tokenizeString(p.getDescription()));
+                state.append(".");
+                // 9.3
+                state.append(p.isDefault());
+                state.append(".");
+                // 9.4
+                state.append(p.getHttpVerbs().toString());
+                state.append(".");
+                // 9.5
+                state.append(p.getUris().toString());
+            }
+        }
+        state.append(SEP);
+        // 10: user subject
+        tokenizeUserSubject(state, token.getSubject());
+        
+        return state.toString();
+    }
+    
+
+    private static Client recreateClientInternal(String sequence) {
+        String[] parts = getParts(sequence);
+        Client c = new Client(parts[0], 
+                              parts[1], 
+                              Boolean.valueOf(parts[2]), 
+                              getStringPart(parts[3]), getStringPart(parts[4]));
+        c.setApplicationDescription(getStringPart(parts[5]));
+        c.setApplicationLogoUri(getStringPart(parts[6]));
+        c.setAllowedGrantTypes(parseSimpleList(parts[7]));
+        c.setRegisteredScopes(parseSimpleList(parts[8]));
+        c.setRedirectUris(parseSimpleList(parts[9]));
+        c.setRegisteredAudiences(parseSimpleList(parts[10]));
+        c.setProperties(parseSimpleMap(parts[11]));
+        c.setSubject(recreateUserSubject(parts[12]));
+        return c; 
+    }
+    private static String tokenizeClient(Client client) {
+        StringBuilder state = new StringBuilder();
+        // 0: id
+        state.append(tokenizeString(client.getClientId()));
+        state.append(SEP);
+        // 1: secret
+        state.append(tokenizeString(client.getClientSecret()));
+        state.append(SEP);
+        // 2: confidentiality
+        state.append(client.isConfidential());
+        state.append(SEP);
+        // 3: app name
+        state.append(tokenizeString(client.getApplicationName()));
+        state.append(SEP);
+        // 4: app web URI
+        state.append(tokenizeString(client.getApplicationWebUri()));
+        state.append(SEP);
+        // 5: app description
+        state.append(tokenizeString(client.getApplicationDescription()));
+        state.append(SEP);
+        // 6: app logo URI
+        state.append(tokenizeString(client.getApplicationLogoUri()));
+        state.append(SEP);
+        // 7: grants
+        state.append(client.getAllowedGrantTypes().toString());
+        state.append(SEP);
+        // 8: redirect URIs
+        state.append(client.getRedirectUris().toString());
+        state.append(SEP);
+        // 9: registered scopes
+        state.append(client.getRegisteredScopes().toString());
+        state.append(SEP);
+        // 10: registered audiences
+        state.append(client.getRegisteredAudiences().toString());
+        state.append(SEP);
+        // 11: properties
+        state.append(client.getProperties().toString());
+        state.append(SEP);
+        // 12: subject
+        tokenizeUserSubject(state, client.getSubject());
+        
+        return state.toString();
+    }
+    private static ServerAuthorizationCodeGrant recreateCodeGrantInternal(OAuthDataProvider provider,
+                                                                          String sequence) {
+        String[] parts = getParts(sequence);
+        ServerAuthorizationCodeGrant grant = new ServerAuthorizationCodeGrant(provider.getClient(parts[0]),
+                                                                              parts[1],
+                                                                              Long.valueOf(parts[2]),
+                                                                              Long.valueOf(parts[3]));
+        grant.setRedirectUri(getStringPart(parts[4]));
+        grant.setAudience(getStringPart(parts[5]));
+        grant.setClientCodeVerifier(getStringPart(parts[6]));
+        grant.setApprovedScopes(parseSimpleList(parts[7]));
+        grant.setSubject(recreateUserSubject(parts[8]));
+        return grant; 
+    }
+    private static String tokenizeCodeGrant(ServerAuthorizationCodeGrant grant) {
+        StringBuilder state = new StringBuilder();
+        // 0: client id
+        state.append(grant.getClient().getClientId());
+        state.append(SEP);
+        // 1: code
+        state.append(tokenizeString(grant.getCode()));
+        state.append(SEP);
+        // 2: expiresIn
+        state.append(grant.getExpiresIn());
+        state.append(SEP);
+        // 3: issuedAt
+        state.append(grant.getIssuedAt());
+        state.append(SEP);
+        // 4: redirect URI
+        state.append(tokenizeString(grant.getRedirectUri()));
+        state.append(SEP);
+        // 5: audience
+        state.append(tokenizeString(grant.getAudience()));
+        state.append(SEP);
+        // 6: code verifier
+        state.append(tokenizeString(grant.getClientCodeVerifier()));
+        state.append(SEP);
+        // 7: approved scopes
+        state.append(grant.getApprovedScopes().toString());
+        state.append(SEP);
+        // 8: subject
+        tokenizeUserSubject(state, grant.getSubject());
+        
+        return state.toString();
+    }
+    
+    private static String getStringPart(String str) {
+        return " ".equals(str) ? null : str;
+    }
+    
+    private static String prepareSimpleString(String str) {
+        return str.trim().isEmpty() ? "" : str.substring(1, str.length() - 1);
+    }
+    
+    private static List<String> parseSimpleList(String listStr) {
+        String pureStringList = prepareSimpleString(listStr);
+        if (pureStringList.isEmpty()) {
+            return Collections.emptyList();
+        } else {
+            return Arrays.asList(pureStringList.split(","));
+        }
+    }
+    
+    private static Map<String, String> parseSimpleMap(String mapStr) {
+        Map<String, String> props = new HashMap<String, String>();
+        List<String> entries = parseSimpleList(mapStr);
+        for (String entry : entries) {
+            String[] pair = entry.split("=");
+            props.put(pair[0], pair[1]);
+        }
+        return props;
+    }
+    
+    private static String[] getParts(String sequence) {
+        return sequence.split("\\" + SEP);
+    }
+    
+    private static UserSubject recreateUserSubject(String sequence) {
+        UserSubject subject = null;
+        if (!sequence.trim().isEmpty()) {
+            String[] subjectParts = sequence.split("\\.");
+            subject = new UserSubject(getStringPart(subjectParts[0]), getStringPart(subjectParts[1]));
+            subject.setRoles(parseSimpleList(subjectParts[2]));
+            subject.setProperties(parseSimpleMap(subjectParts[3]));
+        }
+        return subject;
+        
+        
+    }
+    
+    private static void tokenizeUserSubject(StringBuilder state, UserSubject subject) {
+        if (subject != null) {
+            // 1
+            state.append(tokenizeString(subject.getLogin()));
+            state.append(".");
+            // 2
+            state.append(tokenizeString(subject.getId()));
+            state.append(".");
+            // 3
+            state.append(subject.getRoles().toString());
+            state.append(".");
+            // 4
+            state.append(subject.getProperties().toString());
+        } else {
+            state.append(" ");
+        }
+    }
+    
+    private static String tokenizeString(String str) {
+        return str != null ? str : " ";
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/0e463319/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/CodeGrantEncryptingDataProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/CodeGrantEncryptingDataProvider.java b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/CodeGrantEncryptingDataProvider.java
deleted file mode 100644
index 1a6251b..0000000
--- a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/CodeGrantEncryptingDataProvider.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * 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.utils;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeDataProvider;
-import org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeRegistration;
-import org.apache.cxf.rs.security.oauth2.grants.code.ServerAuthorizationCodeGrant;
-import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
-
-public class CodeGrantEncryptingDataProvider extends EncryptingDataProvider
-    implements AuthorizationCodeDataProvider {
-
-    private Set<String> grants = new HashSet<String>();
-    
-    public CodeGrantEncryptingDataProvider() throws Exception {
-        super();
-    }
-    
-    @Override
-    public ServerAuthorizationCodeGrant createCodeGrant(AuthorizationCodeRegistration reg)
-        throws OAuthServiceException {
-        ServerAuthorizationCodeGrant grant = 
-            new ServerAuthorizationCodeGrant(reg.getClient(), 123);
-        grant.setAudience(reg.getAudience());
-        String encrypted = ModelEncryptionSupport.encryptCodeGrant(grant, key);
-        grant.setCode(encrypted);
-        grants.add(encrypted);
-        return grant;
-    }
-
-    @Override
-    public ServerAuthorizationCodeGrant removeCodeGrant(String code) throws OAuthServiceException {
-        grants.remove(code);
-        return ModelEncryptionSupport.decryptCodeGrant(this, code, key);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cxf/blob/0e463319/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/EncryptingDataProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/EncryptingDataProvider.java b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/EncryptingDataProvider.java
deleted file mode 100644
index fc9bf56..0000000
--- a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/EncryptingDataProvider.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/**
- * 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.utils;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.crypto.SecretKey;
-
-import org.apache.cxf.rs.security.oauth2.common.AccessTokenRegistration;
-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.common.ServerAccessToken;
-import org.apache.cxf.rs.security.oauth2.common.UserSubject;
-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.tokens.bearer.BearerAccessToken;
-import org.apache.cxf.rs.security.oauth2.tokens.refresh.RefreshToken;
-
-public class EncryptingDataProvider implements OAuthDataProvider {
-
-    SecretKey key;
-    private Map<String, String> clients;
-    private Set<String> tokens = new HashSet<String>();
-    private Map<String, String> refreshTokens = new HashMap<String, String>();
-    
-    public EncryptingDataProvider() throws Exception {
-        key = EncryptionUtils.getSecretKey();
-        String encryptedClient = ModelEncryptionSupport.encryptClient(new Client("1", "2", true), key);
-        clients = Collections.singletonMap("1", encryptedClient);
-    }
-    
-    @Override
-    public Client getClient(String clientId) throws OAuthServiceException {
-        return ModelEncryptionSupport.decryptClient(clients.get(clientId), key);
-    }
-
-    @Override
-    public ServerAccessToken createAccessToken(AccessTokenRegistration accessTokenReg)
-        throws OAuthServiceException {
-        
-        ServerAccessToken token = createAccessTokenInternal(accessTokenReg);
-        encryptAccessToken(token);
-        return token;
-    }
-    
-    @Override
-    public ServerAccessToken getAccessToken(String accessTokenKey) throws OAuthServiceException {
-        return ModelEncryptionSupport.decryptAccessToken(this, accessTokenKey, key);
-    }
-
-    @Override
-    public ServerAccessToken refreshAccessToken(Client client, String refreshToken,
-                                                List<String> requestedScopes)
-        throws OAuthServiceException {
-        String encrypted = refreshTokens.remove(refreshToken);
-        ServerAccessToken token = ModelEncryptionSupport.decryptAccessToken(this, encrypted, key);
-        tokens.remove(token.getTokenKey());
-        
-        // create a new refresh token
-        createRefreshToken(token);
-        // possibly update other token properties 
-        encryptAccessToken(token);
-        
-        return token;
-    }
-
-    @Override
-    public void removeAccessToken(ServerAccessToken accessToken) throws OAuthServiceException {
-        tokens.remove(accessToken.getTokenKey());
-    }
-
-    @Override
-    public void revokeToken(Client client, String token, String tokenTypeHint)
-        throws OAuthServiceException {
-        // the fast way: if it is the refresh token then there will be a matching value for it
-        String accessToken = refreshTokens.remove(token);
-        // if no matching value then the token parameter is access token key
-        tokens.remove(accessToken == null ? token : accessToken);
-    }
-
-    @Override
-    public List<OAuthPermission> convertScopeToPermissions(Client client, List<String> requestedScope) {
-        // assuming that no specific scopes is documented/supported
-        return Collections.emptyList();
-    }
-    
-    @Override
-    public ServerAccessToken getPreauthorizedToken(Client client, List<String> requestedScopes,
-                                                   UserSubject subject, String grantType)
-        throws OAuthServiceException {
-        // This is an optimization useful in cases where a client requests an authorization code: 
-        // if a user has already provided a given client with a pre-authorized token then challenging 
-        // a user with yet another form asking for the authorization is redundant  
-        return null;
-    }
-    
-    BearerAccessToken createAccessTokenInternal(AccessTokenRegistration accessTokenReg) {
-        BearerAccessToken token = new BearerAccessToken(accessTokenReg.getClient(), 3600L);
-        token.setSubject(accessTokenReg.getSubject());
-        
-        createRefreshToken(token);
-        
-        token.setGrantType(accessTokenReg.getGrantType());
-        token.setAudience(accessTokenReg.getAudience());
-        token.setParameters(Collections.singletonMap("param", "value"));
-        token.setScopes(Collections.singletonList(
-            new OAuthPermission("read", "read permission")));
-        return token;
-    }
-    
-    private void encryptAccessToken(ServerAccessToken token) {
-        String encryptedToken = ModelEncryptionSupport.encryptAccessToken(token, key);
-        tokens.add(encryptedToken);
-        refreshTokens.put(token.getRefreshToken(), encryptedToken);
-        token.setTokenKey(encryptedToken);
-    }
-    
-    private void createRefreshToken(ServerAccessToken token) {
-        RefreshToken refreshToken = new RefreshToken(token.getClient(),
-                                                     "refresh",
-                                                     1200L,
-                                                     OAuthUtils.getIssuedAt());
-        
-        String encryptedRefreshToken = ModelEncryptionSupport.encryptRefreshToken(refreshToken, key);
-        token.setRefreshToken(encryptedRefreshToken);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cxf/blob/0e463319/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/EncryptionUtilsTest.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/EncryptionUtilsTest.java b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/EncryptionUtilsTest.java
deleted file mode 100644
index 7f153e5..0000000
--- a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/EncryptionUtilsTest.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/**
- * 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.utils;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.lang.annotation.Annotation;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.util.Collections;
-import java.util.List;
-
-import javax.crypto.SecretKey;
-import javax.ws.rs.core.MediaType;
-
-import org.apache.cxf.jaxrs.impl.MetadataMap;
-import org.apache.cxf.jaxrs.provider.json.JSONProvider;
-import org.apache.cxf.rs.security.oauth2.common.AccessTokenRegistration;
-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.common.ServerAccessToken;
-import org.apache.cxf.rs.security.oauth2.common.UserSubject;
-import org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeRegistration;
-import org.apache.cxf.rs.security.oauth2.grants.code.ServerAuthorizationCodeGrant;
-import org.apache.cxf.rs.security.oauth2.tokens.bearer.BearerAccessToken;
-import org.apache.cxf.rs.security.oauth2.tokens.refresh.RefreshToken;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class EncryptionUtilsTest extends Assert {
-    
-    private CodeGrantEncryptingDataProvider p;
-    
-    @Before
-    public void setUp() throws Exception {
-        p = new CodeGrantEncryptingDataProvider();
-    }
-    
-    @After
-    public void tearDown() {
-        p = null;
-    }
-    
-    @Test
-    public void testEncryptDecryptToken() throws Exception {
-        AccessTokenRegistration atr = prepareTokenRegistration();
-        
-        // encrypt
-        ServerAccessToken token = p.createAccessToken(atr);
-        ServerAccessToken token2 = p.getAccessToken(token.getTokenKey());
-        
-        // compare tokens
-        compareAccessTokens(token, token2);
-    }
-    
-    @Test
-    public void testEncryptDecryptCodeGrant() throws Exception {
-        AuthorizationCodeRegistration codeReg = new AuthorizationCodeRegistration(); 
-        codeReg.setAudience("http://bar");
-        codeReg.setClient(p.getClient("1"));
-        ServerAuthorizationCodeGrant grant = p.createCodeGrant(codeReg);
-        ServerAuthorizationCodeGrant grant2 = p.removeCodeGrant(grant.getCode());
-        assertEquals("http://bar", grant2.getAudience());
-        assertEquals("1", grant2.getClient().getClientId());
-    }
-    
-    @Test
-    public void testBearerTokenCertAndSecretKey() throws Exception {
-        AccessTokenRegistration atr = prepareTokenRegistration();
-        BearerAccessToken token = p.createAccessTokenInternal(atr);
-        
-        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
-        KeyPair keyPair = kpg.generateKeyPair();
-        PublicKey publicKey = keyPair.getPublic();
-        PrivateKey privateKey = keyPair.getPrivate();
-        
-        SecretKey secretKey = EncryptionUtils.getSecretKey();
-        String encryptedSecretKey = EncryptionUtils.encryptSecretKey(secretKey, publicKey);
-        
-        String encryptedToken = ModelEncryptionSupport.encryptAccessToken(token, secretKey);
-        token.setTokenKey(encryptedToken);
-        SecretKey decryptedSecretKey = EncryptionUtils.decryptSecretKey(encryptedSecretKey, privateKey);
-        ServerAccessToken token2 = ModelEncryptionSupport.decryptAccessToken(p, encryptedToken, decryptedSecretKey);
-        // compare tokens
-        compareAccessTokens(token, token2);
-    }
-    
-    @Test
-    public void testBearerTokenJSON() throws Exception {
-        AccessTokenRegistration atr = prepareTokenRegistration();
-        
-        BearerAccessToken token = p.createAccessTokenInternal(atr);
-        JSONProvider<BearerAccessToken> jsonp = new JSONProvider<BearerAccessToken>();
-        jsonp.setMarshallAsJaxbElement(true);
-        jsonp.setUnmarshallAsJaxbElement(true);
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        jsonp.writeTo(token, BearerAccessToken.class, new Annotation[]{}, MediaType.APPLICATION_JSON_TYPE,
-                      new MetadataMap<String, Object>(), bos);
-        
-        String encrypted = EncryptionUtils.encryptSequence(bos.toString(), p.key);
-        String decrypted = EncryptionUtils.decryptSequence(encrypted, p.key);
-        ServerAccessToken token2 = jsonp.readFrom(BearerAccessToken.class, BearerAccessToken.class, 
-                                                  new Annotation[]{}, MediaType.APPLICATION_JSON_TYPE, 
-                                                  new MetadataMap<String, String>(), 
-                                                  new ByteArrayInputStream(decrypted.getBytes()));
-        
-        // compare tokens
-        compareAccessTokens(token, token2);
-    }
-    
-    @Test
-    public void testBearerTokenJSONCertificate() throws Exception {
-        
-        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
-        KeyPair keyPair = kpg.generateKeyPair();
-        PublicKey publicKey = keyPair.getPublic();
-        PrivateKey privateKey = keyPair.getPrivate();
-        
-        AccessTokenRegistration atr = prepareTokenRegistration();
-        
-        BearerAccessToken token = p.createAccessTokenInternal(atr);
-        JSONProvider<BearerAccessToken> jsonp = new JSONProvider<BearerAccessToken>();
-        jsonp.setMarshallAsJaxbElement(true);
-        jsonp.setUnmarshallAsJaxbElement(true);
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        jsonp.writeTo(token, BearerAccessToken.class, new Annotation[]{}, MediaType.APPLICATION_JSON_TYPE,
-                      new MetadataMap<String, Object>(), bos);
-        
-        SecretKeyProperties props1 = new SecretKeyProperties(publicKey.getAlgorithm());
-        String encrypted = EncryptionUtils.encryptSequence(bos.toString(), publicKey, props1);
-        SecretKeyProperties props2 = new SecretKeyProperties(privateKey.getAlgorithm());
-        String decrypted = EncryptionUtils.decryptSequence(encrypted, privateKey, props2);
-        ServerAccessToken token2 = jsonp.readFrom(BearerAccessToken.class, BearerAccessToken.class, 
-                                                  new Annotation[]{}, MediaType.APPLICATION_JSON_TYPE, 
-                                                  new MetadataMap<String, String>(), 
-                                                  new ByteArrayInputStream(decrypted.getBytes()));
-        
-        // compare tokens
-        compareAccessTokens(token, token2);
-    }
-    
-    @Test
-    public void testClientJSON() throws Exception {
-        Client c = new Client("client", "secret", true);
-        c.setSubject(new UserSubject("subject", "id"));
-        JSONProvider<Client> jsonp = new JSONProvider<Client>();
-        jsonp.setMarshallAsJaxbElement(true);
-        jsonp.setUnmarshallAsJaxbElement(true);
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        jsonp.writeTo(c, Client.class, new Annotation[]{}, MediaType.APPLICATION_JSON_TYPE,
-                      new MetadataMap<String, Object>(), bos);
-        String encrypted = EncryptionUtils.encryptSequence(bos.toString(), p.key);
-        String decrypted = EncryptionUtils.decryptSequence(encrypted, p.key);
-        Client c2 = jsonp.readFrom(Client.class, Client.class, 
-                                                  new Annotation[]{}, MediaType.APPLICATION_JSON_TYPE, 
-                                                  new MetadataMap<String, String>(), 
-                                                  new ByteArrayInputStream(decrypted.getBytes()));
-        
-        assertEquals(c.getClientId(), c2.getClientId());
-        assertEquals(c.getClientSecret(), c2.getClientSecret());
-        assertTrue(c2.isConfidential());
-        assertEquals("subject", c2.getSubject().getLogin());
-        assertEquals("id", c2.getSubject().getId());
-    }
-    
-    @Test
-    public void testCodeGrantJSON() throws Exception {
-        Client c = new Client("client", "secret", true);
-        ServerAuthorizationCodeGrant grant = new ServerAuthorizationCodeGrant(c, "code", 1, 2); 
-        JSONProvider<ServerAuthorizationCodeGrant> jsonp = new JSONProvider<ServerAuthorizationCodeGrant>();
-        jsonp.setMarshallAsJaxbElement(true);
-        jsonp.setUnmarshallAsJaxbElement(true);
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        jsonp.writeTo(grant, ServerAuthorizationCodeGrant.class, new Annotation[]{}, 
-                      MediaType.APPLICATION_JSON_TYPE,
-                      new MetadataMap<String, Object>(), bos);
-        
-        String encrypted = EncryptionUtils.encryptSequence(bos.toString(), p.key);
-        String decrypted = EncryptionUtils.decryptSequence(encrypted, p.key);
-        ServerAuthorizationCodeGrant grant2 = jsonp.readFrom(ServerAuthorizationCodeGrant.class,
-                                                             Client.class, 
-                                                  new Annotation[]{}, MediaType.APPLICATION_JSON_TYPE, 
-                                                  new MetadataMap<String, String>(), 
-                                                  new ByteArrayInputStream(decrypted.getBytes()));
-        assertEquals("code", grant2.getCode());
-        assertEquals(1, grant2.getExpiresIn());
-        assertEquals(2, grant2.getIssuedAt());
-    }
-    
-    private void compareAccessTokens(ServerAccessToken token, ServerAccessToken token2) {
-        assertEquals(token.getTokenKey(), token2.getTokenKey());
-        assertEquals(token.getTokenType(), token2.getTokenType());
-        assertEquals(token.getIssuedAt(), token2.getIssuedAt());
-        assertEquals(token.getExpiresIn(), token2.getExpiresIn());
-        Client regClient1 = token.getClient();
-        Client regClient2 = token2.getClient();
-        assertEquals(regClient1.getClientId(), regClient2.getClientId());
-        assertNull(regClient2.getApplicationDescription());
-        UserSubject endUser1 = token.getSubject();
-        UserSubject endUser2 = token2.getSubject();
-        assertEquals(endUser1.getLogin(), endUser2.getLogin());
-        assertEquals(endUser1.getId(), endUser2.getId());
-        assertEquals(endUser1.getRoles(), endUser2.getRoles());
-        
-        assertEquals(token.getRefreshToken(), token2.getRefreshToken());
-        assertEquals(token.getAudience(), token2.getAudience());
-        assertEquals(token.getGrantType(), token2.getGrantType());
-        assertEquals(token.getParameters(), token2.getParameters());
-        
-        List<OAuthPermission> permissions = token.getScopes();
-        List<OAuthPermission> permissions2 = token2.getScopes();
-        assertEquals(1, permissions.size());
-        assertEquals(1, permissions2.size());
-        OAuthPermission perm1 = permissions.get(0);
-        OAuthPermission perm2 = permissions2.get(0);
-        assertEquals(perm1.getPermission(), perm2.getPermission());
-        assertEquals(perm1.getDescription(), perm2.getDescription());
-        
-        RefreshToken refreshToken = 
-            ModelEncryptionSupport.decryptRefreshToken(p, token2.getRefreshToken(), p.key);
-        assertEquals(1200L, refreshToken.getExpiresIn());
-    }
-    
-    private AccessTokenRegistration prepareTokenRegistration() {
-        AccessTokenRegistration atr = new AccessTokenRegistration();
-        Client regClient = p.getClient("1");
-        atr.setClient(regClient);
-        atr.setGrantType("code");
-        atr.setAudience("http://localhost");
-        UserSubject endUser = new UserSubject("Barry", "BarryId");
-        atr.setSubject(endUser);
-        endUser.setRoles(Collections.singletonList("role1"));
-        return atr;
-    }
-    
-// TODO: remove once the wiki documentation is updated
-//  KeyStore keyStore = loadKeyStore(); 
-//  Certificate cert = keyStore.getCertificate("alice");
-//  PublicKey publicKey = cert.getPublicKey();
-//  KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry)
-//      keyStore.getEntry("alice", new KeyStore.PasswordProtection(
-//           new char[]{'p', 'a', 's', 's', 'w', 'o', 'r', 'd'}));
-//  PrivateKey privateKey = pkEntry.getPrivateKey();
-    
-    
-//    private KeyStore loadKeyStore() throws Exception {
-//        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
-//        InputStream is = this.getClass().getResourceAsStream("alice.jks");
-//        ks.load(is, new char[]{'p', 'a', 's', 's', 'w', 'o', 'r', 'd'});
-//        return ks;
-//    }
-}

http://git-wip-us.apache.org/repos/asf/cxf/blob/0e463319/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/crypto/CodeGrantEncryptingDataProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/crypto/CodeGrantEncryptingDataProvider.java b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/crypto/CodeGrantEncryptingDataProvider.java
new file mode 100644
index 0000000..04056bf
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/crypto/CodeGrantEncryptingDataProvider.java
@@ -0,0 +1,55 @@
+/**
+ * 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.utils.crypto;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeDataProvider;
+import org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeRegistration;
+import org.apache.cxf.rs.security.oauth2.grants.code.ServerAuthorizationCodeGrant;
+import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
+
+public class CodeGrantEncryptingDataProvider extends EncryptingDataProvider
+    implements AuthorizationCodeDataProvider {
+
+    private Set<String> grants = new HashSet<String>();
+    
+    public CodeGrantEncryptingDataProvider() throws Exception {
+        super();
+    }
+    
+    @Override
+    public ServerAuthorizationCodeGrant createCodeGrant(AuthorizationCodeRegistration reg)
+        throws OAuthServiceException {
+        ServerAuthorizationCodeGrant grant = 
+            new ServerAuthorizationCodeGrant(reg.getClient(), 123);
+        grant.setAudience(reg.getAudience());
+        String encrypted = ModelEncryptionSupport.encryptCodeGrant(grant, key);
+        grant.setCode(encrypted);
+        grants.add(encrypted);
+        return grant;
+    }
+
+    @Override
+    public ServerAuthorizationCodeGrant removeCodeGrant(String code) throws OAuthServiceException {
+        grants.remove(code);
+        return ModelEncryptionSupport.decryptCodeGrant(this, code, key);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/0e463319/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/crypto/EncryptingDataProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/crypto/EncryptingDataProvider.java b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/crypto/EncryptingDataProvider.java
new file mode 100644
index 0000000..bf0b7f7
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/crypto/EncryptingDataProvider.java
@@ -0,0 +1,149 @@
+/**
+ * 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.utils.crypto;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.crypto.SecretKey;
+
+import org.apache.cxf.rs.security.oauth2.common.AccessTokenRegistration;
+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.common.ServerAccessToken;
+import org.apache.cxf.rs.security.oauth2.common.UserSubject;
+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.tokens.bearer.BearerAccessToken;
+import org.apache.cxf.rs.security.oauth2.tokens.refresh.RefreshToken;
+import org.apache.cxf.rs.security.oauth2.utils.OAuthUtils;
+
+public class EncryptingDataProvider implements OAuthDataProvider {
+
+    SecretKey key;
+    private Map<String, String> clients;
+    private Set<String> tokens = new HashSet<String>();
+    private Map<String, String> refreshTokens = new HashMap<String, String>();
+    
+    public EncryptingDataProvider() throws Exception {
+        key = EncryptionUtils.getSecretKey("AES");
+        String encryptedClient = ModelEncryptionSupport.encryptClient(new Client("1", "2", true), key);
+        clients = Collections.singletonMap("1", encryptedClient);
+    }
+    
+    @Override
+    public Client getClient(String clientId) throws OAuthServiceException {
+        return ModelEncryptionSupport.decryptClient(clients.get(clientId), key);
+    }
+
+    @Override
+    public ServerAccessToken createAccessToken(AccessTokenRegistration accessTokenReg)
+        throws OAuthServiceException {
+        
+        ServerAccessToken token = createAccessTokenInternal(accessTokenReg);
+        encryptAccessToken(token);
+        return token;
+    }
+    
+    @Override
+    public ServerAccessToken getAccessToken(String accessTokenKey) throws OAuthServiceException {
+        return ModelEncryptionSupport.decryptAccessToken(this, accessTokenKey, key);
+    }
+
+    @Override
+    public ServerAccessToken refreshAccessToken(Client client, String refreshToken,
+                                                List<String> requestedScopes)
+        throws OAuthServiceException {
+        String encrypted = refreshTokens.remove(refreshToken);
+        ServerAccessToken token = ModelEncryptionSupport.decryptAccessToken(this, encrypted, key);
+        tokens.remove(token.getTokenKey());
+        
+        // create a new refresh token
+        createRefreshToken(token);
+        // possibly update other token properties 
+        encryptAccessToken(token);
+        
+        return token;
+    }
+
+    @Override
+    public void removeAccessToken(ServerAccessToken accessToken) throws OAuthServiceException {
+        tokens.remove(accessToken.getTokenKey());
+    }
+
+    @Override
+    public void revokeToken(Client client, String token, String tokenTypeHint)
+        throws OAuthServiceException {
+        // the fast way: if it is the refresh token then there will be a matching value for it
+        String accessToken = refreshTokens.remove(token);
+        // if no matching value then the token parameter is access token key
+        tokens.remove(accessToken == null ? token : accessToken);
+    }
+
+    @Override
+    public List<OAuthPermission> convertScopeToPermissions(Client client, List<String> requestedScope) {
+        // assuming that no specific scopes is documented/supported
+        return Collections.emptyList();
+    }
+    
+    @Override
+    public ServerAccessToken getPreauthorizedToken(Client client, List<String> requestedScopes,
+                                                   UserSubject subject, String grantType)
+        throws OAuthServiceException {
+        // This is an optimization useful in cases where a client requests an authorization code: 
+        // if a user has already provided a given client with a pre-authorized token then challenging 
+        // a user with yet another form asking for the authorization is redundant  
+        return null;
+    }
+    
+    BearerAccessToken createAccessTokenInternal(AccessTokenRegistration accessTokenReg) {
+        BearerAccessToken token = new BearerAccessToken(accessTokenReg.getClient(), 3600L);
+        token.setSubject(accessTokenReg.getSubject());
+        
+        createRefreshToken(token);
+        
+        token.setGrantType(accessTokenReg.getGrantType());
+        token.setAudience(accessTokenReg.getAudience());
+        token.setParameters(Collections.singletonMap("param", "value"));
+        token.setScopes(Collections.singletonList(
+            new OAuthPermission("read", "read permission")));
+        return token;
+    }
+    
+    private void encryptAccessToken(ServerAccessToken token) {
+        String encryptedToken = ModelEncryptionSupport.encryptAccessToken(token, key);
+        tokens.add(encryptedToken);
+        refreshTokens.put(token.getRefreshToken(), encryptedToken);
+        token.setTokenKey(encryptedToken);
+    }
+    
+    private void createRefreshToken(ServerAccessToken token) {
+        RefreshToken refreshToken = new RefreshToken(token.getClient(),
+                                                     "refresh",
+                                                     1200L,
+                                                     OAuthUtils.getIssuedAt());
+        
+        String encryptedRefreshToken = ModelEncryptionSupport.encryptRefreshToken(refreshToken, key);
+        token.setRefreshToken(encryptedRefreshToken);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/0e463319/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/crypto/EncryptionUtilsTest.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/crypto/EncryptionUtilsTest.java b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/crypto/EncryptionUtilsTest.java
new file mode 100644
index 0000000..19c20ae
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/utils/crypto/EncryptionUtilsTest.java
@@ -0,0 +1,273 @@
+/**
+ * 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.utils.crypto;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.lang.annotation.Annotation;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.util.Collections;
+import java.util.List;
+
+import javax.crypto.SecretKey;
+import javax.ws.rs.core.MediaType;
+
+import org.apache.cxf.jaxrs.impl.MetadataMap;
+import org.apache.cxf.jaxrs.provider.json.JSONProvider;
+import org.apache.cxf.rs.security.oauth2.common.AccessTokenRegistration;
+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.common.ServerAccessToken;
+import org.apache.cxf.rs.security.oauth2.common.UserSubject;
+import org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeRegistration;
+import org.apache.cxf.rs.security.oauth2.grants.code.ServerAuthorizationCodeGrant;
+import org.apache.cxf.rs.security.oauth2.tokens.bearer.BearerAccessToken;
+import org.apache.cxf.rs.security.oauth2.tokens.refresh.RefreshToken;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class EncryptionUtilsTest extends Assert {
+    
+    private CodeGrantEncryptingDataProvider p;
+    
+    @Before
+    public void setUp() throws Exception {
+        p = new CodeGrantEncryptingDataProvider();
+    }
+    
+    @After
+    public void tearDown() {
+        p = null;
+    }
+    
+    @Test
+    public void testEncryptDecryptToken() throws Exception {
+        AccessTokenRegistration atr = prepareTokenRegistration();
+        
+        // encrypt
+        ServerAccessToken token = p.createAccessToken(atr);
+        ServerAccessToken token2 = p.getAccessToken(token.getTokenKey());
+        
+        // compare tokens
+        compareAccessTokens(token, token2);
+    }
+    
+    @Test
+    public void testEncryptDecryptCodeGrant() throws Exception {
+        AuthorizationCodeRegistration codeReg = new AuthorizationCodeRegistration(); 
+        codeReg.setAudience("http://bar");
+        codeReg.setClient(p.getClient("1"));
+        ServerAuthorizationCodeGrant grant = p.createCodeGrant(codeReg);
+        ServerAuthorizationCodeGrant grant2 = p.removeCodeGrant(grant.getCode());
+        assertEquals("http://bar", grant2.getAudience());
+        assertEquals("1", grant2.getClient().getClientId());
+    }
+    
+    @Test
+    public void testBearerTokenCertAndSecretKey() throws Exception {
+        AccessTokenRegistration atr = prepareTokenRegistration();
+        BearerAccessToken token = p.createAccessTokenInternal(atr);
+        
+        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+        KeyPair keyPair = kpg.generateKeyPair();
+        PublicKey publicKey = keyPair.getPublic();
+        PrivateKey privateKey = keyPair.getPrivate();
+        
+        SecretKey secretKey = EncryptionUtils.getSecretKey("AES");
+        String encryptedSecretKey = EncryptionUtils.encryptSecretKey(secretKey, publicKey);
+        
+        String encryptedToken = ModelEncryptionSupport.encryptAccessToken(token, secretKey);
+        token.setTokenKey(encryptedToken);
+        SecretKey decryptedSecretKey = EncryptionUtils.decryptSecretKey(encryptedSecretKey, privateKey);
+        ServerAccessToken token2 = ModelEncryptionSupport.decryptAccessToken(p, encryptedToken, decryptedSecretKey);
+        // compare tokens
+        compareAccessTokens(token, token2);
+    }
+    
+    @Test
+    public void testBearerTokenJSON() throws Exception {
+        AccessTokenRegistration atr = prepareTokenRegistration();
+        
+        BearerAccessToken token = p.createAccessTokenInternal(atr);
+        JSONProvider<BearerAccessToken> jsonp = new JSONProvider<BearerAccessToken>();
+        jsonp.setMarshallAsJaxbElement(true);
+        jsonp.setUnmarshallAsJaxbElement(true);
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        jsonp.writeTo(token, BearerAccessToken.class, new Annotation[]{}, MediaType.APPLICATION_JSON_TYPE,
+                      new MetadataMap<String, Object>(), bos);
+        
+        String encrypted = EncryptionUtils.encryptSequence(bos.toString(), p.key);
+        String decrypted = EncryptionUtils.decryptSequence(encrypted, p.key);
+        ServerAccessToken token2 = jsonp.readFrom(BearerAccessToken.class, BearerAccessToken.class, 
+                                                  new Annotation[]{}, MediaType.APPLICATION_JSON_TYPE, 
+                                                  new MetadataMap<String, String>(), 
+                                                  new ByteArrayInputStream(decrypted.getBytes()));
+        
+        // compare tokens
+        compareAccessTokens(token, token2);
+    }
+    
+    @Test
+    public void testBearerTokenJSONCertificate() throws Exception {
+        
+        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+        KeyPair keyPair = kpg.generateKeyPair();
+        PublicKey publicKey = keyPair.getPublic();
+        PrivateKey privateKey = keyPair.getPrivate();
+        
+        AccessTokenRegistration atr = prepareTokenRegistration();
+        
+        BearerAccessToken token = p.createAccessTokenInternal(atr);
+        JSONProvider<BearerAccessToken> jsonp = new JSONProvider<BearerAccessToken>();
+        jsonp.setMarshallAsJaxbElement(true);
+        jsonp.setUnmarshallAsJaxbElement(true);
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        jsonp.writeTo(token, BearerAccessToken.class, new Annotation[]{}, MediaType.APPLICATION_JSON_TYPE,
+                      new MetadataMap<String, Object>(), bos);
+        
+        KeyProperties props1 = new KeyProperties(publicKey.getAlgorithm());
+        String encrypted = EncryptionUtils.encryptSequence(bos.toString(), publicKey, props1);
+        KeyProperties props2 = new KeyProperties(privateKey.getAlgorithm());
+        String decrypted = EncryptionUtils.decryptSequence(encrypted, privateKey, props2);
+        ServerAccessToken token2 = jsonp.readFrom(BearerAccessToken.class, BearerAccessToken.class, 
+                                                  new Annotation[]{}, MediaType.APPLICATION_JSON_TYPE, 
+                                                  new MetadataMap<String, String>(), 
+                                                  new ByteArrayInputStream(decrypted.getBytes()));
+        
+        // compare tokens
+        compareAccessTokens(token, token2);
+    }
+    
+    @Test
+    public void testClientJSON() throws Exception {
+        Client c = new Client("client", "secret", true);
+        c.setSubject(new UserSubject("subject", "id"));
+        JSONProvider<Client> jsonp = new JSONProvider<Client>();
+        jsonp.setMarshallAsJaxbElement(true);
+        jsonp.setUnmarshallAsJaxbElement(true);
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        jsonp.writeTo(c, Client.class, new Annotation[]{}, MediaType.APPLICATION_JSON_TYPE,
+                      new MetadataMap<String, Object>(), bos);
+        String encrypted = EncryptionUtils.encryptSequence(bos.toString(), p.key);
+        String decrypted = EncryptionUtils.decryptSequence(encrypted, p.key);
+        Client c2 = jsonp.readFrom(Client.class, Client.class, 
+                                                  new Annotation[]{}, MediaType.APPLICATION_JSON_TYPE, 
+                                                  new MetadataMap<String, String>(), 
+                                                  new ByteArrayInputStream(decrypted.getBytes()));
+        
+        assertEquals(c.getClientId(), c2.getClientId());
+        assertEquals(c.getClientSecret(), c2.getClientSecret());
+        assertTrue(c2.isConfidential());
+        assertEquals("subject", c2.getSubject().getLogin());
+        assertEquals("id", c2.getSubject().getId());
+    }
+    
+    @Test
+    public void testCodeGrantJSON() throws Exception {
+        Client c = new Client("client", "secret", true);
+        ServerAuthorizationCodeGrant grant = new ServerAuthorizationCodeGrant(c, "code", 1, 2); 
+        JSONProvider<ServerAuthorizationCodeGrant> jsonp = new JSONProvider<ServerAuthorizationCodeGrant>();
+        jsonp.setMarshallAsJaxbElement(true);
+        jsonp.setUnmarshallAsJaxbElement(true);
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        jsonp.writeTo(grant, ServerAuthorizationCodeGrant.class, new Annotation[]{}, 
+                      MediaType.APPLICATION_JSON_TYPE,
+                      new MetadataMap<String, Object>(), bos);
+        
+        String encrypted = EncryptionUtils.encryptSequence(bos.toString(), p.key);
+        String decrypted = EncryptionUtils.decryptSequence(encrypted, p.key);
+        ServerAuthorizationCodeGrant grant2 = jsonp.readFrom(ServerAuthorizationCodeGrant.class,
+                                                             Client.class, 
+                                                  new Annotation[]{}, MediaType.APPLICATION_JSON_TYPE, 
+                                                  new MetadataMap<String, String>(), 
+                                                  new ByteArrayInputStream(decrypted.getBytes()));
+        assertEquals("code", grant2.getCode());
+        assertEquals(1, grant2.getExpiresIn());
+        assertEquals(2, grant2.getIssuedAt());
+    }
+    
+    private void compareAccessTokens(ServerAccessToken token, ServerAccessToken token2) {
+        assertEquals(token.getTokenKey(), token2.getTokenKey());
+        assertEquals(token.getTokenType(), token2.getTokenType());
+        assertEquals(token.getIssuedAt(), token2.getIssuedAt());
+        assertEquals(token.getExpiresIn(), token2.getExpiresIn());
+        Client regClient1 = token.getClient();
+        Client regClient2 = token2.getClient();
+        assertEquals(regClient1.getClientId(), regClient2.getClientId());
+        assertNull(regClient2.getApplicationDescription());
+        UserSubject endUser1 = token.getSubject();
+        UserSubject endUser2 = token2.getSubject();
+        assertEquals(endUser1.getLogin(), endUser2.getLogin());
+        assertEquals(endUser1.getId(), endUser2.getId());
+        assertEquals(endUser1.getRoles(), endUser2.getRoles());
+        
+        assertEquals(token.getRefreshToken(), token2.getRefreshToken());
+        assertEquals(token.getAudience(), token2.getAudience());
+        assertEquals(token.getGrantType(), token2.getGrantType());
+        assertEquals(token.getParameters(), token2.getParameters());
+        
+        List<OAuthPermission> permissions = token.getScopes();
+        List<OAuthPermission> permissions2 = token2.getScopes();
+        assertEquals(1, permissions.size());
+        assertEquals(1, permissions2.size());
+        OAuthPermission perm1 = permissions.get(0);
+        OAuthPermission perm2 = permissions2.get(0);
+        assertEquals(perm1.getPermission(), perm2.getPermission());
+        assertEquals(perm1.getDescription(), perm2.getDescription());
+        
+        RefreshToken refreshToken = 
+            ModelEncryptionSupport.decryptRefreshToken(p, token2.getRefreshToken(), p.key);
+        assertEquals(1200L, refreshToken.getExpiresIn());
+    }
+    
+    private AccessTokenRegistration prepareTokenRegistration() {
+        AccessTokenRegistration atr = new AccessTokenRegistration();
+        Client regClient = p.getClient("1");
+        atr.setClient(regClient);
+        atr.setGrantType("code");
+        atr.setAudience("http://localhost");
+        UserSubject endUser = new UserSubject("Barry", "BarryId");
+        atr.setSubject(endUser);
+        endUser.setRoles(Collections.singletonList("role1"));
+        return atr;
+    }
+    
+// TODO: remove once the wiki documentation is updated
+//  KeyStore keyStore = loadKeyStore(); 
+//  Certificate cert = keyStore.getCertificate("alice");
+//  PublicKey publicKey = cert.getPublicKey();
+//  KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry)
+//      keyStore.getEntry("alice", new KeyStore.PasswordProtection(
+//           new char[]{'p', 'a', 's', 's', 'w', 'o', 'r', 'd'}));
+//  PrivateKey privateKey = pkEntry.getPrivateKey();
+    
+    
+//    private KeyStore loadKeyStore() throws Exception {
+//        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+//        InputStream is = this.getClass().getResourceAsStream("alice.jks");
+//        ks.load(is, new char[]{'p', 'a', 's', 's', 'w', 'o', 'r', 'd'});
+//        return ks;
+//    }
+}


Mime
View raw message