Return-Path: X-Original-To: apmail-cxf-commits-archive@www.apache.org Delivered-To: apmail-cxf-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 3177D187D1 for ; Mon, 9 Nov 2015 19:27:53 +0000 (UTC) Received: (qmail 88002 invoked by uid 500); 9 Nov 2015 19:27:52 -0000 Delivered-To: apmail-cxf-commits-archive@cxf.apache.org Received: (qmail 87922 invoked by uid 500); 9 Nov 2015 19:27:52 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 87899 invoked by uid 99); 9 Nov 2015 19:27:52 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 09 Nov 2015 19:27:52 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id A8CDADFE80; Mon, 9 Nov 2015 19:27:52 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: coheigea@apache.org To: commits@cxf.apache.org Date: Mon, 09 Nov 2015 19:27:53 -0000 Message-Id: <7d62aa9319a74f7195873ad954d3047a@git.apache.org> In-Reply-To: <9dd034da8a854e8aa2e8619103846b4d@git.apache.org> References: <9dd034da8a854e8aa2e8619103846b4d@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [2/5] cxf git commit: Adding some realms tests Adding some realms tests Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/512e9e90 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/512e9e90 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/512e9e90 Branch: refs/heads/3.1.x-fixes Commit: 512e9e900f3c840e1b0ab4c2fb4c3950bffc84ad Parents: 2715120 Author: Colm O hEigeartaigh Authored: Mon Nov 9 12:09:59 2015 +0000 Committer: Colm O hEigeartaigh Committed: Mon Nov 9 19:27:38 2015 +0000 ---------------------------------------------------------------------- .../provider/jwt/DefaultJWTClaimsProvider.java | 11 +- .../jwt/JWTClaimsProviderParameters.java | 9 + .../token/provider/jwt/JWTTokenProvider.java | 21 +- .../sts/operation/IssueJWTRealmUnitTest.java | 447 +++++++++++++++++++ .../provider/JWTTokenProviderRealmTest.java | 154 +++++++ 5 files changed, 638 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/512e9e90/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/DefaultJWTClaimsProvider.java ---------------------------------------------------------------------- diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/DefaultJWTClaimsProvider.java b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/DefaultJWTClaimsProvider.java index 5addb95..9f29e62 100644 --- a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/DefaultJWTClaimsProvider.java +++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/DefaultJWTClaimsProvider.java @@ -27,6 +27,7 @@ import javax.security.auth.x500.X500Principal; import org.apache.cxf.common.logging.LogUtils; import org.apache.cxf.rs.security.jose.jwt.JwtClaims; +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.provider.TokenProviderParameters; @@ -49,7 +50,15 @@ public class DefaultJWTClaimsProvider implements JWTClaimsProvider { JwtClaims claims = new JwtClaims(); claims.setSubject(getSubjectName(jwtClaimsProviderParameters)); claims.setTokenId(UUID.randomUUID().toString()); - claims.setIssuer("DoubleItSTSIssuer"); + + // Set the Issuer + String issuer = jwtClaimsProviderParameters.getIssuer(); + if (issuer == null) { + STSPropertiesMBean stsProperties = jwtClaimsProviderParameters.getProviderParameters().getStsProperties(); + claims.setIssuer(stsProperties.getIssuer()); + } else { + claims.setIssuer(issuer); + } Date currentDate = new Date(); claims.setIssuedAt(currentDate.getTime() / 1000L); http://git-wip-us.apache.org/repos/asf/cxf/blob/512e9e90/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/JWTClaimsProviderParameters.java ---------------------------------------------------------------------- diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/JWTClaimsProviderParameters.java b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/JWTClaimsProviderParameters.java index 24f1ed9..3008408 100644 --- a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/JWTClaimsProviderParameters.java +++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/JWTClaimsProviderParameters.java @@ -27,6 +27,7 @@ import org.apache.cxf.sts.token.provider.TokenProviderParameters; public class JWTClaimsProviderParameters { private TokenProviderParameters providerParameters; + private String issuer; public TokenProviderParameters getProviderParameters() { return providerParameters; @@ -35,5 +36,13 @@ public class JWTClaimsProviderParameters { public void setProviderParameters(TokenProviderParameters providerParameters) { this.providerParameters = providerParameters; } + + public String getIssuer() { + return issuer; + } + + public void setIssuer(String issuer) { + this.issuer = issuer; + } } http://git-wip-us.apache.org/repos/asf/cxf/blob/512e9e90/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 6096649..0f5a383 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 @@ -93,9 +93,18 @@ public class JWTTokenProvider implements TokenProvider { LOG.fine("Handling token of type: " + tokenRequirements.getTokenType()); } + String realm = tokenParameters.getRealm(); + RealmProperties jwtRealm = null; + if (realm != null && realmMap.containsKey(realm)) { + jwtRealm = realmMap.get(realm); + } + // Get the claims JWTClaimsProviderParameters jwtClaimsProviderParameters = new JWTClaimsProviderParameters(); jwtClaimsProviderParameters.setProviderParameters(tokenParameters); + if (jwtRealm != null) { + jwtClaimsProviderParameters.setIssuer(jwtRealm.getIssuer()); + } JwtClaims claims = jwtClaimsProvider.getJwtClaims(jwtClaimsProviderParameters); @@ -127,7 +136,7 @@ public class JWTTokenProvider implements TokenProvider { JwtToken token = new JwtToken(claims); - String tokenData = signToken(token, null, tokenParameters.getStsProperties(), + String tokenData = signToken(token, jwtRealm, tokenParameters.getStsProperties(), tokenParameters.getTokenRequirements()); TokenProviderResponse response = new TokenProviderResponse(); @@ -243,8 +252,14 @@ public class JWTTokenProvider implements TokenProvider { String password = cb[0].getPassword(); signingProperties.put(JoseConstants.RSSEC_SIGNATURE_ALGORITHM, signatureAlgorithm); - signingProperties.put(JoseConstants.RSSEC_KEY_STORE_ALIAS, alias); - signingProperties.put(JoseConstants.RSSEC_KEY_PSWD, password); + if (alias != null) { + signingProperties.put(JoseConstants.RSSEC_KEY_STORE_ALIAS, alias); + } + if (password != null) { + signingProperties.put(JoseConstants.RSSEC_KEY_PSWD, password); + } else { + throw new STSException("Can't get the password", STSException.REQUEST_FAILED); + } if (!(signatureCrypto instanceof Merlin)) { throw new STSException("Can't get the keystore", STSException.REQUEST_FAILED); http://git-wip-us.apache.org/repos/asf/cxf/blob/512e9e90/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 new file mode 100644 index 0000000..9e2f8a7 --- /dev/null +++ b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueJWTRealmUnitTest.java @@ -0,0 +1,447 @@ +/** + * 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.Principal; +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.xml.bind.JAXBElement; +import javax.xml.namespace.QName; + +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.jws.JwsJwtCompactConsumer; +import org.apache.cxf.rs.security.jose.jwt.JwtConstants; +import org.apache.cxf.rs.security.jose.jwt.JwtToken; +import org.apache.cxf.security.SecurityContext; +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.service.ServiceMBean; +import org.apache.cxf.sts.service.StaticService; +import org.apache.cxf.sts.token.provider.TokenProvider; +import org.apache.cxf.sts.token.provider.jwt.JWTTokenProvider; +import org.apache.cxf.sts.token.realm.RealmProperties; +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.wss4j.common.crypto.Crypto; +import org.apache.wss4j.common.crypto.CryptoFactory; +import org.apache.wss4j.common.principal.CustomTokenPrincipal; +import org.apache.wss4j.dom.WSConstants; +import org.junit.Assert; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * Some unit tests for the issue operation to issue JWT tokens in a specific realm. + */ +public class IssueJWTRealmUnitTest extends org.junit.Assert { + + public static final QName REQUESTED_SECURITY_TOKEN = + QNameConstants.WS_TRUST_FACTORY.createRequestedSecurityToken(null).getName(); + public static final QName ATTACHED_REFERENCE = + QNameConstants.WS_TRUST_FACTORY.createRequestedAttachedReference(null).getName(); + public static final QName UNATTACHED_REFERENCE = + QNameConstants.WS_TRUST_FACTORY.createRequestedUnattachedReference(null).getName(); + + /** + * Test to successfully issue a JWT token in realm "A". + */ + @org.junit.Test + public void testIssueJWTTokenRealmA() throws Exception { + TokenIssueOperation issueOperation = new TokenIssueOperation(); + + // Add Token Provider + List providerList = new ArrayList(); + JWTTokenProvider provider = new JWTTokenProvider(); + provider.setRealmMap(createRealms()); + providerList.add(provider); + issueOperation.setTokenProviders(providerList); + + // 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()); + issueOperation.setStsProperties(stsProperties); + + // Mock up a request + RequestSecurityTokenType request = new RequestSecurityTokenType(); + JAXBElement tokenType = + new JAXBElement( + QNameConstants.TOKEN_TYPE, String.class, JWTTokenProvider.JWT_TOKEN_TYPE + ); + request.getAny().add(tokenType); + request.getAny().add(createAppliesToElement("http://dummy-service.com/dummy")); + + // Mock up message context + MessageImpl msg = new MessageImpl(); + WrappedMessageContext msgCtx = new WrappedMessageContext(msg); + msgCtx.put("url", "ldap"); + msgCtx.put( + SecurityContext.class.getName(), + createSecurityContext(new CustomTokenPrincipal("alice")) + ); + WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx); + + // Issue a token + RequestSecurityTokenResponseCollectionType response = + issueOperation.issue(request, webServiceContext); + List 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); + JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(jwtToken); + JwtToken jwt = jwtConsumer.getJwtToken(); + Assert.assertEquals("A-Issuer", jwt.getClaim(JwtConstants.CLAIM_ISSUER)); + } + + /** + * Test to successfully issue a JWT token in realm "B". + */ + @org.junit.Test + public void testIssueJWTTokenRealmB() throws Exception { + TokenIssueOperation issueOperation = new TokenIssueOperation(); + + // Add Token Provider + List providerList = new ArrayList(); + JWTTokenProvider provider = new JWTTokenProvider(); + provider.setRealmMap(createRealms()); + providerList.add(provider); + issueOperation.setTokenProviders(providerList); + + // 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()); + issueOperation.setStsProperties(stsProperties); + + // Mock up a request + RequestSecurityTokenType request = new RequestSecurityTokenType(); + JAXBElement tokenType = + new JAXBElement( + QNameConstants.TOKEN_TYPE, String.class, JWTTokenProvider.JWT_TOKEN_TYPE + ); + request.getAny().add(tokenType); + request.getAny().add(createAppliesToElement("http://dummy-service.com/dummy")); + + // Mock up message context + MessageImpl msg = new MessageImpl(); + WrappedMessageContext msgCtx = new WrappedMessageContext(msg); + msgCtx.put("url", "https"); + msgCtx.put( + SecurityContext.class.getName(), + createSecurityContext(new CustomTokenPrincipal("alice")) + ); + WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx); + + // Issue a token + RequestSecurityTokenResponseCollectionType response = + issueOperation.issue(request, webServiceContext); + List 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); + JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(jwtToken); + JwtToken jwt = jwtConsumer.getJwtToken(); + Assert.assertEquals("B-Issuer", jwt.getClaim(JwtConstants.CLAIM_ISSUER)); + } + + /** + * Test to successfully issue a JWT token in the default realm. + */ + @org.junit.Test + public void testIssueJWTTokenDefaultRealm() throws Exception { + TokenIssueOperation issueOperation = new TokenIssueOperation(); + + // Add Token Provider + List providerList = new ArrayList(); + JWTTokenProvider provider = new JWTTokenProvider(); + provider.setRealmMap(createRealms()); + providerList.add(provider); + issueOperation.setTokenProviders(providerList); + + // 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()); + issueOperation.setStsProperties(stsProperties); + + // Mock up a request + RequestSecurityTokenType request = new RequestSecurityTokenType(); + JAXBElement tokenType = + new JAXBElement( + QNameConstants.TOKEN_TYPE, String.class, JWTTokenProvider.JWT_TOKEN_TYPE + ); + request.getAny().add(tokenType); + request.getAny().add(createAppliesToElement("http://dummy-service.com/dummy")); + + // Mock up message context + MessageImpl msg = new MessageImpl(); + WrappedMessageContext msgCtx = new WrappedMessageContext(msg); + msgCtx.put("url", "unknown"); + msgCtx.put( + SecurityContext.class.getName(), + createSecurityContext(new CustomTokenPrincipal("alice")) + ); + WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx); + + // Issue a token + RequestSecurityTokenResponseCollectionType response = + issueOperation.issue(request, webServiceContext); + List 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); + JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(jwtToken); + JwtToken jwt = jwtConsumer.getJwtToken(); + Assert.assertEquals("STS", jwt.getClaim(JwtConstants.CLAIM_ISSUER)); + } + + + /** + * Test to successfully issue a JWT token in realm "B" + * using crypto definition in RealmProperties + */ + @org.junit.Test + public void testIssueJWTTokenRealmBCustomCrypto() throws Exception { + TokenIssueOperation issueOperation = new TokenIssueOperation(); + + // Add Token Provider + List providerList = new ArrayList(); + JWTTokenProvider provider = new JWTTokenProvider(); + provider.setRealmMap(createRealms()); + providerList.add(provider); + issueOperation.setTokenProviders(providerList); + + // 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()); + issueOperation.setStsProperties(stsProperties); + + // Set signature properties in Realm B + Map realms = provider.getRealmMap(); + RealmProperties realm = realms.get("B"); + realm.setSignatureCrypto(crypto); + realm.setCallbackHandler(new PasswordCallbackHandler()); + + + // Mock up a request + RequestSecurityTokenType request = new RequestSecurityTokenType(); + JAXBElement tokenType = + new JAXBElement( + QNameConstants.TOKEN_TYPE, String.class, JWTTokenProvider.JWT_TOKEN_TYPE + ); + request.getAny().add(tokenType); + request.getAny().add(createAppliesToElement("http://dummy-service.com/dummy")); + + // Mock up message context + MessageImpl msg = new MessageImpl(); + WrappedMessageContext msgCtx = new WrappedMessageContext(msg); + msgCtx.put("url", "https"); + msgCtx.put( + SecurityContext.class.getName(), + createSecurityContext(new CustomTokenPrincipal("alice")) + ); + WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx); + + // Issue a token - this will fail as the RealmProperties configuration is inconsistent + // no signature alias defined + try { + issueOperation.issue(request, webServiceContext); + fail("Failure expected on no encryption name"); + } catch (STSException ex) { + // expected + } + + realm.setSignatureAlias("mystskey"); + + // Issue a token + RequestSecurityTokenResponseCollectionType response = + issueOperation.issue(request, webServiceContext); + List 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); + JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(jwtToken); + JwtToken jwt = jwtConsumer.getJwtToken(); + Assert.assertEquals("B-Issuer", jwt.getClaim(JwtConstants.CLAIM_ISSUER)); + } + + /** + * Create some JWT Realms + */ + private Map createRealms() { + Map realms = new HashMap(); + 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; + } + + /* + * Create a security context object + */ + private SecurityContext createSecurityContext(final Principal p) { + return new SecurityContext() { + public Principal getUserPrincipal() { + return p; + } + public boolean isUserInRole(String role) { + return false; + } + }; + } + + /* + * Mock up an AppliesTo element using the supplied address + */ + private Element createAppliesToElement(String addressUrl) { + Document doc = DOMUtils.createDocument(); + Element appliesTo = doc.createElementNS(STSConstants.WSP_NS, "wsp:AppliesTo"); + appliesTo.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:wsp", STSConstants.WSP_NS); + Element endpointRef = doc.createElementNS(STSConstants.WSA_NS_05, "wsa:EndpointReference"); + endpointRef.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:wsa", STSConstants.WSA_NS_05); + Element address = doc.createElementNS(STSConstants.WSA_NS_05, "wsa:Address"); + address.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:wsa", STSConstants.WSA_NS_05); + address.setTextContent(addressUrl); + endpointRef.appendChild(address); + appliesTo.appendChild(endpointRef); + return appliesTo; + } + + 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/512e9e90/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTTokenProviderRealmTest.java ---------------------------------------------------------------------- diff --git a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTTokenProviderRealmTest.java b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTTokenProviderRealmTest.java new file mode 100644 index 0000000..2a747c1 --- /dev/null +++ b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTTokenProviderRealmTest.java @@ -0,0 +1,154 @@ +/** + * 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.HashMap; +import java.util.Map; +import java.util.Properties; + +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.StaticSTSProperties; +import org.apache.cxf.sts.common.PasswordCallbackHandler; +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.sts.token.realm.RealmProperties; +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 creating JWT Tokens via the JWTTokenProvider in different realms + */ +public class JWTTokenProviderRealmTest extends org.junit.Assert { + + @org.junit.Test + public void testRealms() throws Exception { + TokenProvider jwtTokenProvider = new JWTTokenProvider(); + TokenProviderParameters providerParameters = createProviderParameters(JWTTokenProvider.JWT_TOKEN_TYPE); + providerParameters.setRealm("A"); + + // Create Realms + Map jwtRealms = new HashMap(); + RealmProperties jwtRealm = new RealmProperties(); + jwtRealm.setIssuer("A-Issuer"); + jwtRealms.put("A", jwtRealm); + jwtRealm = new RealmProperties(); + jwtRealm.setIssuer("B-Issuer"); + jwtRealms.put("B", jwtRealm); + ((JWTTokenProvider)jwtTokenProvider).setRealmMap(jwtRealms); + + // Realm "A" + assertTrue(jwtTokenProvider.canHandleToken(JWTTokenProvider.JWT_TOKEN_TYPE, "A")); + TokenProviderResponse providerResponse = jwtTokenProvider.createToken(providerParameters); + assertTrue(providerResponse != null); + assertTrue(providerResponse.getToken() != null && providerResponse.getTokenId() != null); + + String token = (String)providerResponse.getToken(); + assertNotNull(token); + JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(token); + JwtToken jwt = jwtConsumer.getJwtToken(); + + assertEquals(jwt.getClaim(JwtConstants.CLAIM_ISSUER), "A-Issuer"); + + // Realm "B" + providerParameters.setRealm("B"); + assertTrue(jwtTokenProvider.canHandleToken(JWTTokenProvider.JWT_TOKEN_TYPE, "B")); + providerResponse = jwtTokenProvider.createToken(providerParameters); + assertTrue(providerResponse != null); + assertTrue(providerResponse.getToken() != null && providerResponse.getTokenId() != null); + + token = (String)providerResponse.getToken(); + assertNotNull(token); + jwtConsumer = new JwsJwtCompactConsumer(token); + jwt = jwtConsumer.getJwtToken(); + + assertEquals(jwt.getClaim(JwtConstants.CLAIM_ISSUER), "B-Issuer"); + + // Default Realm + providerParameters.setRealm(null); + assertTrue(jwtTokenProvider.canHandleToken(JWTTokenProvider.JWT_TOKEN_TYPE, null)); + providerResponse = jwtTokenProvider.createToken(providerParameters); + assertTrue(providerResponse != null); + assertTrue(providerResponse.getToken() != null && providerResponse.getTokenId() != null); + + token = (String)providerResponse.getToken(); + assertNotNull(token); + jwtConsumer = new JwsJwtCompactConsumer(token); + jwt = jwtConsumer.getJwtToken(); + + assertEquals(jwt.getClaim(JwtConstants.CLAIM_ISSUER), "STS"); + } + + private TokenProviderParameters createProviderParameters( + String tokenType + ) throws WSSecurityException { + TokenProviderParameters parameters = new TokenProviderParameters(); + + TokenRequirements tokenRequirements = new TokenRequirements(); + tokenRequirements.setTokenType(tokenType); + 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.setEncryptionCrypto(crypto); + stsProperties.setSignatureCrypto(crypto); + stsProperties.setEncryptionUsername("myservicekey"); + 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; + } + +}