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/17 14:51:45 UTC

[2/2] cxf git commit: Added support for realms with JWT validation

Added support for realms with JWT validation


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

Branch: refs/heads/master
Commit: b89bb65b189d029b1ba7696663e973805547ecd8
Parents: 7f4b3b1
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Tue Nov 17 12:39:46 2015 +0000
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Tue Nov 17 13:44:57 2015 +0000

----------------------------------------------------------------------
 .../ws/security/trust/AbstractSTSClient.java    |   4 +-
 .../cxf/sts/operation/TokenIssueOperation.java  |  10 +-
 .../apache/cxf/sts/request/ReceivedToken.java   |   5 -
 .../cxf/sts/token/realm/JWTRealmCodec.java      |  36 +++
 .../token/validator/jwt/JWTTokenValidator.java  |  56 ++--
 .../sts/operation/IssueJWTClaimsUnitTest.java   |  61 ++--
 .../operation/IssueJWTOnbehalfofUnitTest.java   |  46 +--
 .../sts/operation/IssueJWTRealmUnitTest.java    |  63 +++--
 .../cxf/sts/operation/IssueJWTUnitTest.java     |  16 +-
 .../validator/JWTTokenValidatorRealmTest.java   | 280 +++++++++++++++++++
 .../token/validator/JWTTokenValidatorTest.java  |  23 +-
 .../apache/cxf/systest/sts/jwt/JWTUnitTest.java |  41 ++-
 .../cxf/systest/sts/deployment/cxf-sts.xml      |   3 +
 13 files changed, 514 insertions(+), 130 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/b89bb65b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/AbstractSTSClient.java
----------------------------------------------------------------------
diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/AbstractSTSClient.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/AbstractSTSClient.java
index f06ff80..0b6f619 100755
--- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/AbstractSTSClient.java
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/AbstractSTSClient.java
@@ -1117,7 +1117,9 @@ public abstract class AbstractSTSClient implements Configurable, InterceptorProv
             writer.writeStartElement("wst", "ValidateTarget", namespace);
 
             Element el = tok.getToken();
-            StaxUtils.copy(el, writer);
+            if (el != null) {
+                StaxUtils.copy(el, writer);
+            }
 
             writer.writeEndElement();
             writer.writeEndElement();

http://git-wip-us.apache.org/repos/asf/cxf/blob/b89bb65b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenIssueOperation.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenIssueOperation.java b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenIssueOperation.java
index 383535e..7a9b57a 100644
--- a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenIssueOperation.java
+++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/TokenIssueOperation.java
@@ -39,7 +39,6 @@ import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.helpers.DOMUtils;
 import org.apache.cxf.rt.security.claims.ClaimCollection;
 import org.apache.cxf.sts.QNameConstants;
-import org.apache.cxf.sts.STSConstants;
 import org.apache.cxf.sts.event.STSIssueFailureEvent;
 import org.apache.cxf.sts.event.STSIssueSuccessEvent;
 import org.apache.cxf.sts.request.KeyRequirements;
