You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2015/11/10 13:48:56 UTC

[1/3] cxf git commit: Store JWT tokens in the cache

Repository: cxf
Updated Branches:
  refs/heads/3.1.x-fixes 2814cce0d -> 9320bea65


Store JWT tokens in the cache


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/24338419
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/24338419
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/24338419

Branch: refs/heads/3.1.x-fixes
Commit: 243384197f8c395ae001ae0c3ea87aa9724dcda0
Parents: 2814cce
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Tue Nov 10 11:19:49 2015 +0000
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Tue Nov 10 12:48:43 2015 +0000

----------------------------------------------------------------------
 .../token/provider/jwt/JWTTokenProvider.java    | 44 ++++++++------------
 .../token/provider/JWTTokenProviderTest.java    | 34 +++++++++++++++
 2 files changed, 52 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/24338419/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/JWTTokenProvider.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/JWTTokenProvider.java b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/JWTTokenProvider.java
index 0f5a383..5afffda 100644
--- a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/JWTTokenProvider.java
+++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/JWTTokenProvider.java
@@ -42,12 +42,14 @@ import org.apache.cxf.rs.security.jose.jwt.JwtClaims;
 import org.apache.cxf.rs.security.jose.jwt.JwtToken;
 import org.apache.cxf.sts.STSPropertiesMBean;
 import org.apache.cxf.sts.SignatureProperties;
+import org.apache.cxf.sts.cache.CacheUtils;
 import org.apache.cxf.sts.request.TokenRequirements;
 import org.apache.cxf.sts.token.provider.TokenProvider;
 import org.apache.cxf.sts.token.provider.TokenProviderParameters;
 import org.apache.cxf.sts.token.provider.TokenProviderResponse;
 import org.apache.cxf.sts.token.realm.RealmProperties;
 import org.apache.cxf.ws.security.sts.provider.STSException;
+import org.apache.cxf.ws.security.tokenstore.SecurityToken;
 import org.apache.wss4j.common.crypto.Crypto;
 import org.apache.wss4j.common.crypto.Merlin;
 import org.apache.wss4j.common.ext.WSPasswordCallback;
