Renaming test
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/acd0e238 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/acd0e238 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/acd0e238 Branch: refs/heads/master Commit: acd0e23863edf73600e13a0f917750ba06430cc2 Parents: a245aad Author: Colm O hEigeartaigh <cohei...@apache.org> Authored: Wed Feb 10 16:14:59 2016 +0000 Committer: Colm O hEigeartaigh <cohei...@apache.org> Committed: Wed Feb 10 17:22:03 2016 +0000 ---------------------------------------------------------------------- .../cxf/systest/sts/rest/RESTUnitTest.java | 866 ------------------- .../cxf/systest/sts/rest/STSRESTTest.java | 866 +++++++++++++++++++ 2 files changed, 866 insertions(+), 866 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/acd0e238/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/rest/RESTUnitTest.java ---------------------------------------------------------------------- diff --git a/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/rest/RESTUnitTest.java b/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/rest/RESTUnitTest.java deleted file mode 100644 index a5ff4c0..0000000 --- a/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/rest/RESTUnitTest.java +++ /dev/null @@ -1,866 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cxf.systest.sts.rest; - -import java.io.IOException; -import java.net.URL; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.List; - -import javax.security.auth.callback.CallbackHandler; -import javax.ws.rs.core.Response; -import javax.xml.bind.JAXBElement; -import javax.xml.transform.dom.DOMSource; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -import org.apache.cxf.Bus; -import org.apache.cxf.bus.spring.SpringBusFactory; -import org.apache.cxf.jaxrs.client.WebClient; -import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm; -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.rt.security.claims.Claim; -import org.apache.cxf.rt.security.claims.ClaimCollection; -import org.apache.cxf.rt.security.saml.utils.SAMLUtils; -import org.apache.cxf.staxutils.StaxUtils; -import org.apache.cxf.staxutils.W3CDOMStreamWriter; -import org.apache.cxf.systest.sts.common.SecurityTestUtil; -import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase; -import org.apache.cxf.ws.security.sts.provider.model.RequestSecurityTokenResponseType; -import org.apache.cxf.ws.security.sts.provider.model.RequestedSecurityTokenType; -import org.apache.cxf.ws.security.sts.provider.model.StatusType; -import org.apache.cxf.ws.security.trust.STSUtils; -import org.apache.wss4j.common.crypto.Crypto; -import org.apache.wss4j.common.crypto.CryptoFactory; -import org.apache.wss4j.common.saml.OpenSAMLUtil; -import org.apache.wss4j.common.saml.SAMLKeyInfo; -import org.apache.wss4j.common.saml.SamlAssertionWrapper; -import org.apache.wss4j.common.util.Loader; -import org.apache.wss4j.dom.WSDocInfo; -import org.apache.wss4j.dom.engine.WSSecurityEngineResult; -import org.apache.wss4j.dom.handler.RequestData; -import org.apache.wss4j.dom.processor.Processor; -import org.apache.wss4j.dom.processor.SAMLTokenProcessor; -import org.junit.Assert; -import org.junit.BeforeClass; - -/** - * Some unit tests for the REST interface of the CXF STS. - */ -public class RESTUnitTest extends AbstractBusClientServerTestBase { - - static final String STSPORT = allocatePort(STSRESTServer.class); - - private static final String SAML1_TOKEN_TYPE = - "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1"; - private static final String SAML2_TOKEN_TYPE = - "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0"; - private static final String SYMMETRIC_KEY_KEYTYPE = - "http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey"; - private static final String PUBLIC_KEY_KEYTYPE = - "http://docs.oasis-open.org/ws-sx/ws-trust/200512/PublicKey"; - private static final String BEARER_KEYTYPE = - "http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer"; - private static final String DEFAULT_ADDRESS = - "https://localhost:8081/doubleit/services/doubleittransportsaml1"; - - @BeforeClass - public static void startServers() throws Exception { - assertTrue( - "Server failed to launch", - // run the server in the same process - // set this to false to fork - launchServer(STSRESTServer.class, true) - ); - } - - @org.junit.AfterClass - public static void cleanup() throws Exception { - SecurityTestUtil.cleanup(); - stopAllServers(); - } - - @org.junit.Test - public void testIssueSAML2Token() throws Exception { - SpringBusFactory bf = new SpringBusFactory(); - URL busFile = RESTUnitTest.class.getResource("cxf-client.xml"); - - Bus bus = bf.createBus(busFile.toString()); - SpringBusFactory.setDefaultBus(bus); - SpringBusFactory.setThreadDefaultBus(bus); - - String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; - WebClient client = WebClient.create(address, busFile.toString()); - - client.type("application/xml").accept("application/xml"); - client.path("saml2.0"); - - Response response = client.get(); - Document assertionDoc = response.readEntity(Document.class); - assertNotNull(assertionDoc); - - // Process the token - List<WSSecurityEngineResult> results = processToken(assertionDoc.getDocumentElement()); - - assertTrue(results != null && results.size() == 1); - SamlAssertionWrapper assertion = - (SamlAssertionWrapper)results.get(0).get(WSSecurityEngineResult.TAG_SAML_ASSERTION); - assertTrue(assertion != null); - assertTrue(assertion.getSaml2() != null && assertion.getSaml1() == null); - assertTrue(assertion.isSigned()); - - bus.shutdown(true); - } - - @org.junit.Test - public void testIssueSAML1Token() throws Exception { - SpringBusFactory bf = new SpringBusFactory(); - URL busFile = RESTUnitTest.class.getResource("cxf-client.xml"); - - Bus bus = bf.createBus(busFile.toString()); - SpringBusFactory.setDefaultBus(bus); - SpringBusFactory.setThreadDefaultBus(bus); - - String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; - WebClient client = WebClient.create(address, busFile.toString()); - - client.type("application/xml").accept("application/xml"); - client.path("saml1.1"); - - Response response = client.get(); - Document assertionDoc = response.readEntity(Document.class); - assertNotNull(assertionDoc); - - // Process the token - List<WSSecurityEngineResult> results = processToken(assertionDoc.getDocumentElement()); - - assertTrue(results != null && results.size() == 1); - SamlAssertionWrapper assertion = - (SamlAssertionWrapper)results.get(0).get(WSSecurityEngineResult.TAG_SAML_ASSERTION); - assertTrue(assertion != null); - assertTrue(assertion.getSaml2() == null && assertion.getSaml1() != null); - assertTrue(assertion.isSigned()); - - bus.shutdown(true); - } - - @org.junit.Test - public void testIssueSymmetricKeySaml1() throws Exception { - SpringBusFactory bf = new SpringBusFactory(); - URL busFile = RESTUnitTest.class.getResource("cxf-client.xml"); - - Bus bus = bf.createBus(busFile.toString()); - SpringBusFactory.setDefaultBus(bus); - SpringBusFactory.setThreadDefaultBus(bus); - - String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; - WebClient client = WebClient.create(address, busFile.toString()); - - client.type("application/xml").accept("application/xml"); - client.path("saml1.1"); - client.query("keyType", SYMMETRIC_KEY_KEYTYPE); - - Response response = client.get(); - Document assertionDoc = response.readEntity(Document.class); - assertNotNull(assertionDoc); - - // Process the token - List<WSSecurityEngineResult> results = processToken(assertionDoc.getDocumentElement()); - - assertTrue(results != null && results.size() == 1); - SamlAssertionWrapper assertion = - (SamlAssertionWrapper)results.get(0).get(WSSecurityEngineResult.TAG_SAML_ASSERTION); - assertTrue(assertion != null); - assertTrue(assertion.getSaml2() == null && assertion.getSaml1() != null); - assertTrue(assertion.isSigned()); - - List<String> methods = assertion.getConfirmationMethods(); - String confirmMethod = null; - if (methods != null && methods.size() > 0) { - confirmMethod = methods.get(0); - } - assertTrue(OpenSAMLUtil.isMethodHolderOfKey(confirmMethod)); - SAMLKeyInfo subjectKeyInfo = assertion.getSubjectKeyInfo(); - assertTrue(subjectKeyInfo.getSecret() != null); - - bus.shutdown(true); - } - - @org.junit.Test - public void testIssuePublicKeySAML2Token() throws Exception { - SpringBusFactory bf = new SpringBusFactory(); - URL busFile = RESTUnitTest.class.getResource("cxf-client.xml"); - - Bus bus = bf.createBus(busFile.toString()); - SpringBusFactory.setDefaultBus(bus); - SpringBusFactory.setThreadDefaultBus(bus); - - String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; - WebClient client = WebClient.create(address, busFile.toString()); - - client.type("application/xml").accept("application/xml"); - client.path("saml2.0"); - client.query("keyType", PUBLIC_KEY_KEYTYPE); - - Response response = client.get(); - Document assertionDoc = response.readEntity(Document.class); - assertNotNull(assertionDoc); - - // Process the token - List<WSSecurityEngineResult> results = processToken(assertionDoc.getDocumentElement()); - - assertTrue(results != null && results.size() == 1); - SamlAssertionWrapper assertion = - (SamlAssertionWrapper)results.get(0).get(WSSecurityEngineResult.TAG_SAML_ASSERTION); - assertTrue(assertion != null); - assertTrue(assertion.getSaml2() != null && assertion.getSaml1() == null); - assertTrue(assertion.isSigned()); - - List<String> methods = assertion.getConfirmationMethods(); - String confirmMethod = null; - if (methods != null && methods.size() > 0) { - confirmMethod = methods.get(0); - } - assertTrue(OpenSAMLUtil.isMethodHolderOfKey(confirmMethod)); - SAMLKeyInfo subjectKeyInfo = assertion.getSubjectKeyInfo(); - assertTrue(subjectKeyInfo.getCerts() != null); - - bus.shutdown(true); - } - - @org.junit.Test - public void testIssueBearerSAML1Token() throws Exception { - SpringBusFactory bf = new SpringBusFactory(); - URL busFile = RESTUnitTest.class.getResource("cxf-client.xml"); - - Bus bus = bf.createBus(busFile.toString()); - SpringBusFactory.setDefaultBus(bus); - SpringBusFactory.setThreadDefaultBus(bus); - - String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; - WebClient client = WebClient.create(address, busFile.toString()); - - client.type("application/xml").accept("application/xml"); - client.path("saml1.1"); - client.query("keyType", BEARER_KEYTYPE); - - Response response = client.get(); - Document assertionDoc = response.readEntity(Document.class); - assertNotNull(assertionDoc); - - // Process the token - List<WSSecurityEngineResult> results = processToken(assertionDoc.getDocumentElement()); - - assertTrue(results != null && results.size() == 1); - SamlAssertionWrapper assertion = - (SamlAssertionWrapper)results.get(0).get(WSSecurityEngineResult.TAG_SAML_ASSERTION); - assertTrue(assertion != null); - assertTrue(assertion.getSaml2() == null && assertion.getSaml1() != null); - assertTrue(assertion.isSigned()); - - List<String> methods = assertion.getConfirmationMethods(); - String confirmMethod = null; - if (methods != null && methods.size() > 0) { - confirmMethod = methods.get(0); - } - assertTrue(confirmMethod.contains("bearer")); - - bus.shutdown(true); - } - - @org.junit.Test - public void testIssueSAML2TokenAppliesTo() throws Exception { - SpringBusFactory bf = new SpringBusFactory(); - URL busFile = RESTUnitTest.class.getResource("cxf-client.xml"); - - Bus bus = bf.createBus(busFile.toString()); - SpringBusFactory.setDefaultBus(bus); - SpringBusFactory.setThreadDefaultBus(bus); - - String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; - WebClient client = WebClient.create(address, busFile.toString()); - - client.type("application/xml").accept("application/xml"); - client.path("saml2.0"); - client.query("appliesTo", DEFAULT_ADDRESS); - - Response response = client.get(); - Document assertionDoc = response.readEntity(Document.class); - assertNotNull(assertionDoc); - - // Process the token - List<WSSecurityEngineResult> results = processToken(assertionDoc.getDocumentElement()); - - assertTrue(results != null && results.size() == 1); - SamlAssertionWrapper assertion = - (SamlAssertionWrapper)results.get(0).get(WSSecurityEngineResult.TAG_SAML_ASSERTION); - assertTrue(assertion != null); - assertTrue(assertion.getSaml2() != null && assertion.getSaml1() == null); - assertTrue(assertion.isSigned()); - - bus.shutdown(true); - } - - @org.junit.Test - public void testIssueSAML2TokenUnknownAppliesTo() throws Exception { - SpringBusFactory bf = new SpringBusFactory(); - URL busFile = RESTUnitTest.class.getResource("cxf-client.xml"); - - Bus bus = bf.createBus(busFile.toString()); - SpringBusFactory.setDefaultBus(bus); - SpringBusFactory.setThreadDefaultBus(bus); - - String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; - WebClient client = WebClient.create(address, busFile.toString()); - - client.type("application/xml").accept("application/xml"); - client.path("saml2.0"); - client.query("appliesTo", "https://localhost:8081/tripleit/"); - - Response response = client.get(); - try { - response.readEntity(Document.class); - fail("Failure expected on an unknown AppliesTo address"); - } catch (Exception ex) { - // expected - } - - bus.shutdown(true); - } - - @org.junit.Test - public void testIssueSAML2TokenClaims() throws Exception { - SpringBusFactory bf = new SpringBusFactory(); - URL busFile = RESTUnitTest.class.getResource("cxf-client.xml"); - - Bus bus = bf.createBus(busFile.toString()); - SpringBusFactory.setDefaultBus(bus); - SpringBusFactory.setThreadDefaultBus(bus); - - String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; - WebClient client = WebClient.create(address, busFile.toString()); - - client.type("application/xml").accept("application/xml"); - client.path("saml2.0"); - - // First check that the role isn't usually in the generated token - - Response response = client.get(); - Document assertionDoc = response.readEntity(Document.class); - assertNotNull(assertionDoc); - - // Process the token - List<WSSecurityEngineResult> results = processToken(assertionDoc.getDocumentElement()); - - assertTrue(results != null && results.size() == 1); - SamlAssertionWrapper assertion = - (SamlAssertionWrapper)results.get(0).get(WSSecurityEngineResult.TAG_SAML_ASSERTION); - assertTrue(assertion != null); - assertTrue(assertion.getSaml2() != null && assertion.getSaml1() == null); - assertTrue(assertion.isSigned()); - - ClaimCollection claims = SAMLUtils.getClaims(assertion); - assertEquals(1, claims.size()); - Claim claim = claims.get(0); - String role = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role"; - assertNotEquals(claim.getClaimType().toString(), role); - - // Now get another token specifying the role - client.query("claim", role); - response = client.get(); - assertionDoc = response.readEntity(Document.class); - assertNotNull(assertionDoc); - - // Process the token - results = processToken(assertionDoc.getDocumentElement()); - - assertTrue(results != null && results.size() == 1); - assertion = - (SamlAssertionWrapper)results.get(0).get(WSSecurityEngineResult.TAG_SAML_ASSERTION); - assertTrue(assertion != null); - assertTrue(assertion.getSaml2() != null && assertion.getSaml1() == null); - assertTrue(assertion.isSigned()); - - claims = SAMLUtils.getClaims(assertion); - assertEquals(1, claims.size()); - claim = claims.get(0); - assertEquals(claim.getClaimType().toString(), role); - assertEquals("ordinary-user", claim.getValues().get(0)); - - bus.shutdown(true); - } - - @org.junit.Test - public void testIssueSAML2TokenViaWSTrust() throws Exception { - SpringBusFactory bf = new SpringBusFactory(); - URL busFile = RESTUnitTest.class.getResource("cxf-client.xml"); - - Bus bus = bf.createBus(busFile.toString()); - SpringBusFactory.setDefaultBus(bus); - SpringBusFactory.setThreadDefaultBus(bus); - - String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token/ws-trust"; - WebClient client = WebClient.create(address, busFile.toString()); - - client.type("application/xml").accept("application/xml"); - client.path("saml2.0"); - - Response response = client.get(); - RequestSecurityTokenResponseType securityResponse = - response.readEntity(RequestSecurityTokenResponseType.class); - - validateSAMLSecurityTokenResponse(securityResponse, true); - - bus.shutdown(true); - } - - @org.junit.Test - public void testIssueSAML2TokenViaPOST() throws Exception { - SpringBusFactory bf = new SpringBusFactory(); - URL busFile = RESTUnitTest.class.getResource("cxf-client.xml"); - - Bus bus = bf.createBus(busFile.toString()); - SpringBusFactory.setDefaultBus(bus); - SpringBusFactory.setThreadDefaultBus(bus); - - String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; - WebClient client = WebClient.create(address, busFile.toString()); - - client.type("application/xml").accept("application/xml"); - - // Create RequestSecurityToken - W3CDOMStreamWriter writer = new W3CDOMStreamWriter(); - String namespace = STSUtils.WST_NS_05_12; - writer.writeStartElement("wst", "RequestSecurityToken", namespace); - writer.writeNamespace("wst", namespace); - - writer.writeStartElement("wst", "RequestType", namespace); - writer.writeCharacters(namespace + "/Issue"); - writer.writeEndElement(); - - writer.writeStartElement("wst", "TokenType", namespace); - writer.writeCharacters(SAML2_TOKEN_TYPE); - writer.writeEndElement(); - - writer.writeEndElement(); - - Response response = client.post(new DOMSource(writer.getDocument().getDocumentElement())); - - RequestSecurityTokenResponseType securityResponse = - response.readEntity(RequestSecurityTokenResponseType.class); - - validateSAMLSecurityTokenResponse(securityResponse, true); - - bus.shutdown(true); - } - - @org.junit.Test - public void testExplicitlyIssueSAML2TokenViaPOST() throws Exception { - SpringBusFactory bf = new SpringBusFactory(); - URL busFile = RESTUnitTest.class.getResource("cxf-client.xml"); - - Bus bus = bf.createBus(busFile.toString()); - SpringBusFactory.setDefaultBus(bus); - SpringBusFactory.setThreadDefaultBus(bus); - - String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; - WebClient client = WebClient.create(address, busFile.toString()); - - client.type("application/xml").accept("application/xml"); - client.query("action", "issue"); - - // Create RequestSecurityToken - W3CDOMStreamWriter writer = new W3CDOMStreamWriter(); - String namespace = STSUtils.WST_NS_05_12; - writer.writeStartElement("wst", "RequestSecurityToken", namespace); - writer.writeNamespace("wst", namespace); - - writer.writeStartElement("wst", "RequestType", namespace); - writer.writeCharacters(namespace + "/Issue"); - writer.writeEndElement(); - - writer.writeStartElement("wst", "TokenType", namespace); - writer.writeCharacters(SAML2_TOKEN_TYPE); - writer.writeEndElement(); - - writer.writeEndElement(); - - Response response = client.post(new DOMSource(writer.getDocument().getDocumentElement())); - - RequestSecurityTokenResponseType securityResponse = - response.readEntity(RequestSecurityTokenResponseType.class); - - validateSAMLSecurityTokenResponse(securityResponse, true); - - bus.shutdown(true); - } - - @org.junit.Test - public void testExplicitlyIssueSAML1TokenViaPOST() throws Exception { - SpringBusFactory bf = new SpringBusFactory(); - URL busFile = RESTUnitTest.class.getResource("cxf-client.xml"); - - Bus bus = bf.createBus(busFile.toString()); - SpringBusFactory.setDefaultBus(bus); - SpringBusFactory.setThreadDefaultBus(bus); - - String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; - WebClient client = WebClient.create(address, busFile.toString()); - - client.type("application/xml").accept("application/xml"); - client.query("action", "issue"); - - // Create RequestSecurityToken - W3CDOMStreamWriter writer = new W3CDOMStreamWriter(); - String namespace = STSUtils.WST_NS_05_12; - writer.writeStartElement("wst", "RequestSecurityToken", namespace); - writer.writeNamespace("wst", namespace); - - writer.writeStartElement("wst", "RequestType", namespace); - writer.writeCharacters(namespace + "/Issue"); - writer.writeEndElement(); - - writer.writeStartElement("wst", "TokenType", namespace); - writer.writeCharacters(SAML1_TOKEN_TYPE); - writer.writeEndElement(); - - writer.writeEndElement(); - - Response response = client.post(new DOMSource(writer.getDocument().getDocumentElement())); - - RequestSecurityTokenResponseType securityResponse = - response.readEntity(RequestSecurityTokenResponseType.class); - - validateSAMLSecurityTokenResponse(securityResponse, false); - - bus.shutdown(true); - } - - @org.junit.Test - public void testValidateSAML2Token() throws Exception { - SpringBusFactory bf = new SpringBusFactory(); - URL busFile = RESTUnitTest.class.getResource("cxf-client.xml"); - - Bus bus = bf.createBus(busFile.toString()); - SpringBusFactory.setDefaultBus(bus); - SpringBusFactory.setThreadDefaultBus(bus); - - String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; - WebClient client = WebClient.create(address, busFile.toString()); - - client.type("application/xml").accept("application/xml"); - client.path("saml2.0"); - - // 1. Get a token via GET - Response response = client.get(); - Document assertionDoc = response.readEntity(Document.class); - assertNotNull(assertionDoc); - - // 2. Now validate it in the STS using POST - client = WebClient.create(address, busFile.toString()); - - client.type("application/xml").accept("application/xml"); - client.query("action", "validate"); - - // Create RequestSecurityToken - W3CDOMStreamWriter writer = new W3CDOMStreamWriter(); - String namespace = STSUtils.WST_NS_05_12; - writer.writeStartElement("wst", "RequestSecurityToken", namespace); - writer.writeNamespace("wst", namespace); - - writer.writeStartElement("wst", "RequestType", namespace); - writer.writeCharacters(namespace + "/Validate"); - writer.writeEndElement(); - - writer.writeStartElement("wst", "TokenType", namespace); - String tokenType = namespace + "/RSTR/Status"; - writer.writeCharacters(tokenType); - writer.writeEndElement(); - - writer.writeStartElement("wst", "ValidateTarget", namespace); - StaxUtils.copy(assertionDoc.getDocumentElement(), writer); - writer.writeEndElement(); - - writer.writeEndElement(); - - response = client.post(new DOMSource(writer.getDocument().getDocumentElement())); - - RequestSecurityTokenResponseType securityResponse = - response.readEntity(RequestSecurityTokenResponseType.class); - - StatusType status = null; - for (Object obj : securityResponse.getAny()) { - if (obj instanceof JAXBElement<?>) { - JAXBElement<?> jaxbElement = (JAXBElement<?>)obj; - if ("Status".equals(jaxbElement.getName().getLocalPart())) { - status = (StatusType)jaxbElement.getValue(); - break; - } - } - } - assertNotNull(status); - - // Check the token was valid - String validCode = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/status/valid"; - assertEquals(validCode, status.getCode()); - - bus.shutdown(true); - } - - @org.junit.Test - public void testRenewSAML2Token() throws Exception { - SpringBusFactory bf = new SpringBusFactory(); - URL busFile = RESTUnitTest.class.getResource("cxf-client.xml"); - - Bus bus = bf.createBus(busFile.toString()); - SpringBusFactory.setDefaultBus(bus); - SpringBusFactory.setThreadDefaultBus(bus); - - String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; - WebClient client = WebClient.create(address, busFile.toString()); - - client.type("application/xml").accept("application/xml"); - client.query("action", "issue"); - - // 1. Get a token via POST - - // Create RequestSecurityToken - W3CDOMStreamWriter writer = new W3CDOMStreamWriter(); - String namespace = STSUtils.WST_NS_05_12; - writer.writeStartElement("wst", "RequestSecurityToken", namespace); - writer.writeNamespace("wst", namespace); - - writer.writeStartElement("wst", "RequestType", namespace); - writer.writeCharacters(namespace + "/Issue"); - writer.writeEndElement(); - - writer.writeStartElement("wst", "TokenType", namespace); - writer.writeCharacters(SAML2_TOKEN_TYPE); - writer.writeEndElement(); - - writer.writeEndElement(); - - Response response = client.post(new DOMSource(writer.getDocument().getDocumentElement())); - - RequestSecurityTokenResponseType securityResponse = - response.readEntity(RequestSecurityTokenResponseType.class); - Element token = validateSAMLSecurityTokenResponse(securityResponse, true); - - // 2. Now validate it in the STS using POST - client = WebClient.create(address, busFile.toString()); - - client.type("application/xml").accept("application/xml"); - client.query("action", "renew"); - - // Create RequestSecurityToken - writer = new W3CDOMStreamWriter(); - writer.writeStartElement("wst", "RequestSecurityToken", namespace); - writer.writeNamespace("wst", namespace); - - writer.writeStartElement("wst", "RequestType", namespace); - writer.writeCharacters(namespace + "/Renew"); - writer.writeEndElement(); - - writer.writeStartElement("wst", "RenewTarget", namespace); - StaxUtils.copy(token, writer); - writer.writeEndElement(); - - writer.writeEndElement(); - - response = client.post(new DOMSource(writer.getDocument().getDocumentElement())); - - securityResponse = response.readEntity(RequestSecurityTokenResponseType.class); - - validateSAMLSecurityTokenResponse(securityResponse, true); - - bus.shutdown(true); - } - - @org.junit.Test - public void testIssueJWTToken() throws Exception { - SpringBusFactory bf = new SpringBusFactory(); - URL busFile = RESTUnitTest.class.getResource("cxf-client.xml"); - - Bus bus = bf.createBus(busFile.toString()); - SpringBusFactory.setDefaultBus(bus); - SpringBusFactory.setThreadDefaultBus(bus); - - String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; - WebClient client = WebClient.create(address, busFile.toString()); - - client.type("application/json").accept("application/json"); - client.path("jwt"); - - Response response = client.get(); - String token = response.readEntity(String.class); - assertNotNull(token); - - validateJWTToken(token, null); - } - - @org.junit.Test - public void testIssueJWTTokenAppliesTo() throws Exception { - SpringBusFactory bf = new SpringBusFactory(); - URL busFile = RESTUnitTest.class.getResource("cxf-client.xml"); - - Bus bus = bf.createBus(busFile.toString()); - SpringBusFactory.setDefaultBus(bus); - SpringBusFactory.setThreadDefaultBus(bus); - - String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; - WebClient client = WebClient.create(address, busFile.toString()); - - client.type("application/json").accept("application/json"); - client.path("jwt"); - client.query("appliesTo", DEFAULT_ADDRESS); - - Response response = client.get(); - String token = response.readEntity(String.class); - assertNotNull(token); - - validateJWTToken(token, DEFAULT_ADDRESS); - } - - @org.junit.Test - public void testIssueJWTTokenClaims() throws Exception { - SpringBusFactory bf = new SpringBusFactory(); - URL busFile = RESTUnitTest.class.getResource("cxf-client.xml"); - - Bus bus = bf.createBus(busFile.toString()); - SpringBusFactory.setDefaultBus(bus); - SpringBusFactory.setThreadDefaultBus(bus); - - String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; - WebClient client = WebClient.create(address, busFile.toString()); - - client.type("application/json").accept("application/json"); - client.path("jwt"); - - // First check that the role isn't usually in the generated token - - Response response = client.get(); - String token = response.readEntity(String.class); - assertNotNull(token); - - JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(token); - JwtToken jwt = jwtConsumer.getJwtToken(); - - String role = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role"; - assertTrue(jwt.getClaim(role) == null); - - // Now get another token specifying the role - client.query("claim", role); - - response = client.get(); - token = response.readEntity(String.class); - assertNotNull(token); - - // Process the token - validateJWTToken(token, null); - - jwtConsumer = new JwsJwtCompactConsumer(token); - jwt = jwtConsumer.getJwtToken(); - assertEquals("ordinary-user", jwt.getClaim(role)); - - bus.shutdown(true); - } - - private Element validateSAMLSecurityTokenResponse( - RequestSecurityTokenResponseType securityResponse, boolean saml2 - ) throws Exception { - RequestedSecurityTokenType requestedSecurityToken = null; - for (Object obj : securityResponse.getAny()) { - if (obj instanceof JAXBElement<?>) { - JAXBElement<?> jaxbElement = (JAXBElement<?>)obj; - if ("RequestedSecurityToken".equals(jaxbElement.getName().getLocalPart())) { - requestedSecurityToken = (RequestedSecurityTokenType)jaxbElement.getValue(); - break; - } - } - } - assertNotNull(requestedSecurityToken); - - // Process the token - List<WSSecurityEngineResult> results = - processToken((Element)requestedSecurityToken.getAny()); - - assertTrue(results != null && results.size() == 1); - SamlAssertionWrapper assertion = - (SamlAssertionWrapper)results.get(0).get(WSSecurityEngineResult.TAG_SAML_ASSERTION); - assertTrue(assertion != null); - if (saml2) { - assertTrue(assertion.getSaml2() != null && assertion.getSaml1() == null); - } else { - assertTrue(assertion.getSaml2() == null && assertion.getSaml1() != null); - } - assertTrue(assertion.isSigned()); - - return (Element)results.get(0).get(WSSecurityEngineResult.TAG_TOKEN_ELEMENT); - } - - private List<WSSecurityEngineResult> processToken(Element assertionElement) - throws Exception { - RequestData requestData = new RequestData(); - requestData.setDisableBSPEnforcement(true); - CallbackHandler callbackHandler = new org.apache.cxf.systest.sts.common.CommonCallbackHandler(); - requestData.setCallbackHandler(callbackHandler); - Crypto crypto = CryptoFactory.getInstance("serviceKeystore.properties"); - requestData.setDecCrypto(crypto); - requestData.setSigVerCrypto(crypto); - - Processor processor = new SAMLTokenProcessor(); - return processor.handleToken( - assertionElement, requestData, new WSDocInfo(assertionElement.getOwnerDocument()) - ); - } - - private void validateJWTToken(String token, String audience) - throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { - JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(token); - JwtToken jwt = jwtConsumer.getJwtToken(); - - // Validate claims - Assert.assertEquals("DoubleItSTSIssuer", jwt.getClaim(JwtConstants.CLAIM_ISSUER)); - if (audience != null) { - @SuppressWarnings("unchecked") - List<String> audiences = (List<String>)jwt.getClaim(JwtConstants.CLAIM_AUDIENCE); - assertEquals(1, audiences.size()); - Assert.assertEquals(audience, audiences.get(0)); - } - Assert.assertNotNull(jwt.getClaim(JwtConstants.CLAIM_EXPIRY)); - Assert.assertNotNull(jwt.getClaim(JwtConstants.CLAIM_ISSUED_AT)); - - KeyStore keystore = KeyStore.getInstance("JKS"); - keystore.load(Loader.getResource("servicestore.jks").openStream(), "sspass".toCharArray()); - Certificate cert = keystore.getCertificate("mystskey"); - Assert.assertNotNull(cert); - - Assert.assertTrue(jwtConsumer.verifySignatureWith((X509Certificate)cert, - SignatureAlgorithm.RS256)); - } - -} http://git-wip-us.apache.org/repos/asf/cxf/blob/acd0e238/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/rest/STSRESTTest.java ---------------------------------------------------------------------- diff --git a/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/rest/STSRESTTest.java b/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/rest/STSRESTTest.java new file mode 100644 index 0000000..f9ec98c --- /dev/null +++ b/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/rest/STSRESTTest.java @@ -0,0 +1,866 @@ +/** + * 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.systest.sts.rest; + +import java.io.IOException; +import java.net.URL; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.List; + +import javax.security.auth.callback.CallbackHandler; +import javax.ws.rs.core.Response; +import javax.xml.bind.JAXBElement; +import javax.xml.transform.dom.DOMSource; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import org.apache.cxf.Bus; +import org.apache.cxf.bus.spring.SpringBusFactory; +import org.apache.cxf.jaxrs.client.WebClient; +import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm; +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.rt.security.claims.Claim; +import org.apache.cxf.rt.security.claims.ClaimCollection; +import org.apache.cxf.rt.security.saml.utils.SAMLUtils; +import org.apache.cxf.staxutils.StaxUtils; +import org.apache.cxf.staxutils.W3CDOMStreamWriter; +import org.apache.cxf.systest.sts.common.SecurityTestUtil; +import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase; +import org.apache.cxf.ws.security.sts.provider.model.RequestSecurityTokenResponseType; +import org.apache.cxf.ws.security.sts.provider.model.RequestedSecurityTokenType; +import org.apache.cxf.ws.security.sts.provider.model.StatusType; +import org.apache.cxf.ws.security.trust.STSUtils; +import org.apache.wss4j.common.crypto.Crypto; +import org.apache.wss4j.common.crypto.CryptoFactory; +import org.apache.wss4j.common.saml.OpenSAMLUtil; +import org.apache.wss4j.common.saml.SAMLKeyInfo; +import org.apache.wss4j.common.saml.SamlAssertionWrapper; +import org.apache.wss4j.common.util.Loader; +import org.apache.wss4j.dom.WSDocInfo; +import org.apache.wss4j.dom.engine.WSSecurityEngineResult; +import org.apache.wss4j.dom.handler.RequestData; +import org.apache.wss4j.dom.processor.Processor; +import org.apache.wss4j.dom.processor.SAMLTokenProcessor; +import org.junit.Assert; +import org.junit.BeforeClass; + +/** + * Some tests for the REST interface of the CXF STS. + */ +public class STSRESTTest extends AbstractBusClientServerTestBase { + + static final String STSPORT = allocatePort(STSRESTServer.class); + + private static final String SAML1_TOKEN_TYPE = + "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1"; + private static final String SAML2_TOKEN_TYPE = + "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0"; + private static final String SYMMETRIC_KEY_KEYTYPE = + "http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey"; + private static final String PUBLIC_KEY_KEYTYPE = + "http://docs.oasis-open.org/ws-sx/ws-trust/200512/PublicKey"; + private static final String BEARER_KEYTYPE = + "http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer"; + private static final String DEFAULT_ADDRESS = + "https://localhost:8081/doubleit/services/doubleittransportsaml1"; + + @BeforeClass + public static void startServers() throws Exception { + assertTrue( + "Server failed to launch", + // run the server in the same process + // set this to false to fork + launchServer(STSRESTServer.class, true) + ); + } + + @org.junit.AfterClass + public static void cleanup() throws Exception { + SecurityTestUtil.cleanup(); + stopAllServers(); + } + + @org.junit.Test + public void testIssueSAML2Token() throws Exception { + SpringBusFactory bf = new SpringBusFactory(); + URL busFile = STSRESTTest.class.getResource("cxf-client.xml"); + + Bus bus = bf.createBus(busFile.toString()); + SpringBusFactory.setDefaultBus(bus); + SpringBusFactory.setThreadDefaultBus(bus); + + String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; + WebClient client = WebClient.create(address, busFile.toString()); + + client.type("application/xml").accept("application/xml"); + client.path("saml2.0"); + + Response response = client.get(); + Document assertionDoc = response.readEntity(Document.class); + assertNotNull(assertionDoc); + + // Process the token + List<WSSecurityEngineResult> results = processToken(assertionDoc.getDocumentElement()); + + assertTrue(results != null && results.size() == 1); + SamlAssertionWrapper assertion = + (SamlAssertionWrapper)results.get(0).get(WSSecurityEngineResult.TAG_SAML_ASSERTION); + assertTrue(assertion != null); + assertTrue(assertion.getSaml2() != null && assertion.getSaml1() == null); + assertTrue(assertion.isSigned()); + + bus.shutdown(true); + } + + @org.junit.Test + public void testIssueSAML1Token() throws Exception { + SpringBusFactory bf = new SpringBusFactory(); + URL busFile = STSRESTTest.class.getResource("cxf-client.xml"); + + Bus bus = bf.createBus(busFile.toString()); + SpringBusFactory.setDefaultBus(bus); + SpringBusFactory.setThreadDefaultBus(bus); + + String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; + WebClient client = WebClient.create(address, busFile.toString()); + + client.type("application/xml").accept("application/xml"); + client.path("saml1.1"); + + Response response = client.get(); + Document assertionDoc = response.readEntity(Document.class); + assertNotNull(assertionDoc); + + // Process the token + List<WSSecurityEngineResult> results = processToken(assertionDoc.getDocumentElement()); + + assertTrue(results != null && results.size() == 1); + SamlAssertionWrapper assertion = + (SamlAssertionWrapper)results.get(0).get(WSSecurityEngineResult.TAG_SAML_ASSERTION); + assertTrue(assertion != null); + assertTrue(assertion.getSaml2() == null && assertion.getSaml1() != null); + assertTrue(assertion.isSigned()); + + bus.shutdown(true); + } + + @org.junit.Test + public void testIssueSymmetricKeySaml1() throws Exception { + SpringBusFactory bf = new SpringBusFactory(); + URL busFile = STSRESTTest.class.getResource("cxf-client.xml"); + + Bus bus = bf.createBus(busFile.toString()); + SpringBusFactory.setDefaultBus(bus); + SpringBusFactory.setThreadDefaultBus(bus); + + String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; + WebClient client = WebClient.create(address, busFile.toString()); + + client.type("application/xml").accept("application/xml"); + client.path("saml1.1"); + client.query("keyType", SYMMETRIC_KEY_KEYTYPE); + + Response response = client.get(); + Document assertionDoc = response.readEntity(Document.class); + assertNotNull(assertionDoc); + + // Process the token + List<WSSecurityEngineResult> results = processToken(assertionDoc.getDocumentElement()); + + assertTrue(results != null && results.size() == 1); + SamlAssertionWrapper assertion = + (SamlAssertionWrapper)results.get(0).get(WSSecurityEngineResult.TAG_SAML_ASSERTION); + assertTrue(assertion != null); + assertTrue(assertion.getSaml2() == null && assertion.getSaml1() != null); + assertTrue(assertion.isSigned()); + + List<String> methods = assertion.getConfirmationMethods(); + String confirmMethod = null; + if (methods != null && methods.size() > 0) { + confirmMethod = methods.get(0); + } + assertTrue(OpenSAMLUtil.isMethodHolderOfKey(confirmMethod)); + SAMLKeyInfo subjectKeyInfo = assertion.getSubjectKeyInfo(); + assertTrue(subjectKeyInfo.getSecret() != null); + + bus.shutdown(true); + } + + @org.junit.Test + public void testIssuePublicKeySAML2Token() throws Exception { + SpringBusFactory bf = new SpringBusFactory(); + URL busFile = STSRESTTest.class.getResource("cxf-client.xml"); + + Bus bus = bf.createBus(busFile.toString()); + SpringBusFactory.setDefaultBus(bus); + SpringBusFactory.setThreadDefaultBus(bus); + + String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; + WebClient client = WebClient.create(address, busFile.toString()); + + client.type("application/xml").accept("application/xml"); + client.path("saml2.0"); + client.query("keyType", PUBLIC_KEY_KEYTYPE); + + Response response = client.get(); + Document assertionDoc = response.readEntity(Document.class); + assertNotNull(assertionDoc); + + // Process the token + List<WSSecurityEngineResult> results = processToken(assertionDoc.getDocumentElement()); + + assertTrue(results != null && results.size() == 1); + SamlAssertionWrapper assertion = + (SamlAssertionWrapper)results.get(0).get(WSSecurityEngineResult.TAG_SAML_ASSERTION); + assertTrue(assertion != null); + assertTrue(assertion.getSaml2() != null && assertion.getSaml1() == null); + assertTrue(assertion.isSigned()); + + List<String> methods = assertion.getConfirmationMethods(); + String confirmMethod = null; + if (methods != null && methods.size() > 0) { + confirmMethod = methods.get(0); + } + assertTrue(OpenSAMLUtil.isMethodHolderOfKey(confirmMethod)); + SAMLKeyInfo subjectKeyInfo = assertion.getSubjectKeyInfo(); + assertTrue(subjectKeyInfo.getCerts() != null); + + bus.shutdown(true); + } + + @org.junit.Test + public void testIssueBearerSAML1Token() throws Exception { + SpringBusFactory bf = new SpringBusFactory(); + URL busFile = STSRESTTest.class.getResource("cxf-client.xml"); + + Bus bus = bf.createBus(busFile.toString()); + SpringBusFactory.setDefaultBus(bus); + SpringBusFactory.setThreadDefaultBus(bus); + + String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; + WebClient client = WebClient.create(address, busFile.toString()); + + client.type("application/xml").accept("application/xml"); + client.path("saml1.1"); + client.query("keyType", BEARER_KEYTYPE); + + Response response = client.get(); + Document assertionDoc = response.readEntity(Document.class); + assertNotNull(assertionDoc); + + // Process the token + List<WSSecurityEngineResult> results = processToken(assertionDoc.getDocumentElement()); + + assertTrue(results != null && results.size() == 1); + SamlAssertionWrapper assertion = + (SamlAssertionWrapper)results.get(0).get(WSSecurityEngineResult.TAG_SAML_ASSERTION); + assertTrue(assertion != null); + assertTrue(assertion.getSaml2() == null && assertion.getSaml1() != null); + assertTrue(assertion.isSigned()); + + List<String> methods = assertion.getConfirmationMethods(); + String confirmMethod = null; + if (methods != null && methods.size() > 0) { + confirmMethod = methods.get(0); + } + assertTrue(confirmMethod.contains("bearer")); + + bus.shutdown(true); + } + + @org.junit.Test + public void testIssueSAML2TokenAppliesTo() throws Exception { + SpringBusFactory bf = new SpringBusFactory(); + URL busFile = STSRESTTest.class.getResource("cxf-client.xml"); + + Bus bus = bf.createBus(busFile.toString()); + SpringBusFactory.setDefaultBus(bus); + SpringBusFactory.setThreadDefaultBus(bus); + + String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; + WebClient client = WebClient.create(address, busFile.toString()); + + client.type("application/xml").accept("application/xml"); + client.path("saml2.0"); + client.query("appliesTo", DEFAULT_ADDRESS); + + Response response = client.get(); + Document assertionDoc = response.readEntity(Document.class); + assertNotNull(assertionDoc); + + // Process the token + List<WSSecurityEngineResult> results = processToken(assertionDoc.getDocumentElement()); + + assertTrue(results != null && results.size() == 1); + SamlAssertionWrapper assertion = + (SamlAssertionWrapper)results.get(0).get(WSSecurityEngineResult.TAG_SAML_ASSERTION); + assertTrue(assertion != null); + assertTrue(assertion.getSaml2() != null && assertion.getSaml1() == null); + assertTrue(assertion.isSigned()); + + bus.shutdown(true); + } + + @org.junit.Test + public void testIssueSAML2TokenUnknownAppliesTo() throws Exception { + SpringBusFactory bf = new SpringBusFactory(); + URL busFile = STSRESTTest.class.getResource("cxf-client.xml"); + + Bus bus = bf.createBus(busFile.toString()); + SpringBusFactory.setDefaultBus(bus); + SpringBusFactory.setThreadDefaultBus(bus); + + String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; + WebClient client = WebClient.create(address, busFile.toString()); + + client.type("application/xml").accept("application/xml"); + client.path("saml2.0"); + client.query("appliesTo", "https://localhost:8081/tripleit/"); + + Response response = client.get(); + try { + response.readEntity(Document.class); + fail("Failure expected on an unknown AppliesTo address"); + } catch (Exception ex) { + // expected + } + + bus.shutdown(true); + } + + @org.junit.Test + public void testIssueSAML2TokenClaims() throws Exception { + SpringBusFactory bf = new SpringBusFactory(); + URL busFile = STSRESTTest.class.getResource("cxf-client.xml"); + + Bus bus = bf.createBus(busFile.toString()); + SpringBusFactory.setDefaultBus(bus); + SpringBusFactory.setThreadDefaultBus(bus); + + String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; + WebClient client = WebClient.create(address, busFile.toString()); + + client.type("application/xml").accept("application/xml"); + client.path("saml2.0"); + + // First check that the role isn't usually in the generated token + + Response response = client.get(); + Document assertionDoc = response.readEntity(Document.class); + assertNotNull(assertionDoc); + + // Process the token + List<WSSecurityEngineResult> results = processToken(assertionDoc.getDocumentElement()); + + assertTrue(results != null && results.size() == 1); + SamlAssertionWrapper assertion = + (SamlAssertionWrapper)results.get(0).get(WSSecurityEngineResult.TAG_SAML_ASSERTION); + assertTrue(assertion != null); + assertTrue(assertion.getSaml2() != null && assertion.getSaml1() == null); + assertTrue(assertion.isSigned()); + + ClaimCollection claims = SAMLUtils.getClaims(assertion); + assertEquals(1, claims.size()); + Claim claim = claims.get(0); + String role = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role"; + assertNotEquals(claim.getClaimType().toString(), role); + + // Now get another token specifying the role + client.query("claim", role); + response = client.get(); + assertionDoc = response.readEntity(Document.class); + assertNotNull(assertionDoc); + + // Process the token + results = processToken(assertionDoc.getDocumentElement()); + + assertTrue(results != null && results.size() == 1); + assertion = + (SamlAssertionWrapper)results.get(0).get(WSSecurityEngineResult.TAG_SAML_ASSERTION); + assertTrue(assertion != null); + assertTrue(assertion.getSaml2() != null && assertion.getSaml1() == null); + assertTrue(assertion.isSigned()); + + claims = SAMLUtils.getClaims(assertion); + assertEquals(1, claims.size()); + claim = claims.get(0); + assertEquals(claim.getClaimType().toString(), role); + assertEquals("ordinary-user", claim.getValues().get(0)); + + bus.shutdown(true); + } + + @org.junit.Test + public void testIssueSAML2TokenViaWSTrust() throws Exception { + SpringBusFactory bf = new SpringBusFactory(); + URL busFile = STSRESTTest.class.getResource("cxf-client.xml"); + + Bus bus = bf.createBus(busFile.toString()); + SpringBusFactory.setDefaultBus(bus); + SpringBusFactory.setThreadDefaultBus(bus); + + String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token/ws-trust"; + WebClient client = WebClient.create(address, busFile.toString()); + + client.type("application/xml").accept("application/xml"); + client.path("saml2.0"); + + Response response = client.get(); + RequestSecurityTokenResponseType securityResponse = + response.readEntity(RequestSecurityTokenResponseType.class); + + validateSAMLSecurityTokenResponse(securityResponse, true); + + bus.shutdown(true); + } + + @org.junit.Test + public void testIssueSAML2TokenViaPOST() throws Exception { + SpringBusFactory bf = new SpringBusFactory(); + URL busFile = STSRESTTest.class.getResource("cxf-client.xml"); + + Bus bus = bf.createBus(busFile.toString()); + SpringBusFactory.setDefaultBus(bus); + SpringBusFactory.setThreadDefaultBus(bus); + + String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; + WebClient client = WebClient.create(address, busFile.toString()); + + client.type("application/xml").accept("application/xml"); + + // Create RequestSecurityToken + W3CDOMStreamWriter writer = new W3CDOMStreamWriter(); + String namespace = STSUtils.WST_NS_05_12; + writer.writeStartElement("wst", "RequestSecurityToken", namespace); + writer.writeNamespace("wst", namespace); + + writer.writeStartElement("wst", "RequestType", namespace); + writer.writeCharacters(namespace + "/Issue"); + writer.writeEndElement(); + + writer.writeStartElement("wst", "TokenType", namespace); + writer.writeCharacters(SAML2_TOKEN_TYPE); + writer.writeEndElement(); + + writer.writeEndElement(); + + Response response = client.post(new DOMSource(writer.getDocument().getDocumentElement())); + + RequestSecurityTokenResponseType securityResponse = + response.readEntity(RequestSecurityTokenResponseType.class); + + validateSAMLSecurityTokenResponse(securityResponse, true); + + bus.shutdown(true); + } + + @org.junit.Test + public void testExplicitlyIssueSAML2TokenViaPOST() throws Exception { + SpringBusFactory bf = new SpringBusFactory(); + URL busFile = STSRESTTest.class.getResource("cxf-client.xml"); + + Bus bus = bf.createBus(busFile.toString()); + SpringBusFactory.setDefaultBus(bus); + SpringBusFactory.setThreadDefaultBus(bus); + + String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; + WebClient client = WebClient.create(address, busFile.toString()); + + client.type("application/xml").accept("application/xml"); + client.query("action", "issue"); + + // Create RequestSecurityToken + W3CDOMStreamWriter writer = new W3CDOMStreamWriter(); + String namespace = STSUtils.WST_NS_05_12; + writer.writeStartElement("wst", "RequestSecurityToken", namespace); + writer.writeNamespace("wst", namespace); + + writer.writeStartElement("wst", "RequestType", namespace); + writer.writeCharacters(namespace + "/Issue"); + writer.writeEndElement(); + + writer.writeStartElement("wst", "TokenType", namespace); + writer.writeCharacters(SAML2_TOKEN_TYPE); + writer.writeEndElement(); + + writer.writeEndElement(); + + Response response = client.post(new DOMSource(writer.getDocument().getDocumentElement())); + + RequestSecurityTokenResponseType securityResponse = + response.readEntity(RequestSecurityTokenResponseType.class); + + validateSAMLSecurityTokenResponse(securityResponse, true); + + bus.shutdown(true); + } + + @org.junit.Test + public void testExplicitlyIssueSAML1TokenViaPOST() throws Exception { + SpringBusFactory bf = new SpringBusFactory(); + URL busFile = STSRESTTest.class.getResource("cxf-client.xml"); + + Bus bus = bf.createBus(busFile.toString()); + SpringBusFactory.setDefaultBus(bus); + SpringBusFactory.setThreadDefaultBus(bus); + + String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; + WebClient client = WebClient.create(address, busFile.toString()); + + client.type("application/xml").accept("application/xml"); + client.query("action", "issue"); + + // Create RequestSecurityToken + W3CDOMStreamWriter writer = new W3CDOMStreamWriter(); + String namespace = STSUtils.WST_NS_05_12; + writer.writeStartElement("wst", "RequestSecurityToken", namespace); + writer.writeNamespace("wst", namespace); + + writer.writeStartElement("wst", "RequestType", namespace); + writer.writeCharacters(namespace + "/Issue"); + writer.writeEndElement(); + + writer.writeStartElement("wst", "TokenType", namespace); + writer.writeCharacters(SAML1_TOKEN_TYPE); + writer.writeEndElement(); + + writer.writeEndElement(); + + Response response = client.post(new DOMSource(writer.getDocument().getDocumentElement())); + + RequestSecurityTokenResponseType securityResponse = + response.readEntity(RequestSecurityTokenResponseType.class); + + validateSAMLSecurityTokenResponse(securityResponse, false); + + bus.shutdown(true); + } + + @org.junit.Test + public void testValidateSAML2Token() throws Exception { + SpringBusFactory bf = new SpringBusFactory(); + URL busFile = STSRESTTest.class.getResource("cxf-client.xml"); + + Bus bus = bf.createBus(busFile.toString()); + SpringBusFactory.setDefaultBus(bus); + SpringBusFactory.setThreadDefaultBus(bus); + + String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; + WebClient client = WebClient.create(address, busFile.toString()); + + client.type("application/xml").accept("application/xml"); + client.path("saml2.0"); + + // 1. Get a token via GET + Response response = client.get(); + Document assertionDoc = response.readEntity(Document.class); + assertNotNull(assertionDoc); + + // 2. Now validate it in the STS using POST + client = WebClient.create(address, busFile.toString()); + + client.type("application/xml").accept("application/xml"); + client.query("action", "validate"); + + // Create RequestSecurityToken + W3CDOMStreamWriter writer = new W3CDOMStreamWriter(); + String namespace = STSUtils.WST_NS_05_12; + writer.writeStartElement("wst", "RequestSecurityToken", namespace); + writer.writeNamespace("wst", namespace); + + writer.writeStartElement("wst", "RequestType", namespace); + writer.writeCharacters(namespace + "/Validate"); + writer.writeEndElement(); + + writer.writeStartElement("wst", "TokenType", namespace); + String tokenType = namespace + "/RSTR/Status"; + writer.writeCharacters(tokenType); + writer.writeEndElement(); + + writer.writeStartElement("wst", "ValidateTarget", namespace); + StaxUtils.copy(assertionDoc.getDocumentElement(), writer); + writer.writeEndElement(); + + writer.writeEndElement(); + + response = client.post(new DOMSource(writer.getDocument().getDocumentElement())); + + RequestSecurityTokenResponseType securityResponse = + response.readEntity(RequestSecurityTokenResponseType.class); + + StatusType status = null; + for (Object obj : securityResponse.getAny()) { + if (obj instanceof JAXBElement<?>) { + JAXBElement<?> jaxbElement = (JAXBElement<?>)obj; + if ("Status".equals(jaxbElement.getName().getLocalPart())) { + status = (StatusType)jaxbElement.getValue(); + break; + } + } + } + assertNotNull(status); + + // Check the token was valid + String validCode = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/status/valid"; + assertEquals(validCode, status.getCode()); + + bus.shutdown(true); + } + + @org.junit.Test + public void testRenewSAML2Token() throws Exception { + SpringBusFactory bf = new SpringBusFactory(); + URL busFile = STSRESTTest.class.getResource("cxf-client.xml"); + + Bus bus = bf.createBus(busFile.toString()); + SpringBusFactory.setDefaultBus(bus); + SpringBusFactory.setThreadDefaultBus(bus); + + String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; + WebClient client = WebClient.create(address, busFile.toString()); + + client.type("application/xml").accept("application/xml"); + client.query("action", "issue"); + + // 1. Get a token via POST + + // Create RequestSecurityToken + W3CDOMStreamWriter writer = new W3CDOMStreamWriter(); + String namespace = STSUtils.WST_NS_05_12; + writer.writeStartElement("wst", "RequestSecurityToken", namespace); + writer.writeNamespace("wst", namespace); + + writer.writeStartElement("wst", "RequestType", namespace); + writer.writeCharacters(namespace + "/Issue"); + writer.writeEndElement(); + + writer.writeStartElement("wst", "TokenType", namespace); + writer.writeCharacters(SAML2_TOKEN_TYPE); + writer.writeEndElement(); + + writer.writeEndElement(); + + Response response = client.post(new DOMSource(writer.getDocument().getDocumentElement())); + + RequestSecurityTokenResponseType securityResponse = + response.readEntity(RequestSecurityTokenResponseType.class); + Element token = validateSAMLSecurityTokenResponse(securityResponse, true); + + // 2. Now validate it in the STS using POST + client = WebClient.create(address, busFile.toString()); + + client.type("application/xml").accept("application/xml"); + client.query("action", "renew"); + + // Create RequestSecurityToken + writer = new W3CDOMStreamWriter(); + writer.writeStartElement("wst", "RequestSecurityToken", namespace); + writer.writeNamespace("wst", namespace); + + writer.writeStartElement("wst", "RequestType", namespace); + writer.writeCharacters(namespace + "/Renew"); + writer.writeEndElement(); + + writer.writeStartElement("wst", "RenewTarget", namespace); + StaxUtils.copy(token, writer); + writer.writeEndElement(); + + writer.writeEndElement(); + + response = client.post(new DOMSource(writer.getDocument().getDocumentElement())); + + securityResponse = response.readEntity(RequestSecurityTokenResponseType.class); + + validateSAMLSecurityTokenResponse(securityResponse, true); + + bus.shutdown(true); + } + + @org.junit.Test + public void testIssueJWTToken() throws Exception { + SpringBusFactory bf = new SpringBusFactory(); + URL busFile = STSRESTTest.class.getResource("cxf-client.xml"); + + Bus bus = bf.createBus(busFile.toString()); + SpringBusFactory.setDefaultBus(bus); + SpringBusFactory.setThreadDefaultBus(bus); + + String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; + WebClient client = WebClient.create(address, busFile.toString()); + + client.type("application/json").accept("application/json"); + client.path("jwt"); + + Response response = client.get(); + String token = response.readEntity(String.class); + assertNotNull(token); + + validateJWTToken(token, null); + } + + @org.junit.Test + public void testIssueJWTTokenAppliesTo() throws Exception { + SpringBusFactory bf = new SpringBusFactory(); + URL busFile = STSRESTTest.class.getResource("cxf-client.xml"); + + Bus bus = bf.createBus(busFile.toString()); + SpringBusFactory.setDefaultBus(bus); + SpringBusFactory.setThreadDefaultBus(bus); + + String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; + WebClient client = WebClient.create(address, busFile.toString()); + + client.type("application/json").accept("application/json"); + client.path("jwt"); + client.query("appliesTo", DEFAULT_ADDRESS); + + Response response = client.get(); + String token = response.readEntity(String.class); + assertNotNull(token); + + validateJWTToken(token, DEFAULT_ADDRESS); + } + + @org.junit.Test + public void testIssueJWTTokenClaims() throws Exception { + SpringBusFactory bf = new SpringBusFactory(); + URL busFile = STSRESTTest.class.getResource("cxf-client.xml"); + + Bus bus = bf.createBus(busFile.toString()); + SpringBusFactory.setDefaultBus(bus); + SpringBusFactory.setThreadDefaultBus(bus); + + String address = "https://localhost:" + STSPORT + "/SecurityTokenService/token"; + WebClient client = WebClient.create(address, busFile.toString()); + + client.type("application/json").accept("application/json"); + client.path("jwt"); + + // First check that the role isn't usually in the generated token + + Response response = client.get(); + String token = response.readEntity(String.class); + assertNotNull(token); + + JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(token); + JwtToken jwt = jwtConsumer.getJwtToken(); + + String role = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role"; + assertTrue(jwt.getClaim(role) == null); + + // Now get another token specifying the role + client.query("claim", role); + + response = client.get(); + token = response.readEntity(String.class); + assertNotNull(token); + + // Process the token + validateJWTToken(token, null); + + jwtConsumer = new JwsJwtCompactConsumer(token); + jwt = jwtConsumer.getJwtToken(); + assertEquals("ordinary-user", jwt.getClaim(role)); + + bus.shutdown(true); + } + + private Element validateSAMLSecurityTokenResponse( + RequestSecurityTokenResponseType securityResponse, boolean saml2 + ) throws Exception { + RequestedSecurityTokenType requestedSecurityToken = null; + for (Object obj : securityResponse.getAny()) { + if (obj instanceof JAXBElement<?>) { + JAXBElement<?> jaxbElement = (JAXBElement<?>)obj; + if ("RequestedSecurityToken".equals(jaxbElement.getName().getLocalPart())) { + requestedSecurityToken = (RequestedSecurityTokenType)jaxbElement.getValue(); + break; + } + } + } + assertNotNull(requestedSecurityToken); + + // Process the token + List<WSSecurityEngineResult> results = + processToken((Element)requestedSecurityToken.getAny()); + + assertTrue(results != null && results.size() == 1); + SamlAssertionWrapper assertion = + (SamlAssertionWrapper)results.get(0).get(WSSecurityEngineResult.TAG_SAML_ASSERTION); + assertTrue(assertion != null); + if (saml2) { + assertTrue(assertion.getSaml2() != null && assertion.getSaml1() == null); + } else { + assertTrue(assertion.getSaml2() == null && assertion.getSaml1() != null); + } + assertTrue(assertion.isSigned()); + + return (Element)results.get(0).get(WSSecurityEngineResult.TAG_TOKEN_ELEMENT); + } + + private List<WSSecurityEngineResult> processToken(Element assertionElement) + throws Exception { + RequestData requestData = new RequestData(); + requestData.setDisableBSPEnforcement(true); + CallbackHandler callbackHandler = new org.apache.cxf.systest.sts.common.CommonCallbackHandler(); + requestData.setCallbackHandler(callbackHandler); + Crypto crypto = CryptoFactory.getInstance("serviceKeystore.properties"); + requestData.setDecCrypto(crypto); + requestData.setSigVerCrypto(crypto); + + Processor processor = new SAMLTokenProcessor(); + return processor.handleToken( + assertionElement, requestData, new WSDocInfo(assertionElement.getOwnerDocument()) + ); + } + + private void validateJWTToken(String token, String audience) + throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { + JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(token); + JwtToken jwt = jwtConsumer.getJwtToken(); + + // Validate claims + Assert.assertEquals("DoubleItSTSIssuer", jwt.getClaim(JwtConstants.CLAIM_ISSUER)); + if (audience != null) { + @SuppressWarnings("unchecked") + List<String> audiences = (List<String>)jwt.getClaim(JwtConstants.CLAIM_AUDIENCE); + assertEquals(1, audiences.size()); + Assert.assertEquals(audience, audiences.get(0)); + } + Assert.assertNotNull(jwt.getClaim(JwtConstants.CLAIM_EXPIRY)); + Assert.assertNotNull(jwt.getClaim(JwtConstants.CLAIM_ISSUED_AT)); + + KeyStore keystore = KeyStore.getInstance("JKS"); + keystore.load(Loader.getResource("servicestore.jks").openStream(), "sspass".toCharArray()); + Certificate cert = keystore.getCertificate("mystskey"); + Assert.assertNotNull(cert); + + Assert.assertTrue(jwtConsumer.verifySignatureWith((X509Certificate)cert, + SignatureAlgorithm.RS256)); + } + +}