@@ -294,14 +293,13 @@ public class TokenIssueOperation extends AbstractOperation implements IssueOpera
         } else {
             if (tokenResponse.getToken() instanceof String) {
                 Document doc = DOMUtils.newDocument();
-                Element requestedTokenEl = doc.createElementNS(STSConstants.WST_NS_05_12, 
-                                                             "RequestedSecurityToken");
-                requestedTokenEl.setTextContent((String)tokenResponse.getToken());
-                response.getAny().add(requestedTokenEl);
+                Element tokenWrapper = doc.createElementNS(null, "TokenWrapper");
+                tokenWrapper.setTextContent((String)tokenResponse.getToken());
+                requestedTokenType.setAny(tokenWrapper);
             } else {
                 requestedTokenType.setAny(tokenResponse.getToken());
-                response.getAny().add(requestedToken);
             }
+            response.getAny().add(requestedToken);
         }
 
         if (returnReferences) {

http://git-wip-us.apache.org/repos/asf/cxf/blob/b89bb65b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/ReceivedToken.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/ReceivedToken.java b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/ReceivedToken.java
index 252ec60..d220670 100644
--- a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/ReceivedToken.java
+++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/ReceivedToken.java
@@ -74,11 +74,6 @@ public class ReceivedToken {
             }
             this.token = receivedToken;
             isDOMElement = true;
-        } else if (receivedToken instanceof String) {
-            if (LOG.isLoggable(Level.FINE)) {
-                LOG.fine("Found ValidateTarget String");
-            }
-            this.token = receivedToken;
         } else {
             LOG.fine("Found ValidateTarget object of unknown type");
             throw new STSException(

http://git-wip-us.apache.org/repos/asf/cxf/blob/b89bb65b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/realm/JWTRealmCodec.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/realm/JWTRealmCodec.java b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/realm/JWTRealmCodec.java
new file mode 100644
index 0000000..540e1c8
--- /dev/null
+++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/realm/JWTRealmCodec.java
@@ -0,0 +1,36 @@
+/**
+ * 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.realm;
+
+import org.apache.cxf.rs.security.jose.jwt.JwtToken;
+
+/**
+ * This interface defines a pluggable way to return a realm associated with a JWT Token.
+ */
+public interface JWTRealmCodec {
+    
+    /**
+     * Get the realm associated with the JwtToken parameter
+     * @param token a JwtToken Object
+     * @return the realm associated with the JwtToken parameter
+     */
+    String getRealmFromToken(JwtToken token);
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/b89bb65b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/jwt/JWTTokenValidator.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/jwt/JWTTokenValidator.java b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/jwt/JWTTokenValidator.java
index 110a611..4fb9dec 100644
--- a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/jwt/JWTTokenValidator.java
+++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/validator/jwt/JWTTokenValidator.java
@@ -25,6 +25,10 @@ import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import javax.xml.soap.Node;
+
+import org.w3c.dom.Element;
+
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.common.security.SimplePrincipal;
 import org.apache.cxf.rs.security.jose.common.JoseConstants;
@@ -37,6 +41,7 @@ import org.apache.cxf.rs.security.jose.jwt.JwtUtils;
 import org.apache.cxf.sts.STSPropertiesMBean;
 import org.apache.cxf.sts.request.ReceivedToken;
 import org.apache.cxf.sts.request.ReceivedToken.STATE;
+import org.apache.cxf.sts.token.realm.JWTRealmCodec;
 import org.apache.cxf.sts.token.validator.TokenValidator;
 import org.apache.cxf.sts.token.validator.TokenValidatorParameters;
 import org.apache.cxf.sts.token.validator.TokenValidatorResponse;
@@ -53,6 +58,7 @@ public class JWTTokenValidator implements TokenValidator {
     private int clockOffset;
     private int ttl;
     private JWTRoleParser roleParser;
+    private JWTRealmCodec realmCodec;
     
     /**
      * Return true if this TokenValidator implementation is capable of validating the
@@ -68,14 +74,17 @@ public class JWTTokenValidator implements TokenValidator {
      */
     public boolean canHandleToken(ReceivedToken validateTarget, String realm) {
         Object token = validateTarget.getToken();
-        if (token instanceof String) {
-            try {
-                JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer((String)token);
-                if (jwtConsumer.getJwtToken() != null) {
-                    return true;
+        if (token instanceof Element) {
+            Element tokenEl = (Element)token;
+            if (tokenEl.getFirstChild().getNodeType() == Node.TEXT_NODE) {
+                try {
+                    JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(tokenEl.getTextContent());
+                    if (jwtConsumer.getJwtToken() != null) {
+                        return true;
+                    }
+                } catch (RuntimeException ex) {
+                    return false;
                 }
-            } catch (RuntimeException ex) {
-                return false;
             }
         }
         return false;
@@ -93,8 +102,8 @@ public class JWTTokenValidator implements TokenValidator {
         validateTarget.setState(STATE.INVALID);
         response.setToken(validateTarget);
         
-        String token = (String)validateTarget.getToken();
-        if (token == null) {
+        String token = ((Element)validateTarget.getToken()).getTextContent();
+        if (token == null || "".equals(token)) {
             return response;
         }
         
@@ -137,24 +146,11 @@ public class JWTTokenValidator implements TokenValidator {
         }
         
         
-        /*
-        // Get the realm of the SAML token
-        String tokenRealm = null;
-        if (samlRealmCodec != null) {
-            tokenRealm = samlRealmCodec.getRealmFromToken(assertion);
-            // verify the realm against the cached token
-            if (secToken != null) {
-                Map<String, Object> props = secToken.getProperties();
-                if (props != null) {
-                    String cachedRealm = (String)props.get(STSConstants.TOKEN_REALM);
-                    if (cachedRealm != null && !tokenRealm.equals(cachedRealm)) {
-                        return response;
-                    }
-                }
-            }
+        // Get the realm of the JWT Token
+        if (realmCodec != null) {
+            String tokenRealm = realmCodec.getRealmFromToken(jwt);
+            response.setTokenRealm(tokenRealm);
         }
-        response.setTokenRealm(tokenRealm);
-        */
 
         if (isVerifiedWithAPublicKey(jwt)) {
             Principal principal = new SimplePrincipal(jwt.getClaims().getSubject());
@@ -215,4 +211,12 @@ public class JWTTokenValidator implements TokenValidator {
     public void setRoleParser(JWTRoleParser roleParser) {
         this.roleParser = roleParser;
     }
+
+    public JWTRealmCodec getRealmCodec() {
+        return realmCodec;
+    }
+
+    public void setRealmCodec(JWTRealmCodec realmCodec) {
+        this.realmCodec = realmCodec;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/b89bb65b/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 ab20e96..82d921b 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,6 +77,7 @@ 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;
@@ -136,20 +137,21 @@ public class IssueJWTClaimsUnitTest extends org.junit.Assert {
                 webServiceContext);
         
         // Test the generated token.
-        String jwtToken = null;
+        Element token = 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();
+            if (tokenObject instanceof JAXBElement<?>
+                && REQUESTED_SECURITY_TOKEN.equals(((JAXBElement<?>)tokenObject).getName())) {
+                RequestedSecurityTokenType rstType = 
+                    (RequestedSecurityTokenType)((JAXBElement<?>)tokenObject).getValue();
+                token = (Element)rstType.getAny();
                 break;
             }
         }
         
-        assertNotNull(jwtToken);
+        assertNotNull(token);
         
         // Validate the token
-        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(jwtToken);
+        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(token.getTextContent());
         JwtToken jwt = jwtConsumer.getJwtToken();
         Assert.assertEquals("alice", jwt.getClaim(JwtConstants.CLAIM_SUBJECT));
         assertEquals(jwt.getClaim(ClaimTypes.LASTNAME.toString()), "doe");
@@ -262,20 +264,21 @@ public class IssueJWTClaimsUnitTest extends org.junit.Assert {
                 webServiceContext);
         
         // Test the generated token.
-        String jwtToken = null;
+        Element token = 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();
+            if (tokenObject instanceof JAXBElement<?>
+                && REQUESTED_SECURITY_TOKEN.equals(((JAXBElement<?>)tokenObject).getName())) {
+                RequestedSecurityTokenType rstType = 
+                    (RequestedSecurityTokenType)((JAXBElement<?>)tokenObject).getValue();
+                token = (Element)rstType.getAny();
                 break;
             }
         }
         
-        assertNotNull(jwtToken);
+        assertNotNull(token);
         
         // Validate the token
-        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(jwtToken);
+        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(token.getTextContent());
         JwtToken jwt = jwtConsumer.getJwtToken();
         Assert.assertEquals("alice", jwt.getClaim(JwtConstants.CLAIM_SUBJECT));
         assertEquals(jwt.getClaim(ClaimTypes.LASTNAME.toString()), "doe");
@@ -387,20 +390,21 @@ public class IssueJWTClaimsUnitTest extends org.junit.Assert {
                 request, webServiceContext);       
         
         // Test the generated token.
-        String jwtToken = null;
+        Element token = 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();
+            if (tokenObject instanceof JAXBElement<?>
+                && REQUESTED_SECURITY_TOKEN.equals(((JAXBElement<?>)tokenObject).getName())) {
+                RequestedSecurityTokenType rstType = 
+                    (RequestedSecurityTokenType)((JAXBElement<?>)tokenObject).getValue();
+                token = (Element)rstType.getAny();
                 break;
             }
         }
         
-        assertNotNull(jwtToken);
+        assertNotNull(token);
         
         // Validate the token
-        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(jwtToken);
+        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(token.getTextContent());
         JwtToken jwt = jwtConsumer.getJwtToken();
         // subject unchanged
         Assert.assertEquals("alice", jwt.getClaim(JwtConstants.CLAIM_SUBJECT));
@@ -539,20 +543,21 @@ public class IssueJWTClaimsUnitTest extends org.junit.Assert {
                 request, webServiceContext);       
         
         // Test the generated token.
-        String jwtToken = null;
+        Element token = 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();
+            if (tokenObject instanceof JAXBElement<?>
+                && REQUESTED_SECURITY_TOKEN.equals(((JAXBElement<?>)tokenObject).getName())) {
+                RequestedSecurityTokenType rstType = 
+                    (RequestedSecurityTokenType)((JAXBElement<?>)tokenObject).getValue();
+                token = (Element)rstType.getAny();
                 break;
             }
         }
         
-        assertNotNull(jwtToken);
+        assertNotNull(token);
         
         // Validate the token
-        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(jwtToken);
+        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(token.getTextContent());
         JwtToken jwt = jwtConsumer.getJwtToken();
         // subject changed (to uppercase)
         Assert.assertEquals("ALICE", jwt.getClaim(JwtConstants.CLAIM_SUBJECT));

http://git-wip-us.apache.org/repos/asf/cxf/blob/b89bb65b/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
index dc2352f..5d1bfa6 100644
--- 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
@@ -68,6 +68,7 @@ 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.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;
@@ -159,20 +160,21 @@ public class IssueJWTOnbehalfofUnitTest extends org.junit.Assert {
         assertTrue(!securityTokenResponse.isEmpty());
         
         // Test the generated token.
-        String jwtToken = null;
+        Element token = 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();
+            if (tokenObject instanceof JAXBElement<?>
+                && REQUESTED_SECURITY_TOKEN.equals(((JAXBElement<?>)tokenObject).getName())) {
+                RequestedSecurityTokenType rstType = 
+                    (RequestedSecurityTokenType)((JAXBElement<?>)tokenObject).getValue();
+                token = (Element)rstType.getAny();
                 break;
             }
         }
         
-        assertNotNull(jwtToken);
+        assertNotNull(token);
         
         // Validate the token
-        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(jwtToken);
+        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(token.getTextContent());
         JwtToken jwt = jwtConsumer.getJwtToken();
         Assert.assertEquals("alice", jwt.getClaim(JwtConstants.CLAIM_SUBJECT));
     }
@@ -256,20 +258,21 @@ public class IssueJWTOnbehalfofUnitTest extends org.junit.Assert {
         assertTrue(!securityTokenResponse.isEmpty());
         
         // Test the generated token.
-        String jwtToken = null;
+        Element token = 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();
+            if (tokenObject instanceof JAXBElement<?>
+                && REQUESTED_SECURITY_TOKEN.equals(((JAXBElement<?>)tokenObject).getName())) {
+                RequestedSecurityTokenType rstType = 
+                    (RequestedSecurityTokenType)((JAXBElement<?>)tokenObject).getValue();
+                token = (Element)rstType.getAny();
                 break;
             }
         }
         
-        assertNotNull(jwtToken);
+        assertNotNull(token);
         
         // Validate the token
-        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(jwtToken);
+        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(token.getTextContent());
         JwtToken jwt = jwtConsumer.getJwtToken();
         Assert.assertEquals("alice", jwt.getClaim(JwtConstants.CLAIM_SUBJECT));
     }
@@ -357,20 +360,21 @@ public class IssueJWTOnbehalfofUnitTest extends org.junit.Assert {
         assertTrue(!securityTokenResponse.isEmpty());
         
         // Test the generated token.
-        String jwtToken = null;
+        Element token = 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();
+            if (tokenObject instanceof JAXBElement<?>
+                && REQUESTED_SECURITY_TOKEN.equals(((JAXBElement<?>)tokenObject).getName())) {
+                RequestedSecurityTokenType rstType = 
+                    (RequestedSecurityTokenType)((JAXBElement<?>)tokenObject).getValue();
+                token = (Element)rstType.getAny();
                 break;
             }
         }
         
-        assertNotNull(jwtToken);
+        assertNotNull(token);
         
         // Validate the token
-        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(jwtToken);
+        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(token.getTextContent());
         JwtToken jwt = jwtConsumer.getJwtToken();
         Assert.assertEquals("ALICE", jwt.getClaim(JwtConstants.CLAIM_SUBJECT));
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/b89bb65b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueJWTRealmUnitTest.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueJWTRealmUnitTest.java b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueJWTRealmUnitTest.java
index 3a8b496..4608396 100644
--- a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueJWTRealmUnitTest.java
+++ b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueJWTRealmUnitTest.java
@@ -54,6 +54,7 @@ import org.apache.cxf.ws.security.sts.provider.STSException;
 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.principal.CustomTokenPrincipal;
@@ -130,18 +131,19 @@ public class IssueJWTRealmUnitTest extends org.junit.Assert {
         assertTrue(!securityTokenResponse.isEmpty());
         
         // Test the generated token.
-        String jwtToken = null;
+        Element token = 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();
+            if (tokenObject instanceof JAXBElement<?>
+                && REQUESTED_SECURITY_TOKEN.equals(((JAXBElement<?>)tokenObject).getName())) {
+                RequestedSecurityTokenType rstType = 
+                    (RequestedSecurityTokenType)((JAXBElement<?>)tokenObject).getValue();
+                token = (Element)rstType.getAny();
                 break;
             }
         }
         
-        assertNotNull(jwtToken);
-        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(jwtToken);
+        assertNotNull(token);
+        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(token.getTextContent());
         JwtToken jwt = jwtConsumer.getJwtToken();
         Assert.assertEquals("A-Issuer", jwt.getClaim(JwtConstants.CLAIM_ISSUER));
     }
@@ -204,18 +206,19 @@ public class IssueJWTRealmUnitTest extends org.junit.Assert {
         assertTrue(!securityTokenResponse.isEmpty());
         
         // Test the generated token.
-        String jwtToken = null;
+        Element token = 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();
+            if (tokenObject instanceof JAXBElement<?>
+                && REQUESTED_SECURITY_TOKEN.equals(((JAXBElement<?>)tokenObject).getName())) {
+                RequestedSecurityTokenType rstType = 
+                    (RequestedSecurityTokenType)((JAXBElement<?>)tokenObject).getValue();
+                token = (Element)rstType.getAny();
                 break;
             }
         }
         
-        assertNotNull(jwtToken);
-        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(jwtToken);
+        assertNotNull(token);
+        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(token.getTextContent());
         JwtToken jwt = jwtConsumer.getJwtToken();
         Assert.assertEquals("B-Issuer", jwt.getClaim(JwtConstants.CLAIM_ISSUER));
     }
@@ -278,18 +281,19 @@ public class IssueJWTRealmUnitTest extends org.junit.Assert {
         assertTrue(!securityTokenResponse.isEmpty());
         
         // Test the generated token.
-        String jwtToken = null;
+        Element token = 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();
+            if (tokenObject instanceof JAXBElement<?>
+                && REQUESTED_SECURITY_TOKEN.equals(((JAXBElement<?>)tokenObject).getName())) {
+                RequestedSecurityTokenType rstType = 
+                    (RequestedSecurityTokenType)((JAXBElement<?>)tokenObject).getValue();
+                token = (Element)rstType.getAny();
                 break;
             }
         }
         
-        assertNotNull(jwtToken);
-        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(jwtToken);
+        assertNotNull(token);
+        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(token.getTextContent());
         JwtToken jwt = jwtConsumer.getJwtToken();
         Assert.assertEquals("STS", jwt.getClaim(JwtConstants.CLAIM_ISSUER));
     }
@@ -371,19 +375,20 @@ public class IssueJWTRealmUnitTest extends org.junit.Assert {
             response.getRequestSecurityTokenResponse();
         assertTrue(!securityTokenResponse.isEmpty());
         
-        // Test the generated token.
-        String jwtToken = null;
+     // Test the generated token.
+        Element token = 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();
+            if (tokenObject instanceof JAXBElement<?>
+                && REQUESTED_SECURITY_TOKEN.equals(((JAXBElement<?>)tokenObject).getName())) {
+                RequestedSecurityTokenType rstType = 
+                    (RequestedSecurityTokenType)((JAXBElement<?>)tokenObject).getValue();
+                token = (Element)rstType.getAny();
                 break;
             }
         }
         
-        assertNotNull(jwtToken);
-        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(jwtToken);
+        assertNotNull(token);
+        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(token.getTextContent());
         JwtToken jwt = jwtConsumer.getJwtToken();
         Assert.assertEquals("B-Issuer", jwt.getClaim(JwtConstants.CLAIM_ISSUER));
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/b89bb65b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueJWTUnitTest.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueJWTUnitTest.java b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueJWTUnitTest.java
index 58d6b25..5cd7a3c 100644
--- a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueJWTUnitTest.java
+++ b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueJWTUnitTest.java
@@ -51,6 +51,7 @@ import org.apache.cxf.sts.token.provider.jwt.JWTTokenProvider;
 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.cxf.ws.security.tokenstore.TokenStore;
 import org.apache.wss4j.common.crypto.Crypto;
 import org.apache.wss4j.common.crypto.CryptoFactory;
@@ -127,20 +128,21 @@ public class IssueJWTUnitTest extends org.junit.Assert {
         assertTrue(!securityTokenResponse.isEmpty());
         
         // Test the generated token.
-        String jwtToken = null;
+        Element token = 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();
+            if (tokenObject instanceof JAXBElement<?>
+                && REQUESTED_SECURITY_TOKEN.equals(((JAXBElement<?>)tokenObject).getName())) {
+                RequestedSecurityTokenType rstType = 
+                    (RequestedSecurityTokenType)((JAXBElement<?>)tokenObject).getValue();
+                token = (Element)rstType.getAny();
                 break;
             }
         }
         
-        assertNotNull(jwtToken);
+        assertNotNull(token);
         
         // Validate the token
-        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(jwtToken);
+        JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(token.getTextContent());
         JwtToken jwt = jwtConsumer.getJwtToken();
         Assert.assertEquals("alice", jwt.getClaim(JwtConstants.CLAIM_SUBJECT));
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/b89bb65b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/validator/JWTTokenValidatorRealmTest.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/validator/JWTTokenValidatorRealmTest.java b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/validator/JWTTokenValidatorRealmTest.java
new file mode 100644
index 0000000..a73c3e1
--- /dev/null
+++ b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/validator/JWTTokenValidatorRealmTest.java
@@ -0,0 +1,280 @@
+/**
+ * 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.validator;
+
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.cxf.helpers.DOMUtils;
+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.jwt.JwtConstants;
+import org.apache.cxf.rs.security.jose.jwt.JwtToken;
+import org.apache.cxf.sts.STSConstants;
+import org.apache.cxf.sts.StaticSTSProperties;
+import org.apache.cxf.sts.cache.DefaultInMemoryTokenStore;
+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.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.JWTRealmCodec;
+import org.apache.cxf.sts.token.realm.RealmProperties;
+import org.apache.cxf.sts.token.validator.jwt.JWTTokenValidator;
+import org.apache.cxf.ws.security.tokenstore.TokenStore;
+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;
+
+/**
+ * Some unit tests for validating JWTTokens in different realms
+ */
+public class JWTTokenValidatorRealmTest extends org.junit.Assert {
+    private static TokenStore tokenStore = new DefaultInMemoryTokenStore();
+    
+    @org.junit.Test
+    public void testRealmA() throws Exception {
+        // Create
+        TokenProvider jwtTokenProvider = new JWTTokenProvider();
+        ((JWTTokenProvider)jwtTokenProvider).setSignToken(true);
+        ((JWTTokenProvider)jwtTokenProvider).setRealmMap(getRealms());
+        
+        TokenProviderParameters providerParameters = createProviderParameters();
+        providerParameters.setRealm("A");
+        
+        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 - no realm is returned
+        TokenValidator jwtTokenValidator = new JWTTokenValidator();
+        TokenValidatorParameters validatorParameters = createValidatorParameters();
+        TokenRequirements tokenRequirements = validatorParameters.getTokenRequirements();
+        
+        // Create a ValidateTarget consisting of a JWT Token
+        ReceivedToken validateTarget = new ReceivedToken(createTokenWrapper(token));
+        tokenRequirements.setValidateTarget(validateTarget);
+        validatorParameters.setToken(validateTarget);
+        
+        assertTrue(jwtTokenValidator.canHandleToken(validateTarget));
+        
+        TokenValidatorResponse validatorResponse = 
+            jwtTokenValidator.validateToken(validatorParameters);
+        assertTrue(validatorResponse != null);
+        assertTrue(validatorResponse.getToken() != null);
+        assertTrue(validatorResponse.getToken().getState() == STATE.VALID);
+        assertNull(validatorResponse.getTokenRealm());
+        
+        // Now set the JWTRealmCodec implementation on the Validator
+        ((JWTTokenValidator)jwtTokenValidator).setRealmCodec(new IssuerJWTRealmCodec());
+        
+        validatorResponse = jwtTokenValidator.validateToken(validatorParameters);
+        assertTrue(validatorResponse != null);
+        assertTrue(validatorResponse.getToken() != null);
+        assertTrue(validatorResponse.getToken().getState() == STATE.VALID);
+        assertTrue(validatorResponse.getTokenRealm().equals("A"));
+        
+        Principal principal = validatorResponse.getPrincipal();
+        assertTrue(principal != null && principal.getName() != null);
+    }
+    
+    @org.junit.Test
+    public void testRealmB() throws Exception {
+        // Create
+        TokenProvider jwtTokenProvider = new JWTTokenProvider();
+        ((JWTTokenProvider)jwtTokenProvider).setSignToken(true);
+        ((JWTTokenProvider)jwtTokenProvider).setRealmMap(getRealms());
+        
+        TokenProviderParameters providerParameters = createProviderParameters();
+        providerParameters.setRealm("B");
+        
+        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 - no realm is returned
+        TokenValidator jwtTokenValidator = new JWTTokenValidator();
+        TokenValidatorParameters validatorParameters = createValidatorParameters();
+        TokenRequirements tokenRequirements = validatorParameters.getTokenRequirements();
+        
+        // Create a ValidateTarget consisting of a JWT Token
+        ReceivedToken validateTarget = new ReceivedToken(createTokenWrapper(token));
+        tokenRequirements.setValidateTarget(validateTarget);
+        validatorParameters.setToken(validateTarget);
+        
+        assertTrue(jwtTokenValidator.canHandleToken(validateTarget));
+        
+        TokenValidatorResponse validatorResponse = 
+            jwtTokenValidator.validateToken(validatorParameters);
+        assertTrue(validatorResponse != null);
+        assertTrue(validatorResponse.getToken() != null);
+        assertTrue(validatorResponse.getToken().getState() == STATE.VALID);
+        assertNull(validatorResponse.getTokenRealm());
+        
+        // Now set the JWTRealmCodec implementation on the Validator
+        ((JWTTokenValidator)jwtTokenValidator).setRealmCodec(new IssuerJWTRealmCodec());
+        
+        validatorResponse = jwtTokenValidator.validateToken(validatorParameters);
+        assertTrue(validatorResponse != null);
+        assertTrue(validatorResponse.getToken() != null);
+        assertTrue(validatorResponse.getToken().getState() == STATE.VALID);
+        assertTrue(validatorResponse.getTokenRealm().equals("B"));
+        
+        Principal principal = validatorResponse.getPrincipal();
+        assertTrue(principal != null && principal.getName() != null);
+    }
+    
+    private Map<String, RealmProperties> getRealms() {
+        // Create Realms
+        Map<String, RealmProperties> realms = new HashMap<String, RealmProperties>();
+        RealmProperties realm = new RealmProperties();
+        realm.setIssuer("A-Issuer");
+        realms.put("A", realm);
+        realm = new RealmProperties();
+        realm.setIssuer("B-Issuer");
+        realms.put("B", realm);
+        return realms;
+    }
+    
+    private TokenProviderParameters createProviderParameters() throws WSSecurityException {
+        TokenProviderParameters parameters = new TokenProviderParameters();
+        
+        TokenRequirements tokenRequirements = new TokenRequirements();
+        tokenRequirements.setTokenType(JWTTokenProvider.JWT_TOKEN_TYPE);
+        parameters.setTokenRequirements(tokenRequirements);
+        
+        KeyRequirements keyRequirements = new KeyRequirements();
+        parameters.setKeyRequirements(keyRequirements);
+
+        parameters.setTokenStore(tokenStore);
+        
+        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());
+        stsProperties.setEncryptionCrypto(crypto);
+        stsProperties.setEncryptionUsername("myservicekey");
+        stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+        
+        return parameters;
+    }
+    
+    private TokenValidatorParameters createValidatorParameters() throws WSSecurityException {
+        TokenValidatorParameters parameters = new TokenValidatorParameters();
+        
+        TokenRequirements tokenRequirements = new TokenRequirements();
+        tokenRequirements.setTokenType(STSConstants.STATUS);
+        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);
+        
+        // Add STSProperties object
+        StaticSTSProperties 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");
+        parameters.setStsProperties(stsProperties);
+        parameters.setTokenStore(tokenStore);
+        
+        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;
+    }
+    
+    private Element createTokenWrapper(String token) {
+        Document doc = DOMUtils.newDocument();
+        Element tokenWrapper = doc.createElementNS(null, "TokenWrapper");
+        tokenWrapper.setTextContent(token);
+        return tokenWrapper;
+    }
+    
+    /**
+     * This class returns a realm associated with a JWTToken depending on the issuer.
+     */
+    private class IssuerJWTRealmCodec implements JWTRealmCodec {
+        
+        public String getRealmFromToken(JwtToken token) {
+            if ("A-Issuer".equals(token.getClaim(JwtConstants.CLAIM_ISSUER))) {
+                return "A";
+            } else if ("B-Issuer".equals(token.getClaim(JwtConstants.CLAIM_ISSUER))) {
+                return "B";
+            }
+            return null;
+        }
+        
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/b89bb65b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/validator/JWTTokenValidatorTest.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/validator/JWTTokenValidatorTest.java b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/validator/JWTTokenValidatorTest.java
index 6882751..13a60b8 100644
--- a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/validator/JWTTokenValidatorTest.java
+++ b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/validator/JWTTokenValidatorTest.java
@@ -27,6 +27,10 @@ import javax.security.auth.callback.Callback;
 import javax.security.auth.callback.CallbackHandler;
 import javax.security.auth.callback.UnsupportedCallbackException;
 
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.cxf.helpers.DOMUtils;
 import org.apache.cxf.jaxws.context.WebServiceContextImpl;
 import org.apache.cxf.jaxws.context.WrappedMessageContext;
 import org.apache.cxf.message.MessageImpl;
@@ -85,7 +89,7 @@ public class JWTTokenValidatorTest extends org.junit.Assert {
         TokenRequirements tokenRequirements = validatorParameters.getTokenRequirements();
         
         // Create a ValidateTarget consisting of a JWT Token
-        ReceivedToken validateTarget = new ReceivedToken(token);
+        ReceivedToken validateTarget = new ReceivedToken(createTokenWrapper(token));
         tokenRequirements.setValidateTarget(validateTarget);
         validatorParameters.setToken(validateTarget);
         
@@ -129,7 +133,7 @@ public class JWTTokenValidatorTest extends org.junit.Assert {
         TokenRequirements tokenRequirements = validatorParameters.getTokenRequirements();
         
         // Create a ValidateTarget consisting of a JWT Token
-        ReceivedToken validateTarget = new ReceivedToken(token);
+        ReceivedToken validateTarget = new ReceivedToken(createTokenWrapper(token));
         tokenRequirements.setValidateTarget(validateTarget);
         validatorParameters.setToken(validateTarget);
         
@@ -170,7 +174,7 @@ public class JWTTokenValidatorTest extends org.junit.Assert {
         TokenRequirements tokenRequirements = validatorParameters.getTokenRequirements();
         
         // Create a ValidateTarget consisting of a JWT Token
-        ReceivedToken validateTarget = new ReceivedToken(token);
+        ReceivedToken validateTarget = new ReceivedToken(createTokenWrapper(token));
         tokenRequirements.setValidateTarget(validateTarget);
         validatorParameters.setToken(validateTarget);
         
@@ -212,7 +216,7 @@ public class JWTTokenValidatorTest extends org.junit.Assert {
         TokenRequirements tokenRequirements = validatorParameters.getTokenRequirements();
         
         // Create a ValidateTarget consisting of a JWT Token
-        ReceivedToken validateTarget = new ReceivedToken(token);
+        ReceivedToken validateTarget = new ReceivedToken(createTokenWrapper(token));
         tokenRequirements.setValidateTarget(validateTarget);
         validatorParameters.setToken(validateTarget);
         
@@ -256,7 +260,7 @@ public class JWTTokenValidatorTest extends org.junit.Assert {
         TokenRequirements tokenRequirements = validatorParameters.getTokenRequirements();
         
         // Create a ValidateTarget consisting of a JWT Token
-        ReceivedToken validateTarget = new ReceivedToken(token);
+        ReceivedToken validateTarget = new ReceivedToken(createTokenWrapper(token));
         tokenRequirements.setValidateTarget(validateTarget);
         validatorParameters.setToken(validateTarget);
         
@@ -299,7 +303,7 @@ public class JWTTokenValidatorTest extends org.junit.Assert {
         TokenRequirements tokenRequirements = validatorParameters.getTokenRequirements();
         
         // Create a ValidateTarget consisting of a JWT Token
-        ReceivedToken validateTarget = new ReceivedToken(token);
+        ReceivedToken validateTarget = new ReceivedToken(createTokenWrapper(token));
         tokenRequirements.setValidateTarget(validateTarget);
         validatorParameters.setToken(validateTarget);
         
@@ -426,6 +430,13 @@ public class JWTTokenValidatorTest extends org.junit.Assert {
         }
     }
     
+    private Element createTokenWrapper(String token) {
+        Document doc = DOMUtils.newDocument();
+        Element tokenWrapper = doc.createElementNS(null, "TokenWrapper");
+        tokenWrapper.setTextContent(token);
+        return tokenWrapper;
+    }
+    
     private static class RoleJWTClaimsProvider extends DefaultJWTClaimsProvider {
         
         private String role;

http://git-wip-us.apache.org/repos/asf/cxf/blob/b89bb65b/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/jwt/JWTUnitTest.java
----------------------------------------------------------------------
diff --git a/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/jwt/JWTUnitTest.java b/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/jwt/JWTUnitTest.java
index 837db43..2f094e5 100644
--- a/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/jwt/JWTUnitTest.java
+++ b/services/sts/systests/advanced/src/test/java/org/apache/cxf/systest/sts/jwt/JWTUnitTest.java
@@ -67,10 +67,16 @@ public class JWTUnitTest extends AbstractBusClientServerTestBase {
         SpringBusFactory.setDefaultBus(bus);
         SpringBusFactory.setThreadDefaultBus(bus);
         
+        // Issue the token
         SecurityToken token = 
             requestSecurityToken(JWT_TOKEN_TYPE, bus, DEFAULT_ADDRESS, null, null);
         assertNotNull(token);
-        assertNotNull(token.getData());
+        assertNotNull(token.getToken());
+        
+        // Validate the token
+        token = validateSecurityToken(token, bus, null, null);
+        assertNotNull(token);
+        assertNotNull(token.getToken());
     }
     
     private SecurityToken requestSecurityToken(
@@ -107,4 +113,37 @@ public class JWTUnitTest extends AbstractBusClientServerTestBase {
 
         return stsClient.requestSecurityToken(endpointAddress);
     }
+    
+    private SecurityToken validateSecurityToken(
+        SecurityToken token,
+        Bus bus,
+        Map<String, Object> msgProperties,
+        String wsdlPort
+    ) throws Exception {
+        STSClient stsClient = new STSClient(bus);
+        String port = STSPORT;
+
+        stsClient.setWsdlLocation("https://localhost:" + port + "/SecurityTokenService/Transport?wsdl");
+        stsClient.setServiceName("{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}SecurityTokenService");
+        if (wsdlPort != null) {
+            stsClient.setEndpointName("{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}" + wsdlPort);
+        } else {
+            stsClient.setEndpointName("{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}Transport_Port");
+        }
+
+        Map<String, Object> properties = msgProperties;
+        if (properties == null) {
+            properties = new HashMap<String, Object>();
+            properties.put(SecurityConstants.USERNAME, "alice");
+            properties.put(
+                           SecurityConstants.CALLBACK_HANDLER, 
+                           "org.apache.cxf.systest.sts.common.CommonCallbackHandler"
+                );
+        }
+
+        stsClient.setProperties(properties);
+        stsClient.setSendKeyType(false);
+
+        return stsClient.validateSecurityToken(token).get(0);
+    }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/b89bb65b/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-sts.xml
----------------------------------------------------------------------
diff --git a/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-sts.xml b/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-sts.xml
index 989873f..f33a137 100644
--- a/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-sts.xml
+++ b/services/sts/systests/advanced/src/test/resources/org/apache/cxf/systest/sts/deployment/cxf-sts.xml
@@ -57,6 +57,7 @@
         <ref bean="transportX509TokenValidator"/>
         <ref bean="transportUsernameTokenValidator"/>
         <ref bean="transportCustomBSTTokenValidator"/>
+        <ref bean="transportJWTTokenValidator"/>
     </util:list>
     <bean id="transportCustomBSTTokenProvider" class="org.apache.cxf.systest.sts.deployment.CustomBSTTokenProvider">
         </bean>
@@ -104,6 +105,8 @@
         </bean>
     <bean id="transportSamlTokenValidator" class="org.apache.cxf.sts.token.validator.SAMLTokenValidator">
         </bean>
+    <bean id="transportJWTTokenValidator" class="org.apache.cxf.sts.token.validator.jwt.JWTTokenValidator">
+        </bean>
     <bean id="transportService" class="org.apache.cxf.sts.service.StaticService">
         <property name="endpoints" ref="transportEndpoints"/>
     </bean>