@@ -109,31 +111,6 @@ public class JWTTokenProvider implements TokenProvider {
         JwtClaims claims = jwtClaimsProvider.getJwtClaims(jwtClaimsProviderParameters);
         
         try {
-            /*
-            Document doc = DOMUtils.createDocument();
-            SamlAssertionWrapper assertion = createSamlToken(tokenParameters, secret, doc);
-            Element token = assertion.toDOM(doc);
-            
-            // set the token in cache (only if the token is signed)
-            byte[] signatureValue = assertion.getSignatureValue();
-            if (tokenParameters.getTokenStore() != null && signatureValue != null
-                && signatureValue.length > 0) {
-                DateTime validTill = null;
-                if (assertion.getSamlVersion().equals(SAMLVersion.VERSION_20)) {
-                    validTill = assertion.getSaml2().getConditions().getNotOnOrAfter();
-                } else {
-                    validTill = assertion.getSaml1().getConditions().getNotOnOrAfter();
-                }
-                
-                SecurityToken securityToken = 
-                    CacheUtils.createSecurityTokenForStorage(token, assertion.getId(), 
-                        validTill.toDate(), tokenParameters.getPrincipal(), tokenParameters.getRealm(),
-                        tokenParameters.getTokenRequirements().getRenewing());
-                CacheUtils.storeTokenInCache(
-                    securityToken, tokenParameters.getTokenStore(), signatureValue);
-            }
-            */
-            
             JwtToken token = new JwtToken(claims);
             
             String tokenData = signToken(token, jwtRealm, tokenParameters.getStsProperties(), 
@@ -147,8 +124,23 @@ public class JWTTokenProvider implements TokenProvider {
             if (claims.getIssuedAt() > 0) {
                 response.setCreated(new Date(claims.getIssuedAt() * 1000L));
             }
+            Date expires = null;
             if (claims.getExpiryTime() > 0) {
-                response.setExpires(new Date(claims.getExpiryTime() * 1000L));
+                expires = new Date(claims.getExpiryTime() * 1000L);
+                response.setExpires(expires);
+            }
+            
+            // set the token in cache (only if the token is signed)
+            if (signToken && tokenParameters.getTokenStore() != null) {
+                SecurityToken securityToken = 
+                    CacheUtils.createSecurityTokenForStorage(null, claims.getTokenId(), 
+                        expires, tokenParameters.getPrincipal(), tokenParameters.getRealm(),
+                        tokenParameters.getTokenRequirements().getRenewing());
+                securityToken.setData(tokenData.getBytes());
+                
+                String signature = tokenData.substring(tokenData.lastIndexOf(".") + 1);
+                CacheUtils.storeTokenInCache(
+                    securityToken, tokenParameters.getTokenStore(), signature.getBytes());
             }
             
             LOG.fine("JWT Token successfully created");

http://git-wip-us.apache.org/repos/asf/cxf/blob/24338419/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTTokenProviderTest.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTTokenProviderTest.java b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTTokenProviderTest.java
index aed28ef..6273e0e 100644
--- a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTTokenProviderTest.java
+++ b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTTokenProviderTest.java
@@ -19,6 +19,7 @@
 package org.apache.cxf.sts.token.provider;
 
 import java.security.cert.X509Certificate;
+import java.util.Arrays;
 import java.util.Properties;
 
 import org.apache.cxf.jaxws.context.WebServiceContextImpl;
@@ -35,6 +36,7 @@ import org.apache.cxf.sts.request.KeyRequirements;
 import org.apache.cxf.sts.request.TokenRequirements;
 import org.apache.cxf.sts.service.EncryptionProperties;
 import org.apache.cxf.sts.token.provider.jwt.JWTTokenProvider;
+import org.apache.cxf.ws.security.tokenstore.SecurityToken;
 import org.apache.cxf.ws.security.tokenstore.TokenStore;
 import org.apache.wss4j.common.crypto.Crypto;
 import org.apache.wss4j.common.crypto.CryptoFactory;
@@ -113,6 +115,38 @@ public class JWTTokenProviderTest extends org.junit.Assert {
         assertTrue(jwtConsumer.verifySignatureWith(certs[0], SignatureAlgorithm.RS256));
     }
     
+    @org.junit.Test
+    public void testCachedSignedJWT() throws Exception {
+        TokenProvider jwtTokenProvider = new JWTTokenProvider();
+        ((JWTTokenProvider)jwtTokenProvider).setSignToken(true);
+        
+        TokenProviderParameters providerParameters = createProviderParameters();
+        
+        assertTrue(jwtTokenProvider.canHandleToken(JWTTokenProvider.JWT_TOKEN_TYPE));
+        TokenProviderResponse providerResponse = jwtTokenProvider.createToken(providerParameters);
+        assertTrue(providerResponse != null);
+        assertTrue(providerResponse.getToken() != null && providerResponse.getTokenId() != null);
+
+        String token = (String)providerResponse.getToken();
+        assertNotNull(token);
+        assertTrue(token.split("\\.").length == 3);
+        
+        // Validate the token
+        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(token);
+        JwtToken jwt = jwtConsumer.getJwtToken();
+        Assert.assertEquals("alice", jwt.getClaim(JwtConstants.CLAIM_SUBJECT));
+        Assert.assertEquals(providerResponse.getTokenId(), jwt.getClaim(JwtConstants.CLAIM_JWT_ID));
+        Assert.assertEquals(providerResponse.getCreated().getTime() / 1000L, 
+                            jwt.getClaim(JwtConstants.CLAIM_ISSUED_AT));
+        Assert.assertEquals(providerResponse.getExpires().getTime() / 1000L, 
+                            jwt.getClaim(JwtConstants.CLAIM_EXPIRY));
+        
+        // Check that the token is stored correctly in the cache
+        String signature = token.substring(token.lastIndexOf(".") + 1);
+        SecurityToken secToken = tokenStore.getToken(Integer.toString(Arrays.hashCode(signature.getBytes())));
+        Assert.assertNotNull(secToken);
+    }
+    
     private TokenProviderParameters createProviderParameters() throws WSSecurityException {
         TokenProviderParameters parameters = new TokenProviderParameters();
         


[3/3] cxf git commit: Removing unused variable

Posted by co...@apache.org.
Removing unused variable


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/9320bea6
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/9320bea6
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/9320bea6

Branch: refs/heads/3.1.x-fixes
Commit: 9320bea658e97e54d2bd9d47ad07313c388079f9
Parents: 362437e
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Tue Nov 10 12:14:54 2015 +0000
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Tue Nov 10 12:48:46 2015 +0000

----------------------------------------------------------------------
 parent/pom.xml | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/9320bea6/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index 751f730..8244caf 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -76,7 +76,6 @@
         <cxf.cglib.bundle.version>2.2_2</cxf.cglib.bundle.version>
         <cxf.cglib.osgi.version>[2.1.3,3.0.0)</cxf.cglib.osgi.version>
         <cxf.commons-codec.version>1.10</cxf.commons-codec.version>
-        <cxf.commons-collections.version>3.2.1</cxf.commons-collections.version>
         <cxf.commons-lang.version>2.6</cxf.commons-lang.version>
         <cxf.commons-lang3.version>3.4</cxf.commons-lang3.version>
         <cxf.derby.version>10.2.2.0</cxf.derby.version>


[2/3] cxf git commit: Adding some OnBehalfOf/ActAs tests for JWT tokens

Posted by co...@apache.org.
Adding some OnBehalfOf/ActAs tests for JWT tokens


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/362437e2
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/362437e2
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/362437e2

Branch: refs/heads/3.1.x-fixes
Commit: 362437e222ea79e92078323d865fb0b2d7195610
Parents: 2433841
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Tue Nov 10 12:12:17 2015 +0000
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Tue Nov 10 12:48:45 2015 +0000

----------------------------------------------------------------------
 .../sts/operation/IssueJWTClaimsUnitTest.java   | 108 ++--
 .../operation/IssueJWTOnbehalfofUnitTest.java   | 507 +++++++++++++++++++
 .../token/provider/JWTProviderActAsTest.java    | 196 +++++++
 .../provider/JWTProviderOnBehalfOfTest.java     | 196 +++++++
 4 files changed, 947 insertions(+), 60 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/362437e2/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueJWTClaimsUnitTest.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueJWTClaimsUnitTest.java b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueJWTClaimsUnitTest.java
index 5e92191..ab20e96 100644
--- a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueJWTClaimsUnitTest.java
+++ b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueJWTClaimsUnitTest.java
@@ -77,7 +77,6 @@ import org.apache.cxf.ws.security.sts.provider.model.OnBehalfOfType;
 import org.apache.cxf.ws.security.sts.provider.model.RequestSecurityTokenResponseCollectionType;
 import org.apache.cxf.ws.security.sts.provider.model.RequestSecurityTokenResponseType;
 import org.apache.cxf.ws.security.sts.provider.model.RequestSecurityTokenType;
-import org.apache.cxf.ws.security.sts.provider.model.RequestedSecurityTokenType;
 import org.apache.wss4j.common.crypto.Crypto;
 import org.apache.wss4j.common.crypto.CryptoFactory;
 import org.apache.wss4j.common.ext.WSSecurityException;
@@ -283,14 +282,12 @@ public class IssueJWTClaimsUnitTest extends org.junit.Assert {
     }
     
     /**
-     * Test to successfully issue a SAML 2 token (realm "B") on-behalf-of a SAML 2 token
+     * Test to successfully issue a JWT token (realm "B") on-behalf-of a SAML 2 token
      * which was issued by realm "A".
      * The relationship type between realm A and B is: FederateClaims
-     * TODO
      */
     @org.junit.Test
-    @org.junit.Ignore
-    public void testIssueSaml2TokenOnBehalfOfSaml2DifferentRealmFederateClaims() 
+    public void testIssueJWTTokenOnBehalfOfSaml2DifferentRealmFederateClaims() 
         throws Exception {
         TokenIssueOperation issueOperation = new TokenIssueOperation();
         
@@ -298,13 +295,9 @@ public class IssueJWTClaimsUnitTest extends org.junit.Assert {
         
         // Add Token Provider
         List<TokenProvider> providerList = new ArrayList<TokenProvider>();
-        SAMLTokenProvider samlTokenProvider = new SAMLTokenProvider();
-        samlTokenProvider.setRealmMap(realms);
-        List<AttributeStatementProvider> customProviderList = 
-            new ArrayList<AttributeStatementProvider>();
-        customProviderList.add(new ClaimsAttributeStatementProvider());
-        samlTokenProvider.setAttributeStatementProviders(customProviderList);
-        providerList.add(samlTokenProvider);
+        JWTTokenProvider tokenProvider = new JWTTokenProvider();
+        tokenProvider.setRealmMap(realms);
+        providerList.add(tokenProvider);
         issueOperation.setTokenProviders(providerList);
         
         TokenDelegationHandler delegationHandler = new SAMLDelegationHandler();
@@ -342,7 +335,7 @@ public class IssueJWTClaimsUnitTest extends org.junit.Assert {
         RequestSecurityTokenType request = new RequestSecurityTokenType();
         JAXBElement<String> tokenType = 
             new JAXBElement<String>(
-                QNameConstants.TOKEN_TYPE, String.class, WSConstants.WSS_SAML2_TOKEN_TYPE
+                QNameConstants.TOKEN_TYPE, String.class, JWTTokenProvider.JWT_TOKEN_TYPE
             );
         request.getAny().add(tokenType);
         
@@ -392,57 +385,55 @@ public class IssueJWTClaimsUnitTest extends org.junit.Assert {
         
         List<RequestSecurityTokenResponseType> securityTokenResponseList = issueToken(issueOperation,
                 request, webServiceContext);       
-        RequestSecurityTokenResponseType securityTokenResponse = securityTokenResponseList.get(0);
         
         // Test the generated token.
-        Element assertion = null;
-        for (Object tokenObject : securityTokenResponse.getAny()) {
-            if (tokenObject instanceof JAXBElement<?>
-                && REQUESTED_SECURITY_TOKEN.equals(((JAXBElement<?>)tokenObject).getName())) {
-                RequestedSecurityTokenType rstType = 
-                    (RequestedSecurityTokenType)((JAXBElement<?>)tokenObject).getValue();
-                assertion = (Element)rstType.getAny();
+        String jwtToken = null;
+        for (Object tokenObject : securityTokenResponseList.get(0).getAny()) {
+            if (tokenObject instanceof Element
+                && REQUESTED_SECURITY_TOKEN.getLocalPart().equals(((Element)tokenObject).getLocalName())
+                && REQUESTED_SECURITY_TOKEN.getNamespaceURI().equals(((Element)tokenObject).getNamespaceURI())) {
+                jwtToken = ((Element)tokenObject).getTextContent();
                 break;
             }
         }
-        assertNotNull(assertion);
-        String tokenString = DOM2Writer.nodeToString(assertion);
-        assertTrue(tokenString.contains("AttributeStatement"));
-        assertTrue(tokenString.contains("alice"));  //subject unchanged
-        assertTrue(tokenString.contains("DOE")); //transformed claim (to uppercase)
-        assertTrue(tokenString.contains(SAML2Constants.CONF_BEARER));
+        
+        assertNotNull(jwtToken);
+        
+        // Validate the token
+        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(jwtToken);
+        JwtToken jwt = jwtConsumer.getJwtToken();
+        // subject unchanged
+        Assert.assertEquals("alice", jwt.getClaim(JwtConstants.CLAIM_SUBJECT));
+        // transformed claim (to uppercase)
+        assertEquals(jwt.getClaim(ClaimTypes.LASTNAME.toString()), "DOE");
     }
     
     /**
-     * Test to successfully issue a SAML 2 token (realm "B") on-behalf-of a SAML 2 token
+     * Test to successfully issue a JWT token (realm "B") on-behalf-of a SAML 2 token
      * which was issued by realm "A".
      * The relationship type between realm A and B is: FederateIdentity
      * IdentityMapper is configured globally in STSPropertiesMBean
-     * TODO
      */
     @org.junit.Test
-    @org.junit.Ignore
-    public void testIssueSaml2TokenOnBehalfOfSaml2DifferentRealmFederateIdentityGlobalConfig()
+    public void testIssueJWTTokenOnBehalfOfSaml2DifferentRealmFederateIdentityGlobalConfig()
         throws Exception {
-        runIssueSaml2TokenOnBehalfOfSaml2DifferentRealmFederateIdentity(true);
+        runIssueJWTTokenOnBehalfOfSaml2DifferentRealmFederateIdentity(true);
     }
     
     
     /**
-     * Test to successfully issue a SAML 2 token (realm "B") on-behalf-of a SAML 2 token
+     * Test to successfully issue a JWT token (realm "B") on-behalf-of a SAML 2 token
      * which was issued by realm "A".
      * The relationship type between realm A and B is: FederateIdentity
      * IdentityMapper is configured in the Relationship
-     * TODO
      */
     @org.junit.Test
-    @org.junit.Ignore
-    public void testIssueSaml2TokenOnBehalfOfSaml2DifferentRealmFederateIdentityRelationshipConfig()
+    public void testIssueJWTTokenOnBehalfOfSaml2DifferentRealmFederateIdentityRelationshipConfig()
         throws Exception {
-        runIssueSaml2TokenOnBehalfOfSaml2DifferentRealmFederateIdentity(false);
+        runIssueJWTTokenOnBehalfOfSaml2DifferentRealmFederateIdentity(false);
     }
 
-    private void runIssueSaml2TokenOnBehalfOfSaml2DifferentRealmFederateIdentity(
+    private void runIssueJWTTokenOnBehalfOfSaml2DifferentRealmFederateIdentity(
             boolean useGlobalIdentityMapper) throws WSSecurityException {
         TokenIssueOperation issueOperation = new TokenIssueOperation();
         
@@ -450,13 +441,9 @@ public class IssueJWTClaimsUnitTest extends org.junit.Assert {
         
         // Add Token Provider
         List<TokenProvider> providerList = new ArrayList<TokenProvider>();
-        SAMLTokenProvider samlTokenProvider = new SAMLTokenProvider();
-        samlTokenProvider.setRealmMap(realms);
-        List<AttributeStatementProvider> customProviderList = 
-            new ArrayList<AttributeStatementProvider>();
-        customProviderList.add(new ClaimsAttributeStatementProvider());
-        samlTokenProvider.setAttributeStatementProviders(customProviderList);
-        providerList.add(samlTokenProvider);
+        JWTTokenProvider tokenProvider = new JWTTokenProvider();
+        tokenProvider.setRealmMap(realms);
+        providerList.add(tokenProvider);
         issueOperation.setTokenProviders(providerList);
         
         TokenDelegationHandler delegationHandler = new SAMLDelegationHandler();
@@ -500,7 +487,7 @@ public class IssueJWTClaimsUnitTest extends org.junit.Assert {
         RequestSecurityTokenType request = new RequestSecurityTokenType();
         JAXBElement<String> tokenType = 
             new JAXBElement<String>(
-                QNameConstants.TOKEN_TYPE, String.class, WSConstants.WSS_SAML2_TOKEN_TYPE
+                QNameConstants.TOKEN_TYPE, String.class, JWTTokenProvider.JWT_TOKEN_TYPE
             );
         request.getAny().add(tokenType);
         
@@ -550,26 +537,27 @@ public class IssueJWTClaimsUnitTest extends org.junit.Assert {
         
         List<RequestSecurityTokenResponseType> securityTokenResponseList = issueToken(issueOperation,
                 request, webServiceContext);       
-        RequestSecurityTokenResponseType securityTokenResponse = securityTokenResponseList.get(0);
         
         // Test the generated token.
-        Element assertion = null;
-        for (Object tokenObject : securityTokenResponse.getAny()) {
-            if (tokenObject instanceof JAXBElement<?>
-                && REQUESTED_SECURITY_TOKEN.equals(((JAXBElement<?>)tokenObject).getName())) {
-                RequestedSecurityTokenType rstType = 
-                    (RequestedSecurityTokenType)((JAXBElement<?>)tokenObject).getValue();
-                assertion = (Element)rstType.getAny();
+        String jwtToken = null;
+        for (Object tokenObject : securityTokenResponseList.get(0).getAny()) {
+            if (tokenObject instanceof Element
+                && REQUESTED_SECURITY_TOKEN.getLocalPart().equals(((Element)tokenObject).getLocalName())
+                && REQUESTED_SECURITY_TOKEN.getNamespaceURI().equals(((Element)tokenObject).getNamespaceURI())) {
+                jwtToken = ((Element)tokenObject).getTextContent();
                 break;
             }
         }
         
-        assertNotNull(assertion);
-        String tokenString = DOM2Writer.nodeToString(assertion);
-        assertTrue(tokenString.contains("AttributeStatement"));
-        assertTrue(tokenString.contains("ALICE"));  //subject changed (to uppercase)
-        assertTrue(tokenString.contains("doe"));  //claim unchanged but requested
-        assertTrue(tokenString.contains(SAML2Constants.CONF_BEARER));
+        assertNotNull(jwtToken);
+        
+        // Validate the token
+        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(jwtToken);
+        JwtToken jwt = jwtConsumer.getJwtToken();
+        // subject changed (to uppercase)
+        Assert.assertEquals("ALICE", jwt.getClaim(JwtConstants.CLAIM_SUBJECT));
+        // claim unchanged but requested
+        assertEquals(jwt.getClaim(ClaimTypes.LASTNAME.toString()), "doe");
     }
     
 

http://git-wip-us.apache.org/repos/asf/cxf/blob/362437e2/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueJWTOnbehalfofUnitTest.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueJWTOnbehalfofUnitTest.java b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueJWTOnbehalfofUnitTest.java
new file mode 100644
index 0000000..dc2352f
--- /dev/null
+++ b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueJWTOnbehalfofUnitTest.java
@@ -0,0 +1,507 @@
+/**
+ * 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.sts.operation;
+
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.xml.bind.JAXBElement;
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.cxf.jaxws.context.WebServiceContextImpl;
+import org.apache.cxf.jaxws.context.WrappedMessageContext;
+import org.apache.cxf.message.MessageImpl;
+import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactConsumer;
+import org.apache.cxf.rs.security.jose.jwt.JwtConstants;
+import org.apache.cxf.rs.security.jose.jwt.JwtToken;
+import org.apache.cxf.sts.QNameConstants;
+import org.apache.cxf.sts.STSConstants;
+import org.apache.cxf.sts.STSPropertiesMBean;
+import org.apache.cxf.sts.StaticSTSProperties;
+import org.apache.cxf.sts.common.PasswordCallbackHandler;
+import org.apache.cxf.sts.request.KeyRequirements;
+import org.apache.cxf.sts.request.ReceivedKey;
+import org.apache.cxf.sts.request.TokenRequirements;
+import org.apache.cxf.sts.service.EncryptionProperties;
+import org.apache.cxf.sts.service.ServiceMBean;
+import org.apache.cxf.sts.service.StaticService;
+import org.apache.cxf.sts.token.delegation.SAMLDelegationHandler;
+import org.apache.cxf.sts.token.delegation.TokenDelegationHandler;
+import org.apache.cxf.sts.token.delegation.UsernameTokenDelegationHandler;
+import org.apache.cxf.sts.token.provider.SAMLTokenProvider;
+import org.apache.cxf.sts.token.provider.TokenProvider;
+import org.apache.cxf.sts.token.provider.TokenProviderParameters;
+import org.apache.cxf.sts.token.provider.TokenProviderResponse;
+import org.apache.cxf.sts.token.provider.jwt.JWTTokenProvider;
+import org.apache.cxf.sts.token.realm.RealmProperties;
+import org.apache.cxf.sts.token.validator.IssuerSAMLRealmCodec;
+import org.apache.cxf.sts.token.validator.SAMLTokenValidator;
+import org.apache.cxf.sts.token.validator.TokenValidator;
+import org.apache.cxf.sts.token.validator.UsernameTokenValidator;
+import org.apache.cxf.ws.security.sts.provider.STSException;
+import org.apache.cxf.ws.security.sts.provider.model.OnBehalfOfType;
+import org.apache.cxf.ws.security.sts.provider.model.RequestSecurityTokenResponseCollectionType;
+import org.apache.cxf.ws.security.sts.provider.model.RequestSecurityTokenResponseType;
+import org.apache.cxf.ws.security.sts.provider.model.RequestSecurityTokenType;
+import org.apache.cxf.ws.security.sts.provider.model.secext.AttributedString;
+import org.apache.cxf.ws.security.sts.provider.model.secext.PasswordString;
+import org.apache.cxf.ws.security.sts.provider.model.secext.UsernameTokenType;
+import org.apache.wss4j.common.crypto.Crypto;
+import org.apache.wss4j.common.crypto.CryptoFactory;
+import org.apache.wss4j.common.crypto.CryptoType;
+import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.principal.CustomTokenPrincipal;
+import org.apache.wss4j.dom.WSConstants;
+import org.junit.Assert;
+
+/**
+ * Issue JWT tokens on behalf of other tokens.
+ */
+public class IssueJWTOnbehalfofUnitTest extends org.junit.Assert {
+
+    public static final QName REQUESTED_SECURITY_TOKEN = 
+        QNameConstants.WS_TRUST_FACTORY.createRequestedSecurityToken(null).getName();
+    
+    /**
+     * Test to successfully issue a JWT token on-behalf-of a SAML 2 token
+     */
+    @org.junit.Test
+    public void testIssueJWTTokenOnBehalfOfSaml2() throws Exception {
+        TokenIssueOperation issueOperation = new TokenIssueOperation();
+
+        // Add Token Provider
+        List<TokenProvider> providerList = new ArrayList<TokenProvider>();
+        providerList.add(new JWTTokenProvider());
+        issueOperation.setTokenProviders(providerList);
+        
+        // Add Token Validator
+        List<TokenValidator> validatorList = new ArrayList<TokenValidator>();
+        validatorList.add(new SAMLTokenValidator());
+        issueOperation.setTokenValidators(validatorList);
+
+        // Add Service
+        ServiceMBean service = new StaticService();
+        service.setEndpoints(Collections.singletonList("http://dummy-service.com/dummy"));
+        issueOperation.setServices(Collections.singletonList(service));
+
+        // Add STSProperties object
+        STSPropertiesMBean stsProperties = new StaticSTSProperties();
+        Crypto crypto = CryptoFactory.getInstance(getEncryptionProperties());
+        stsProperties.setEncryptionCrypto(crypto);
+        stsProperties.setSignatureCrypto(crypto);
+        stsProperties.setEncryptionUsername("myservicekey");
+        stsProperties.setSignatureUsername("mystskey");
+        stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+        stsProperties.setIssuer("STS");
+        issueOperation.setStsProperties(stsProperties);
+        
+        TokenDelegationHandler delegationHandler = new SAMLDelegationHandler();
+        issueOperation.setDelegationHandlers(Collections.singletonList(delegationHandler));
+
+        // Mock up a request
+        RequestSecurityTokenType request = new RequestSecurityTokenType();
+        JAXBElement<String> tokenType = 
+            new JAXBElement<String>(
+                    QNameConstants.TOKEN_TYPE, String.class, JWTTokenProvider.JWT_TOKEN_TYPE
+            );
+        request.getAny().add(tokenType);
+
+        // Get a SAML Token via the SAMLTokenProvider
+        CallbackHandler callbackHandler = new PasswordCallbackHandler();
+        Element samlToken = 
+            createSAMLAssertion(WSConstants.WSS_SAML2_TOKEN_TYPE, crypto, "mystskey", callbackHandler);
+        Document doc = samlToken.getOwnerDocument();
+        samlToken = (Element)doc.appendChild(samlToken);
+        OnBehalfOfType onbehalfof = new OnBehalfOfType();
+        onbehalfof.setAny(samlToken);
+
+        JAXBElement<OnBehalfOfType> onbehalfofType = 
+            new JAXBElement<OnBehalfOfType>(
+                    QNameConstants.ON_BEHALF_OF, OnBehalfOfType.class, onbehalfof
+            );
+        request.getAny().add(onbehalfofType);
+        
+        // Mock up message context
+        MessageImpl msg = new MessageImpl();
+        WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+        WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
+
+        // Issue a token
+        RequestSecurityTokenResponseCollectionType response = 
+            issueOperation.issue(request, webServiceContext);
+        List<RequestSecurityTokenResponseType> securityTokenResponse = 
+            response.getRequestSecurityTokenResponse();
+        assertTrue(!securityTokenResponse.isEmpty());
+        
+        // Test the generated token.
+        String jwtToken = null;
+        for (Object tokenObject : securityTokenResponse.get(0).getAny()) {
+            if (tokenObject instanceof Element
+                && REQUESTED_SECURITY_TOKEN.getLocalPart().equals(((Element)tokenObject).getLocalName())
+                && REQUESTED_SECURITY_TOKEN.getNamespaceURI().equals(((Element)tokenObject).getNamespaceURI())) {
+                jwtToken = ((Element)tokenObject).getTextContent();
+                break;
+            }
+        }
+        
+        assertNotNull(jwtToken);
+        
+        // Validate the token
+        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(jwtToken);
+        JwtToken jwt = jwtConsumer.getJwtToken();
+        Assert.assertEquals("alice", jwt.getClaim(JwtConstants.CLAIM_SUBJECT));
+    }
+    
+    /**
+     * Test to successfully issue a JWT token on-behalf-of a UsernameToken
+     */
+    @org.junit.Test
+    public void testIssueJWTTokenOnBehalfOfUsernameToken() throws Exception {
+        TokenIssueOperation issueOperation = new TokenIssueOperation();
+
+        // Add Token Provider
+        List<TokenProvider> providerList = new ArrayList<TokenProvider>();
+        providerList.add(new JWTTokenProvider());
+        issueOperation.setTokenProviders(providerList);
+        
+        // Add Token Validator
+        List<TokenValidator> validatorList = new ArrayList<TokenValidator>();
+        validatorList.add(new UsernameTokenValidator());
+        issueOperation.setTokenValidators(validatorList);
+
+        // Add Service
+        ServiceMBean service = new StaticService();
+        service.setEndpoints(Collections.singletonList("http://dummy-service.com/dummy"));
+        issueOperation.setServices(Collections.singletonList(service));
+
+        // Add STSProperties object
+        STSPropertiesMBean stsProperties = new StaticSTSProperties();
+        Crypto crypto = CryptoFactory.getInstance(getEncryptionProperties());
+        stsProperties.setEncryptionCrypto(crypto);
+        stsProperties.setSignatureCrypto(crypto);
+        stsProperties.setEncryptionUsername("myservicekey");
+        stsProperties.setSignatureUsername("mystskey");
+        stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+        stsProperties.setIssuer("STS");
+        issueOperation.setStsProperties(stsProperties);
+
+        // Mock up a request
+        RequestSecurityTokenType request = new RequestSecurityTokenType();
+        JAXBElement<String> tokenType = 
+            new JAXBElement<String>(
+                    QNameConstants.TOKEN_TYPE, String.class, JWTTokenProvider.JWT_TOKEN_TYPE
+            );
+        request.getAny().add(tokenType);
+
+        
+        // Create a UsernameToken
+        JAXBElement<UsernameTokenType> usernameTokenType = createUsernameToken("alice", "clarinet");
+        OnBehalfOfType onbehalfof = new OnBehalfOfType();
+        onbehalfof.setAny(usernameTokenType);
+        
+        JAXBElement<OnBehalfOfType> onbehalfofType = 
+            new JAXBElement<OnBehalfOfType>(
+                    QNameConstants.ON_BEHALF_OF, OnBehalfOfType.class, onbehalfof
+            );
+        request.getAny().add(onbehalfofType);
+        
+
+        // Mock up message context
+        MessageImpl msg = new MessageImpl();
+        WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+        WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
+
+        // Issue a token
+        
+        // This should fail as the default DelegationHandler does not allow UsernameTokens
+        try {
+            issueOperation.issue(request, webServiceContext);
+            fail("Failure expected as UsernameTokens are not accepted for OnBehalfOf by default");
+        } catch (STSException ex) {
+            // expected
+        }
+        
+        TokenDelegationHandler delegationHandler = new UsernameTokenDelegationHandler();
+        issueOperation.setDelegationHandlers(Collections.singletonList(delegationHandler));
+        
+        RequestSecurityTokenResponseCollectionType response = 
+            issueOperation.issue(request, webServiceContext);
+        List<RequestSecurityTokenResponseType> securityTokenResponse = 
+            response.getRequestSecurityTokenResponse();
+        assertTrue(!securityTokenResponse.isEmpty());
+        
+        // Test the generated token.
+        String jwtToken = null;
+        for (Object tokenObject : securityTokenResponse.get(0).getAny()) {
+            if (tokenObject instanceof Element
+                && REQUESTED_SECURITY_TOKEN.getLocalPart().equals(((Element)tokenObject).getLocalName())
+                && REQUESTED_SECURITY_TOKEN.getNamespaceURI().equals(((Element)tokenObject).getNamespaceURI())) {
+                jwtToken = ((Element)tokenObject).getTextContent();
+                break;
+            }
+        }
+        
+        assertNotNull(jwtToken);
+        
+        // Validate the token
+        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(jwtToken);
+        JwtToken jwt = jwtConsumer.getJwtToken();
+        Assert.assertEquals("alice", jwt.getClaim(JwtConstants.CLAIM_SUBJECT));
+    }
+    
+    /**
+     * Test to successfully issue a JWT Token (realm "B") on-behalf-of a SAML 2 token
+     * on-behalf-of token issued by realm "A".
+     */
+    @org.junit.Test
+    public void testIssueJWTTokenOnBehalfOfSaml2DifferentRealm() throws Exception {
+        TokenIssueOperation issueOperation = new TokenIssueOperation();
+        
+        // Add Token Provider
+        List<TokenProvider> providerList = new ArrayList<TokenProvider>();
+        JWTTokenProvider tokenProvider = new JWTTokenProvider();
+        providerList.add(tokenProvider);
+        issueOperation.setTokenProviders(providerList);
+        
+        TokenDelegationHandler delegationHandler = new SAMLDelegationHandler();
+        issueOperation.setDelegationHandlers(Collections.singletonList(delegationHandler));
+        
+        // Add Token Validator
+        List<TokenValidator> validatorList = new ArrayList<TokenValidator>();
+        SAMLTokenValidator samlTokenValidator = new SAMLTokenValidator();
+        samlTokenValidator.setSamlRealmCodec(new IssuerSAMLRealmCodec());
+        validatorList.add(samlTokenValidator);
+        issueOperation.setTokenValidators(validatorList);
+
+        // Add Service
+        ServiceMBean service = new StaticService();
+        service.setEndpoints(Collections.singletonList("http://dummy-service.com/dummy"));
+        issueOperation.setServices(Collections.singletonList(service));
+        
+        // Add STSProperties object
+        STSPropertiesMBean stsProperties = new StaticSTSProperties();
+        Crypto crypto = CryptoFactory.getInstance(getEncryptionProperties());
+        stsProperties.setEncryptionCrypto(crypto);
+        stsProperties.setSignatureCrypto(crypto);
+        stsProperties.setEncryptionUsername("myservicekey");
+        stsProperties.setSignatureUsername("mystskey");
+        stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+        stsProperties.setIssuer("STS");
+        stsProperties.setRealmParser(new CustomRealmParser());
+        stsProperties.setIdentityMapper(new CustomIdentityMapper());
+        issueOperation.setStsProperties(stsProperties);
+        
+        Map<String, RealmProperties> realms = createSamlRealms();
+        
+        // Mock up a request
+        RequestSecurityTokenType request = new RequestSecurityTokenType();
+        JAXBElement<String> tokenType = 
+            new JAXBElement<String>(
+                QNameConstants.TOKEN_TYPE, String.class, JWTTokenProvider.JWT_TOKEN_TYPE
+            );
+        request.getAny().add(tokenType);
+        
+        // Get a SAML Token via the SAMLTokenProvider
+        CallbackHandler callbackHandler = new PasswordCallbackHandler();
+        Element samlToken = 
+            createSAMLAssertion(WSConstants.WSS_SAML2_TOKEN_TYPE, crypto, "mystskey",
+                    callbackHandler, realms, STSConstants.BEARER_KEY_KEYTYPE);
+        Document doc = samlToken.getOwnerDocument();
+        samlToken = (Element)doc.appendChild(samlToken);
+        OnBehalfOfType onbehalfof = new OnBehalfOfType();
+        onbehalfof.setAny(samlToken);
+
+        JAXBElement<OnBehalfOfType> onbehalfofType = 
+            new JAXBElement<OnBehalfOfType>(
+                    QNameConstants.ON_BEHALF_OF, OnBehalfOfType.class, onbehalfof
+            );
+        request.getAny().add(onbehalfofType);
+        
+        // Mock up message context
+        MessageImpl msg = new MessageImpl();
+        WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+        msgCtx.put("url", "https");
+        WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
+        
+        tokenProvider.setRealmMap(realms);
+        
+        RequestSecurityTokenResponseCollectionType response = 
+            issueOperation.issue(request, webServiceContext);
+        List<RequestSecurityTokenResponseType> securityTokenResponse = 
+            response.getRequestSecurityTokenResponse();
+        assertTrue(!securityTokenResponse.isEmpty());
+        
+        // Test the generated token.
+        String jwtToken = null;
+        for (Object tokenObject : securityTokenResponse.get(0).getAny()) {
+            if (tokenObject instanceof Element
+                && REQUESTED_SECURITY_TOKEN.getLocalPart().equals(((Element)tokenObject).getLocalName())
+                && REQUESTED_SECURITY_TOKEN.getNamespaceURI().equals(((Element)tokenObject).getNamespaceURI())) {
+                jwtToken = ((Element)tokenObject).getTextContent();
+                break;
+            }
+        }
+        
+        assertNotNull(jwtToken);
+        
+        // Validate the token
+        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(jwtToken);
+        JwtToken jwt = jwtConsumer.getJwtToken();
+        Assert.assertEquals("ALICE", jwt.getClaim(JwtConstants.CLAIM_SUBJECT));
+    }
+    
+    /*
+     * Mock up an SAML assertion element
+     */
+    private Element createSAMLAssertion(
+            String tokenType, Crypto crypto, String signatureUsername, CallbackHandler callbackHandler
+    ) throws WSSecurityException {
+        return createSAMLAssertion(tokenType, crypto, signatureUsername, 
+                                   callbackHandler, null, STSConstants.BEARER_KEY_KEYTYPE);
+    }
+
+    /*
+     * Mock up an SAML assertion element
+     */
+    private Element createSAMLAssertion(
+            String tokenType, Crypto crypto, String signatureUsername, CallbackHandler callbackHandler,
+            Map<String, RealmProperties> realms, String keyType
+    ) throws WSSecurityException {
+        SAMLTokenProvider samlTokenProvider = new SAMLTokenProvider();
+        samlTokenProvider.setRealmMap(realms);
+
+        TokenProviderParameters providerParameters = 
+            createProviderParameters(
+                    tokenType, keyType, crypto, signatureUsername, callbackHandler
+            );
+        if (realms != null) {
+            providerParameters.setRealm("A");
+        }
+        TokenProviderResponse providerResponse = samlTokenProvider.createToken(providerParameters);
+        assertTrue(providerResponse != null);
+        assertTrue(providerResponse.getToken() != null && providerResponse.getTokenId() != null);
+
+        return (Element)providerResponse.getToken();
+    }
+
+    private TokenProviderParameters createProviderParameters(
+            String tokenType, String keyType, Crypto crypto, 
+            String signatureUsername, CallbackHandler callbackHandler
+    ) throws WSSecurityException {
+        TokenProviderParameters parameters = new TokenProviderParameters();
+
+        TokenRequirements tokenRequirements = new TokenRequirements();
+        tokenRequirements.setTokenType(tokenType);
+        parameters.setTokenRequirements(tokenRequirements);
+
+        KeyRequirements keyRequirements = new KeyRequirements();
+        keyRequirements.setKeyType(keyType);
+        
+        CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
+        cryptoType.setAlias("myclientkey");
+        X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
+        ReceivedKey receivedKey = new ReceivedKey();
+        receivedKey.setX509Cert(certs[0]);
+        keyRequirements.setReceivedKey(receivedKey);
+        
+        parameters.setKeyRequirements(keyRequirements);
+
+        parameters.setPrincipal(new CustomTokenPrincipal("alice"));
+        // Mock up message context
+        MessageImpl msg = new MessageImpl();
+        WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+        WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
+        parameters.setWebServiceContext(webServiceContext);
+
+        parameters.setAppliesToAddress("http://dummy-service.com/dummy");
+
+        // Add STSProperties object
+        StaticSTSProperties stsProperties = new StaticSTSProperties();
+        stsProperties.setSignatureCrypto(crypto);
+        stsProperties.setSignatureUsername(signatureUsername);
+        stsProperties.setCallbackHandler(callbackHandler);
+        stsProperties.setIssuer("STS");
+        stsProperties.setEncryptionUsername("myservicekey");
+        stsProperties.setEncryptionCrypto(crypto);
+        parameters.setStsProperties(stsProperties);
+
+        parameters.setEncryptionProperties(new EncryptionProperties());
+
+        return parameters;
+    }
+
+    private JAXBElement<UsernameTokenType> createUsernameToken(String name, String password) {
+        UsernameTokenType usernameToken = new UsernameTokenType();
+        AttributedString username = new AttributedString();
+        username.setValue(name);
+        usernameToken.setUsername(username);
+
+        // Add a password
+        if (password != null) {
+            PasswordString passwordString = new PasswordString();
+            passwordString.setValue(password);
+            passwordString.setType(WSConstants.PASSWORD_TEXT);
+            JAXBElement<PasswordString> passwordType = 
+                new JAXBElement<PasswordString>(
+                        QNameConstants.PASSWORD, PasswordString.class, passwordString
+                );
+            usernameToken.getAny().add(passwordType);
+        }
+
+        JAXBElement<UsernameTokenType> tokenType = 
+            new JAXBElement<UsernameTokenType>(
+                    QNameConstants.USERNAME_TOKEN, UsernameTokenType.class, usernameToken
+            );
+
+        return tokenType;
+    }
+
+    private Map<String, RealmProperties> createSamlRealms() {
+        // Create Realms
+        Map<String, RealmProperties> samlRealms = new HashMap<String, RealmProperties>();
+        RealmProperties samlRealm = new RealmProperties();
+        samlRealm.setIssuer("A-Issuer");
+        samlRealms.put("A", samlRealm);
+        samlRealm = new RealmProperties();
+        samlRealm.setIssuer("B-Issuer");
+        samlRealms.put("B", samlRealm);
+        return samlRealms;
+    }
+
+    private Properties getEncryptionProperties() {
+        Properties properties = new Properties();
+        properties.put(
+                "org.apache.wss4j.crypto.provider", "org.apache.wss4j.common.crypto.Merlin"
+        );
+        properties.put("org.apache.wss4j.crypto.merlin.keystore.password", "stsspass");
+        properties.put("org.apache.wss4j.crypto.merlin.keystore.file", "stsstore.jks");
+
+        return properties;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/362437e2/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTProviderActAsTest.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTProviderActAsTest.java b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTProviderActAsTest.java
new file mode 100644
index 0000000..9e0fcd6
--- /dev/null
+++ b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTProviderActAsTest.java
@@ -0,0 +1,196 @@
+/**
+ * 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.sts.token.provider;
+
+import java.util.Properties;
+
+import javax.xml.bind.JAXBElement;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.jaxws.context.WebServiceContextImpl;
+import org.apache.cxf.jaxws.context.WrappedMessageContext;
+import org.apache.cxf.message.MessageImpl;
+import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactConsumer;
+import org.apache.cxf.rs.security.jose.jwt.JwtConstants;
+import org.apache.cxf.rs.security.jose.jwt.JwtToken;
+import org.apache.cxf.sts.QNameConstants;
+import org.apache.cxf.sts.STSConstants;
+import org.apache.cxf.sts.StaticSTSProperties;
+import org.apache.cxf.sts.common.PasswordCallbackHandler;
+import org.apache.cxf.sts.request.KeyRequirements;
+import org.apache.cxf.sts.request.ReceivedToken;
+import org.apache.cxf.sts.request.ReceivedToken.STATE;
+import org.apache.cxf.sts.request.TokenRequirements;
+import org.apache.cxf.sts.service.EncryptionProperties;
+import org.apache.cxf.sts.token.provider.jwt.JWTTokenProvider;
+import org.apache.cxf.ws.security.sts.provider.model.secext.AttributedString;
+import org.apache.cxf.ws.security.sts.provider.model.secext.UsernameTokenType;
+import org.apache.wss4j.common.crypto.Crypto;
+import org.apache.wss4j.common.crypto.CryptoFactory;
+import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.principal.CustomTokenPrincipal;
+import org.apache.wss4j.dom.WSConstants;
+import org.junit.Assert;
+
+/**
+ * Some unit tests for creating JWT Tokens with an ActAs element.
+ */
+public class JWTProviderActAsTest extends org.junit.Assert {
+    
+    /**
+     * Create a JWT Token with ActAs from a UsernameToken
+     */
+    @org.junit.Test
+    public void testJWTActAsUsernameToken() throws Exception {
+        TokenProvider tokenProvider = new JWTTokenProvider();
+        
+        UsernameTokenType usernameToken = new UsernameTokenType();
+        AttributedString username = new AttributedString();
+        username.setValue("bob");
+        usernameToken.setUsername(username);
+        JAXBElement<UsernameTokenType> usernameTokenType = 
+            new JAXBElement<UsernameTokenType>(
+                QNameConstants.USERNAME_TOKEN, UsernameTokenType.class, usernameToken
+            );
+        
+        TokenProviderParameters providerParameters = 
+            createProviderParameters(
+                JWTTokenProvider.JWT_TOKEN_TYPE, usernameTokenType
+            );
+        //Principal must be set in ReceivedToken/ActAs
+        providerParameters.getTokenRequirements().getActAs().setPrincipal(
+                new CustomTokenPrincipal(username.getValue()));
+        
+        assertTrue(tokenProvider.canHandleToken(JWTTokenProvider.JWT_TOKEN_TYPE));
+        TokenProviderResponse providerResponse = tokenProvider.createToken(providerParameters);
+        assertTrue(providerResponse != null);
+        assertTrue(providerResponse.getToken() != null && providerResponse.getTokenId() != null);
+        
+        String token = (String)providerResponse.getToken();
+        assertNotNull(token);
+        
+        // Validate the token
+        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(token);
+        JwtToken jwt = jwtConsumer.getJwtToken();
+        Assert.assertEquals("bob", jwt.getClaim(JwtConstants.CLAIM_SUBJECT));
+    }
+    
+    /**
+     * Create a JWT Token with ActAs from a SAML Assertion
+     */
+    @org.junit.Test
+    public void testJWTActAsAssertion() throws Exception {
+        TokenProvider tokenProvider = new JWTTokenProvider();
+        
+        String user = "alice";
+        Element saml1Assertion = getSAMLAssertion(user);
+        
+        TokenProviderParameters providerParameters = 
+            createProviderParameters(
+                JWTTokenProvider.JWT_TOKEN_TYPE, saml1Assertion
+            );
+        //Principal must be set in ReceivedToken/ActAs
+        providerParameters.getTokenRequirements().getActAs().setPrincipal(
+                new CustomTokenPrincipal(user));
+        
+        assertTrue(tokenProvider.canHandleToken(JWTTokenProvider.JWT_TOKEN_TYPE));
+        TokenProviderResponse providerResponse = tokenProvider.createToken(providerParameters);
+        assertTrue(providerResponse != null);
+        assertTrue(providerResponse.getToken() != null && providerResponse.getTokenId() != null);
+        
+        String token = (String)providerResponse.getToken();
+        assertNotNull(token);
+        
+        // Validate the token
+        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(token);
+        JwtToken jwt = jwtConsumer.getJwtToken();
+        Assert.assertEquals(user, jwt.getClaim(JwtConstants.CLAIM_SUBJECT));
+    }
+    
+    private Element getSAMLAssertion(String user) throws Exception {
+        TokenProvider samlTokenProvider = new SAMLTokenProvider();
+        TokenProviderParameters providerParameters = 
+            createProviderParameters(WSConstants.WSS_SAML_TOKEN_TYPE, null);
+        providerParameters.getKeyRequirements().setKeyType(STSConstants.BEARER_KEY_KEYTYPE);
+        providerParameters.setPrincipal(new CustomTokenPrincipal(user));
+        assertTrue(samlTokenProvider.canHandleToken(WSConstants.WSS_SAML_TOKEN_TYPE));
+        TokenProviderResponse providerResponse = samlTokenProvider.createToken(providerParameters);
+        assertTrue(providerResponse != null);
+        assertTrue(providerResponse.getToken() != null && providerResponse.getTokenId() != null);
+
+        return (Element)providerResponse.getToken();
+    }
+
+    private TokenProviderParameters createProviderParameters(
+        String tokenType, Object actAs
+    ) throws WSSecurityException {
+        TokenProviderParameters parameters = new TokenProviderParameters();
+        
+        TokenRequirements tokenRequirements = new TokenRequirements();
+        tokenRequirements.setTokenType(tokenType);
+        
+        if (actAs != null) {
+            ReceivedToken actAsToken = new ReceivedToken(actAs);
+            actAsToken.setState(STATE.VALID);
+            tokenRequirements.setActAs(actAsToken);
+            
+        }
+        parameters.setTokenRequirements(tokenRequirements);
+        
+        KeyRequirements keyRequirements = new KeyRequirements();
+        parameters.setKeyRequirements(keyRequirements);
+        
+        parameters.setPrincipal(new CustomTokenPrincipal("alice"));
+        // Mock up message context
+        MessageImpl msg = new MessageImpl();
+        WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+        WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
+        parameters.setWebServiceContext(webServiceContext);
+        
+        parameters.setAppliesToAddress("http://dummy-service.com/dummy");
+        
+        // Add STSProperties object
+        StaticSTSProperties stsProperties = new StaticSTSProperties();
+        Crypto crypto = CryptoFactory.getInstance(getEncryptionProperties());
+        stsProperties.setSignatureCrypto(crypto);
+        stsProperties.setSignatureUsername("mystskey");
+        stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+        stsProperties.setIssuer("STS");
+        parameters.setStsProperties(stsProperties);
+        
+        parameters.setEncryptionProperties(new EncryptionProperties());
+        
+        return parameters;
+    }
+    
+    private Properties getEncryptionProperties() {
+        Properties properties = new Properties();
+        properties.put(
+            "org.apache.wss4j.crypto.provider", "org.apache.wss4j.common.crypto.Merlin"
+        );
+        properties.put("org.apache.wss4j.crypto.merlin.keystore.password", "stsspass");
+        properties.put("org.apache.wss4j.crypto.merlin.keystore.file", "stsstore.jks");
+        
+        return properties;
+    }
+    
+  
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/362437e2/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTProviderOnBehalfOfTest.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTProviderOnBehalfOfTest.java b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTProviderOnBehalfOfTest.java
new file mode 100644
index 0000000..265b48c
--- /dev/null
+++ b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTProviderOnBehalfOfTest.java
@@ -0,0 +1,196 @@
+/**
+ * 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.sts.token.provider;
+
+import java.util.Properties;
+
+import javax.xml.bind.JAXBElement;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.jaxws.context.WebServiceContextImpl;
+import org.apache.cxf.jaxws.context.WrappedMessageContext;
+import org.apache.cxf.message.MessageImpl;
+import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactConsumer;
+import org.apache.cxf.rs.security.jose.jwt.JwtConstants;
+import org.apache.cxf.rs.security.jose.jwt.JwtToken;
+import org.apache.cxf.sts.QNameConstants;
+import org.apache.cxf.sts.STSConstants;
+import org.apache.cxf.sts.StaticSTSProperties;
+import org.apache.cxf.sts.common.PasswordCallbackHandler;
+import org.apache.cxf.sts.request.KeyRequirements;
+import org.apache.cxf.sts.request.ReceivedToken;
+import org.apache.cxf.sts.request.ReceivedToken.STATE;
+import org.apache.cxf.sts.request.TokenRequirements;
+import org.apache.cxf.sts.service.EncryptionProperties;
+import org.apache.cxf.sts.token.provider.jwt.JWTTokenProvider;
+import org.apache.cxf.ws.security.sts.provider.model.secext.AttributedString;
+import org.apache.cxf.ws.security.sts.provider.model.secext.UsernameTokenType;
+import org.apache.wss4j.common.crypto.Crypto;
+import org.apache.wss4j.common.crypto.CryptoFactory;
+import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.principal.CustomTokenPrincipal;
+import org.apache.wss4j.dom.WSConstants;
+import org.junit.Assert;
+
+/**
+ * Some unit tests for creating JWT Tokens with an OnBehalfOf element.
+ */
+public class JWTProviderOnBehalfOfTest extends org.junit.Assert {
+    
+    /**
+     * Create a JWT Token with OnBehalfOf from a UsernameToken
+     */
+    @org.junit.Test
+    public void testJWTOnBehalfOfUsernameToken() throws Exception {
+        TokenProvider tokenProvider = new JWTTokenProvider();
+        
+        UsernameTokenType usernameToken = new UsernameTokenType();
+        AttributedString username = new AttributedString();
+        username.setValue("bob");
+        usernameToken.setUsername(username);
+        JAXBElement<UsernameTokenType> usernameTokenType = 
+            new JAXBElement<UsernameTokenType>(
+                QNameConstants.USERNAME_TOKEN, UsernameTokenType.class, usernameToken
+            );
+        
+        TokenProviderParameters providerParameters = 
+            createProviderParameters(
+                JWTTokenProvider.JWT_TOKEN_TYPE, usernameTokenType
+            );
+        //Principal must be set in ReceivedToken/OnBehalfOf
+        providerParameters.getTokenRequirements().getOnBehalfOf().setPrincipal(
+                new CustomTokenPrincipal(username.getValue()));
+        
+        assertTrue(tokenProvider.canHandleToken(JWTTokenProvider.JWT_TOKEN_TYPE));
+        TokenProviderResponse providerResponse = tokenProvider.createToken(providerParameters);
+        assertTrue(providerResponse != null);
+        assertTrue(providerResponse.getToken() != null && providerResponse.getTokenId() != null);
+        
+        String token = (String)providerResponse.getToken();
+        assertNotNull(token);
+        
+        // Validate the token
+        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(token);
+        JwtToken jwt = jwtConsumer.getJwtToken();
+        Assert.assertEquals("bob", jwt.getClaim(JwtConstants.CLAIM_SUBJECT));
+    }
+    
+    /**
+     * Create a JWT Token with OnBehalfOf from a SAML Assertion
+     */
+    @org.junit.Test
+    public void testJWTOnBehalfOfAssertion() throws Exception {
+        TokenProvider tokenProvider = new JWTTokenProvider();
+        
+        String user = "alice";
+        Element saml1Assertion = getSAMLAssertion(user);
+        
+        TokenProviderParameters providerParameters = 
+            createProviderParameters(
+                JWTTokenProvider.JWT_TOKEN_TYPE, saml1Assertion
+            );
+        //Principal must be set in ReceivedToken/OnBehalfOf
+        providerParameters.getTokenRequirements().getOnBehalfOf().setPrincipal(
+                new CustomTokenPrincipal(user));
+        
+        assertTrue(tokenProvider.canHandleToken(JWTTokenProvider.JWT_TOKEN_TYPE));
+        TokenProviderResponse providerResponse = tokenProvider.createToken(providerParameters);
+        assertTrue(providerResponse != null);
+        assertTrue(providerResponse.getToken() != null && providerResponse.getTokenId() != null);
+        
+        String token = (String)providerResponse.getToken();
+        assertNotNull(token);
+        
+        // Validate the token
+        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(token);
+        JwtToken jwt = jwtConsumer.getJwtToken();
+        Assert.assertEquals(user, jwt.getClaim(JwtConstants.CLAIM_SUBJECT));
+    }
+    
+    private Element getSAMLAssertion(String user) throws Exception {
+        TokenProvider samlTokenProvider = new SAMLTokenProvider();
+        TokenProviderParameters providerParameters = 
+            createProviderParameters(WSConstants.WSS_SAML_TOKEN_TYPE, null);
+        providerParameters.getKeyRequirements().setKeyType(STSConstants.BEARER_KEY_KEYTYPE);
+        providerParameters.setPrincipal(new CustomTokenPrincipal(user));
+        assertTrue(samlTokenProvider.canHandleToken(WSConstants.WSS_SAML_TOKEN_TYPE));
+        TokenProviderResponse providerResponse = samlTokenProvider.createToken(providerParameters);
+        assertTrue(providerResponse != null);
+        assertTrue(providerResponse.getToken() != null && providerResponse.getTokenId() != null);
+
+        return (Element)providerResponse.getToken();
+    }
+
+    private TokenProviderParameters createProviderParameters(
+        String tokenType, Object onBehalfOf
+    ) throws WSSecurityException {
+        TokenProviderParameters parameters = new TokenProviderParameters();
+        
+        TokenRequirements tokenRequirements = new TokenRequirements();
+        tokenRequirements.setTokenType(tokenType);
+        
+        if (onBehalfOf != null) {
+            ReceivedToken onBehalfOfToken = new ReceivedToken(onBehalfOf);
+            onBehalfOfToken.setState(STATE.VALID);
+            tokenRequirements.setOnBehalfOf(onBehalfOfToken);
+            
+        }
+        parameters.setTokenRequirements(tokenRequirements);
+        
+        KeyRequirements keyRequirements = new KeyRequirements();
+        parameters.setKeyRequirements(keyRequirements);
+        
+        parameters.setPrincipal(new CustomTokenPrincipal("alice"));
+        // Mock up message context
+        MessageImpl msg = new MessageImpl();
+        WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+        WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
+        parameters.setWebServiceContext(webServiceContext);
+        
+        parameters.setAppliesToAddress("http://dummy-service.com/dummy");
+        
+        // Add STSProperties object
+        StaticSTSProperties stsProperties = new StaticSTSProperties();
+        Crypto crypto = CryptoFactory.getInstance(getEncryptionProperties());
+        stsProperties.setSignatureCrypto(crypto);
+        stsProperties.setSignatureUsername("mystskey");
+        stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+        stsProperties.setIssuer("STS");
+        parameters.setStsProperties(stsProperties);
+        
+        parameters.setEncryptionProperties(new EncryptionProperties());
+        
+        return parameters;
+    }
+    
+    private Properties getEncryptionProperties() {
+        Properties properties = new Properties();
+        properties.put(
+            "org.apache.wss4j.crypto.provider", "org.apache.wss4j.common.crypto.Merlin"
+        );
+        properties.put("org.apache.wss4j.crypto.merlin.keystore.password", "stsspass");
+        properties.put("org.apache.wss4j.crypto.merlin.keystore.file", "stsstore.jks");
+        
+        return properties;
+    }
+    
+  
+    
+}