blob: 79c836c1a4d0abe7d3790d1b9f28ebd2279a52bd [file] [log] [blame]
/**
* 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.fediz.core.federation;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.math.BigInteger;
import java.util.Collections;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.apache.cxf.fediz.common.STSUtil;
import org.apache.cxf.fediz.common.SecurityTestUtil;
import org.apache.cxf.fediz.core.Claim;
import org.apache.cxf.fediz.core.ClaimTypes;
import org.apache.cxf.fediz.core.FederationConstants;
import org.apache.cxf.fediz.core.KeystoreCallbackHandler;
import org.apache.cxf.fediz.core.SAML2CallbackHandler;
import org.apache.cxf.fediz.core.config.FedizConfigurator;
import org.apache.cxf.fediz.core.config.FedizContext;
import org.apache.cxf.fediz.core.config.jaxb.ArgumentType;
import org.apache.cxf.fediz.core.config.jaxb.AudienceUris;
import org.apache.cxf.fediz.core.config.jaxb.CallbackType;
import org.apache.cxf.fediz.core.config.jaxb.CertificateStores;
import org.apache.cxf.fediz.core.config.jaxb.ClaimType;
import org.apache.cxf.fediz.core.config.jaxb.ClaimTypesRequested;
import org.apache.cxf.fediz.core.config.jaxb.ContextConfig;
import org.apache.cxf.fediz.core.config.jaxb.FederationProtocolType;
import org.apache.cxf.fediz.core.config.jaxb.FedizConfig;
import org.apache.cxf.fediz.core.config.jaxb.KeyStoreType;
import org.apache.cxf.fediz.core.config.jaxb.ProtocolType;
import org.apache.cxf.fediz.core.config.jaxb.TrustManagersType;
import org.apache.cxf.fediz.core.config.jaxb.TrustedIssuerType;
import org.apache.cxf.fediz.core.config.jaxb.TrustedIssuers;
import org.apache.cxf.fediz.core.config.jaxb.ValidationType;
import org.apache.cxf.fediz.core.exception.ProcessingException;
import org.apache.cxf.fediz.core.processor.FederationProcessorImpl;
import org.apache.cxf.fediz.core.processor.FedizProcessor;
import org.apache.cxf.fediz.core.processor.FedizRequest;
import org.apache.cxf.fediz.core.processor.FedizResponse;
import org.apache.wss4j.common.crypto.Crypto;
import org.apache.wss4j.common.crypto.CryptoFactory;
import org.apache.wss4j.common.ext.WSPasswordCallback;
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.common.saml.SAMLCallback;
import org.apache.wss4j.common.saml.SAMLUtil;
import org.apache.wss4j.common.saml.SamlAssertionWrapper;
import org.apache.wss4j.common.saml.bean.AudienceRestrictionBean;
import org.apache.wss4j.common.saml.bean.ConditionsBean;
import org.apache.wss4j.common.saml.builder.SAML2Constants;
import org.apache.wss4j.common.util.DOM2Writer;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
/**
* Test for requested claims
*/
public class RequestedClaimsTest {
private static final String ISSUER = "FedizSTSIssuer";
private static final String PROTOCOL_VERSION = "1.0.0";
//private static final String REQUEST = "request value";
private static final String REPLY = "reply value";
private static final String TARGET_REALM = "target realm";
private static final String HOME_REALM_CLASS = "org.apache.fediz.realm.MyHomeRealm.class";
private static final String FRESHNESS_VALUE = "10000";
private static final String CONFIG_NAME = "ROOT";
private static final String CLOCK_SKEW = "1000";
private static final String AUTH_TYPE_VALUE = "some auth type";
private static final String AUDIENCE_URI_1 = "http://host_one:port/url";
private static final String ROLE_DELIMITER = ";";
private static final String ROLE_URI = "http://someserver:8080/path/roles.uri";
private static final String CLAIM_TYPE_1 = ClaimTypes.FIRSTNAME.toString();
private static final String CLAIM_TYPE_2 = ClaimTypes.LASTNAME.toString();
private static Crypto crypto;
private static CallbackHandler cbPasswordHandler = new KeystoreCallbackHandler();
@BeforeClass
public static void init() {
try {
crypto = CryptoFactory.getInstance("signature.properties");
} catch (Exception e) {
e.printStackTrace();
}
}
@AfterClass
public static void cleanup() {
SecurityTestUtil.cleanup();
}
//CHECKSTYLE:OFF
private FedizConfig createConfiguration() throws JAXBException {
FedizConfig rootConfig = new FedizConfig();
ContextConfig config = new ContextConfig();
rootConfig.getContextConfig().add(config);
config.setName(CONFIG_NAME);
config.setMaximumClockSkew(new BigInteger(CLOCK_SKEW));
CertificateStores certStores = new CertificateStores();
TrustManagersType tm0 = new TrustManagersType();
KeyStoreType ks0 = new KeyStoreType();
ks0.setType("JKS");
ks0.setPassword("storepass");
ks0.setFile("ststrust.jks");
tm0.setKeyStore(ks0);
certStores.getTrustManager().add(tm0);
config.setCertificateStores(certStores);
TrustedIssuers trustedIssuers = new TrustedIssuers();
TrustedIssuerType ti0 = new TrustedIssuerType();
ti0.setCertificateValidation(ValidationType.PEER_TRUST);
trustedIssuers.getIssuer().add(ti0);
config.setTrustedIssuers(trustedIssuers);
ProtocolType protocol = new FederationProtocolType();
CallbackType authType = new CallbackType();
authType.setType(ArgumentType.STRING);
authType.setValue(AUTH_TYPE_VALUE);
((FederationProtocolType)protocol).setAuthenticationType(authType);
CallbackType freshness = new CallbackType();
freshness.setValue(FRESHNESS_VALUE);
((FederationProtocolType)protocol).setFreshness(freshness);
CallbackType homeRealm = new CallbackType();
homeRealm.setType(ArgumentType.CLASS);
homeRealm.setValue(HOME_REALM_CLASS);
((FederationProtocolType)protocol).setHomeRealm(homeRealm);
((FederationProtocolType)protocol).setReply(REPLY);
((FederationProtocolType)protocol).setVersion(PROTOCOL_VERSION);
config.setProtocol(protocol);
AudienceUris audienceUris = new AudienceUris();
audienceUris.getAudienceItem().add(AUDIENCE_URI_1);
config.setAudienceUris(audienceUris);
protocol.setRoleDelimiter(ROLE_DELIMITER);
protocol.setRoleURI(ROLE_URI);
ClaimTypesRequested claimTypeReq = new ClaimTypesRequested();
ClaimType claimType = new ClaimType();
claimType.setOptional(false);
claimType.setType(CLAIM_TYPE_1);
claimTypeReq.getClaimType().add(claimType);
ClaimType claimType2 = new ClaimType();
claimType2.setOptional(true);
claimType2.setType(CLAIM_TYPE_2);
claimTypeReq.getClaimType().add(claimType2);
protocol.setClaimTypesRequested(claimTypeReq);
CallbackType realm = new CallbackType();
realm.setValue(TARGET_REALM);
protocol.setRealm(realm);
CallbackType issuer = new CallbackType();
issuer.setValue(ISSUER);
protocol.setIssuer(issuer);
return rootConfig;
}
@org.junit.Test
public void testRequiredClaimIncluded() throws Exception {
SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
callbackHandler.setIssuer(ISSUER);
callbackHandler.setSubjectName("alice");
callbackHandler.setAttributeNameFormat(ClaimTypes.URI_BASE.toString());
callbackHandler.setCountryClaimName("country");
callbackHandler.setRoleAttributeName("role");
callbackHandler.setCustomClaimName(CLAIM_TYPE_1);
callbackHandler.setCustomAttributeValues(Collections.singletonList("xyz"));
ConditionsBean cp = new ConditionsBean();
AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
audienceRestriction.getAudienceURIs().add(AUDIENCE_URI_1);
cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
callbackHandler.setConditions(cp);
SAMLCallback samlCallback = new SAMLCallback();
SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
String rstr = createSamlToken(assertion, "mystskey", true);
FedizRequest wfReq = new FedizRequest();
wfReq.setAction(FederationConstants.ACTION_SIGNIN);
wfReq.setResponseToken(rstr);
FedizConfig config = createConfiguration();
StringWriter writer = new StringWriter();
final JAXBContext jaxbContext = JAXBContext.newInstance(FedizConfig.class);
jaxbContext.createMarshaller().marshal(config, writer);
StringReader reader = new StringReader(writer.toString());
FedizConfigurator configurator = new FedizConfigurator();
configurator.loadConfig(reader);
FedizContext context = configurator.getFedizContext(CONFIG_NAME);
FedizProcessor wfProc = new FederationProcessorImpl();
FedizResponse wfRes = wfProc.processRequest(wfReq, context);
Object claimValue = null;
for (Claim c : wfRes.getClaims()) {
if (CLAIM_TYPE_1.equals(c.getClaimType().toString())) {
claimValue = c.getValue();
}
}
Assert.assertEquals("xyz", claimValue);
}
@org.junit.Test
public void testRequiredClaimNotIncluded() throws Exception {
SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
callbackHandler.setIssuer(ISSUER);
callbackHandler.setSubjectName("alice");
callbackHandler.setAttributeNameFormat(ClaimTypes.URI_BASE.toString());
callbackHandler.setCountryClaimName("country");
callbackHandler.setRoleAttributeName("role");
callbackHandler.setCustomClaimName(CLAIM_TYPE_2);
callbackHandler.setCustomAttributeValues(Collections.singletonList("xyz"));
ConditionsBean cp = new ConditionsBean();
AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
audienceRestriction.getAudienceURIs().add(AUDIENCE_URI_1);
cp.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
callbackHandler.setConditions(cp);
SAMLCallback samlCallback = new SAMLCallback();
SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
String rstr = createSamlToken(assertion, "mystskey", true);
FedizRequest wfReq = new FedizRequest();
wfReq.setAction(FederationConstants.ACTION_SIGNIN);
wfReq.setResponseToken(rstr);
FedizConfig config = createConfiguration();
StringWriter writer = new StringWriter();
final JAXBContext jaxbContext = JAXBContext.newInstance(FedizConfig.class);
jaxbContext.createMarshaller().marshal(config, writer);
StringReader reader = new StringReader(writer.toString());
FedizConfigurator configurator = new FedizConfigurator();
configurator.loadConfig(reader);
FedizContext context = configurator.getFedizContext(CONFIG_NAME);
FedizProcessor wfProc = new FederationProcessorImpl();
try {
wfProc.processRequest(wfReq, context);
Assert.fail("Failure expected on a mandatory claim not being included");
} catch (ProcessingException ex) {
// expected
}
}
private String createSamlToken(SamlAssertionWrapper assertion, String alias, boolean sign)
throws IOException, UnsupportedCallbackException, WSSecurityException, Exception {
return createSamlToken(assertion, alias, sign, STSUtil.SAMPLE_RSTR_COLL_MSG);
}
private String createSamlToken(SamlAssertionWrapper assertion, String alias, boolean sign, String rstr)
throws IOException, UnsupportedCallbackException, WSSecurityException, Exception {
WSPasswordCallback[] cb = {
new WSPasswordCallback(alias, WSPasswordCallback.SIGNATURE)
};
cbPasswordHandler.handle(cb);
String password = cb[0].getPassword();
if (sign) {
assertion.signAssertion(alias, password, crypto, false);
}
Document doc = STSUtil.toSOAPPart(rstr);
Element token = assertion.toDOM(doc);
Element e = SAMLTokenValidatorOldTest.findElement(doc, "RequestedSecurityToken",
FederationConstants.WS_TRUST_13_NS);
if (e == null) {
e = SAMLTokenValidatorOldTest.findElement(doc, "RequestedSecurityToken",
FederationConstants.WS_TRUST_2005_02_NS);
}
e.appendChild(token);
return DOM2Writer.nodeToString(doc);
}
}