Author: thilinamb Date: Fri Feb 25 09:14:38 2011 New Revision: 1074447 URL: http://svn.apache.org/viewvc?rev=1074447&view=rev Log: - Fixing some issues related to Bearer subject confirmation method in SAML 1.1. - Adding support for bearer subject confirmation in SAML 2.0. - Adding a new integration test to cover bearer subject confirmation with SAML 2.0 - Improving the existing SAML 1.0 bearer subject confirmation test.
Added: axis/axis2/java/rampart/trunk/modules/rampart-integration/src/test/java/org/apache/rahas/RahasSAML2TokenUTForBearerTest.java Modified: axis/axis2/java/rampart/trunk/modules/rampart-integration/src/test/java/org/apache/rahas/RahasSAMLTokenUTForBearerTest.java axis/axis2/java/rampart/trunk/modules/rampart-trust/src/main/java/org/apache/rahas/impl/SAML2TokenIssuer.java axis/axis2/java/rampart/trunk/modules/rampart-trust/src/main/java/org/apache/rahas/impl/SAMLTokenIssuer.java Added: axis/axis2/java/rampart/trunk/modules/rampart-integration/src/test/java/org/apache/rahas/RahasSAML2TokenUTForBearerTest.java URL: http://svn.apache.org/viewvc/axis/axis2/java/rampart/trunk/modules/rampart-integration/src/test/java/org/apache/rahas/RahasSAML2TokenUTForBearerTest.java?rev=1074447&view=auto ============================================================================== --- axis/axis2/java/rampart/trunk/modules/rampart-integration/src/test/java/org/apache/rahas/RahasSAML2TokenUTForBearerTest.java (added) +++ axis/axis2/java/rampart/trunk/modules/rampart-integration/src/test/java/org/apache/rahas/RahasSAML2TokenUTForBearerTest.java Fri Feb 25 09:14:38 2011 @@ -0,0 +1,174 @@ +/* + * Copyright 2004,2005 The Apache Software Foundation. + * + * Licensed 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.rahas; + +import org.apache.axiom.om.OMAbstractFactory; +import org.apache.axiom.om.OMElement; +import org.apache.axiom.om.OMFactory; +import org.apache.neethi.Policy; +import org.apache.rampart.handler.config.InflowConfiguration; +import org.apache.rampart.handler.config.OutflowConfiguration; +import org.apache.ws.secpolicy.SP11Constants; +import org.opensaml.Configuration; +import org.opensaml.saml2.core.Assertion; +import org.opensaml.saml2.core.Subject; +import org.opensaml.saml2.core.SubjectConfirmation; +import org.opensaml.xml.io.Unmarshaller; +import org.opensaml.xml.io.UnmarshallerFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.ByteArrayInputStream; +import java.util.List; + +/** + * + * @author Ruchith Fernando (ruchith.ferna...@gmail.com) + */ +public class RahasSAML2TokenUTForBearerTest extends TestClient { + + public RahasSAML2TokenUTForBearerTest(String name) { + super(name); + } + + public OMElement getRequest() { + try { + OMElement rstElem = TrustUtil.createRequestSecurityTokenElement(RahasConstants.VERSION_05_02); + TrustUtil.createRequestTypeElement(RahasConstants.VERSION_05_02, rstElem, RahasConstants.REQ_TYPE_ISSUE); + OMElement tokenTypeElem = TrustUtil.createTokenTypeElement(RahasConstants.VERSION_05_02, rstElem); + tokenTypeElem.setText(RahasConstants.TOK_TYPE_SAML_20); + + TrustUtil.createAppliesToElement(rstElem, "http://localhost:5555/axis2/services/SecureService", this.getWSANamespace()); + TrustUtil.createKeyTypeElement(RahasConstants.VERSION_05_02, + rstElem, RahasConstants.KEY_TYPE_BEARER); + TrustUtil.createKeySizeElement(RahasConstants.VERSION_05_02, rstElem, 256); + + return rstElem; + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public OutflowConfiguration getClientOutflowConfiguration() { + OutflowConfiguration ofc = new OutflowConfiguration(); + + ofc.setActionItems("UsernameToken Timestamp"); + ofc.setUser("joe"); + ofc.setPasswordCallbackClass(PWCallback.class.getName()); + return ofc; + } + + public InflowConfiguration getClientInflowConfiguration() { + InflowConfiguration ifc = new InflowConfiguration(); + + ifc.setActionItems("Timestamp"); + + return ifc; + } + + public String getServiceRepo() { + return "rahas_service_repo_3"; + } + + public String getRequestAction() throws TrustException { + return TrustUtil.getActionValue(RahasConstants.VERSION_05_02, RahasConstants.RST_ACTION_ISSUE); + } + + public void validateRsponse(OMElement resp) { + OMElement rst = resp.getFirstChildWithName(new QName(RahasConstants.WST_NS_05_02, + RahasConstants.IssuanceBindingLocalNames. + REQUESTED_SECURITY_TOKEN)); + assertNotNull("RequestedSecurityToken missing", rst); + + OMElement elem = rst.getFirstChildWithName(new QName( + "urn:oasis:names:tc:SAML:2.0:assertion", "Assertion")); + assertNotNull("Missing SAML Assertion", elem); + + Assertion assertion = getAssertionObjectFromOMElement(elem); + Subject subject = assertion.getSubject(); + assertNotNull("SAML Subject of the assertion cannot be null", subject); + + List<SubjectConfirmation> subjectConfirmations = subject.getSubjectConfirmations(); + assertNotNull("At least one Subject Confirmation should be present in the SAML Subject", + subjectConfirmations.get(0)); + assertEquals("Subject Confirmation should be BEARER : urn:oasis:names:tc:SAML:2.0:cm:bearer", + RahasConstants.SAML20_SUBJECT_CONFIRMATION_BEARER, + subjectConfirmations.get(0).getMethod()); + } + + /* (non-Javadoc) + * @see org.apache.rahas.TestClient#getServicePolicy() + */ + public Policy getServicePolicy() throws Exception { + return this.getPolicy("test-resources/rahas/policy/service-policy-transport-binding.xml"); + } + + /* (non-Javadoc) + * @see org.apache.rahas.TestClient#getSTSPolicy() + */ + public Policy getSTSPolicy() throws Exception { + return this.getPolicy("test-resources/rahas/policy/sts-policy-transport-binding.xml"); + } + + /* (non-Javadoc) + * @see org.apache.rahas.TestClient#getRSTTemplate() + */ + public OMElement getRSTTemplate() throws TrustException { + OMFactory factory = OMAbstractFactory.getOMFactory(); + OMElement elem = factory.createOMElement(SP11Constants.REQUEST_SECURITY_TOKEN_TEMPLATE); + + TrustUtil.createTokenTypeElement( + RahasConstants.VERSION_05_02, elem).setText(RahasConstants.TOK_TYPE_SAML_20); + TrustUtil.createKeyTypeElement( + RahasConstants.VERSION_05_02, elem, RahasConstants.KEY_TYPE_BEARER); + + return elem; + } + + public int getTrstVersion() { + return RahasConstants.VERSION_05_02; + } + + /** + * Build the SAML Assertion object from the OMElement for the ease of processing + * @param omElement OMElement containing the SAML Assertion + * @return Assertion object + */ + private Assertion getAssertionObjectFromOMElement(OMElement omElement){ + Assertion assertion = null; + try { + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + documentBuilderFactory.setNamespaceAware(true); + DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder(); + Document document = docBuilder.parse(new ByteArrayInputStream(omElement.toString().getBytes())); + Element element = document.getDocumentElement(); + UnmarshallerFactory unmarshallerFactory = Configuration + .getUnmarshallerFactory(); + Unmarshaller unmarshaller = unmarshallerFactory + .getUnmarshaller(element); + assertion = (org.opensaml.saml2.core.Assertion) unmarshaller + .unmarshall(element); + } catch (Exception e){ + e.printStackTrace(); + } + return assertion; + } +} Modified: axis/axis2/java/rampart/trunk/modules/rampart-integration/src/test/java/org/apache/rahas/RahasSAMLTokenUTForBearerTest.java URL: http://svn.apache.org/viewvc/axis/axis2/java/rampart/trunk/modules/rampart-integration/src/test/java/org/apache/rahas/RahasSAMLTokenUTForBearerTest.java?rev=1074447&r1=1074446&r2=1074447&view=diff ============================================================================== --- axis/axis2/java/rampart/trunk/modules/rampart-integration/src/test/java/org/apache/rahas/RahasSAMLTokenUTForBearerTest.java (original) +++ axis/axis2/java/rampart/trunk/modules/rampart-integration/src/test/java/org/apache/rahas/RahasSAMLTokenUTForBearerTest.java Fri Feb 25 09:14:38 2011 @@ -23,10 +23,22 @@ import org.apache.neethi.Policy; import org.apache.rampart.handler.config.InflowConfiguration; import org.apache.rampart.handler.config.OutflowConfiguration; import org.apache.ws.secpolicy.SP11Constants; -import org.apache.ws.secpolicy.SPConstants; +import org.opensaml.Configuration; import org.opensaml.XML; +import org.opensaml.saml1.core.Assertion; +import org.opensaml.saml1.core.AuthenticationStatement; +import org.opensaml.saml1.core.ConfirmationMethod; +import org.opensaml.saml1.core.SubjectStatement; +import org.opensaml.xml.io.Unmarshaller; +import org.opensaml.xml.io.UnmarshallerFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.ByteArrayInputStream; +import java.util.List; /** * @@ -87,8 +99,23 @@ public class RahasSAMLTokenUTForBearerTe RahasConstants.IssuanceBindingLocalNames. REQUESTED_SECURITY_TOKEN)); assertNotNull("RequestedSecurityToken missing", rst); + OMElement elem = rst.getFirstChildWithName(new QName(XML.SAML_NS, "Assertion")); - assertNotNull("Missing SAML Assertoin", elem); + assertNotNull("Missing SAML Assertion", elem); + + Assertion assertion = getAssertionObjectFromOMElement(elem); + List<AuthenticationStatement> authStmts = assertion.getAuthenticationStatements(); + assertNotNull("At least one Authentication Statement should be present in the assertion", + authStmts.get(0)); + + SubjectStatement authStmt = authStmts.get(0); + List<ConfirmationMethod> subConfirmationMethods = authStmt.getSubject(). + getSubjectConfirmation().getConfirmationMethods(); + assertNotNull("At least one Subject Confirmation method should be present in the SAML Subject", + subConfirmationMethods.get(0)); + assertEquals("Subject Confirmation should be BEARER : urn:oasis:names:tc:SAML:1.0:cm:bearer", + RahasConstants.SAML11_SUBJECT_CONFIRMATION_BEARER, + subConfirmationMethods.get(0).getConfirmationMethod()); } /* (non-Javadoc) @@ -121,4 +148,29 @@ public class RahasSAMLTokenUTForBearerTe public int getTrstVersion() { return RahasConstants.VERSION_05_02; } + + /** + * Build the SAML Assertion object from the OMElement for the ease of processing + * @param omElement OMElement containing the SAML Assertion + * @return Assertion object + */ + private Assertion getAssertionObjectFromOMElement(OMElement omElement){ + Assertion assertion = null; + try { + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + documentBuilderFactory.setNamespaceAware(true); + DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder(); + Document document = docBuilder.parse(new ByteArrayInputStream(omElement.toString().getBytes())); + Element element = document.getDocumentElement(); + UnmarshallerFactory unmarshallerFactory = Configuration + .getUnmarshallerFactory(); + Unmarshaller unmarshaller = unmarshallerFactory + .getUnmarshaller(element); + assertion = (org.opensaml.saml1.core.Assertion) unmarshaller + .unmarshall(element); + } catch (Exception e){ + e.printStackTrace(); + } + return assertion; + } } Modified: axis/axis2/java/rampart/trunk/modules/rampart-trust/src/main/java/org/apache/rahas/impl/SAML2TokenIssuer.java URL: http://svn.apache.org/viewvc/axis/axis2/java/rampart/trunk/modules/rampart-trust/src/main/java/org/apache/rahas/impl/SAML2TokenIssuer.java?rev=1074447&r1=1074446&r2=1074447&view=diff ============================================================================== --- axis/axis2/java/rampart/trunk/modules/rampart-trust/src/main/java/org/apache/rahas/impl/SAML2TokenIssuer.java (original) +++ axis/axis2/java/rampart/trunk/modules/rampart-trust/src/main/java/org/apache/rahas/impl/SAML2TokenIssuer.java Fri Feb 25 09:14:38 2011 @@ -164,7 +164,6 @@ public class SAML2TokenIssuer implements } - // Get the document Document doc = ((Element) env).getOwnerDocument(); @@ -205,7 +204,14 @@ public class SAML2TokenIssuer implements assertion.setConditions(conditions); // Create the subject - Subject subject = createSubject(config, doc, crypto, creationDate, expirationDate, data); + Subject subject; + + if (!data.getKeyType().endsWith(RahasConstants.KEY_TYPE_BEARER)) { + subject = createSubjectWithHolderOfKeySC(config, doc, crypto, creationDate, expirationDate, data); + } + else{ + subject = createSubjectWithBearerSC(data); + } // Set the subject assertion.setSubject(subject); @@ -217,6 +223,9 @@ public class SAML2TokenIssuer implements } else { AuthnStatement authStmt = createAuthnStatement(data); assertion.getAuthnStatements().add(authStmt); + if (data.getClaimDialect() != null && data.getClaimElem() != null) { + assertion.getAttributeStatements().add(createAttributeStatement(data, config)); + } } // Create a SignKeyHolder to hold the crypto objects that are used to sign the assertion @@ -299,7 +308,7 @@ public class SAML2TokenIssuer implements DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder(); Document document = docBuilder.parse(new ByteArrayInputStream(elementString.trim().getBytes())); Element assertionElement = document.getDocumentElement(); - + reqSecTokenElem.addChild((OMNode) ((Element) rstrElem) .getOwnerDocument().importNode(tempNode, true)); @@ -314,11 +323,11 @@ public class SAML2TokenIssuer implements TrustUtil.getTokenStore(inMsgCtx).add(assertionToken); if (keyType.endsWith(RahasConstants.KEY_TYPE_SYMM_KEY) - && config.keyComputation != SAMLTokenIssuerConfig.KeyComputation.KEY_COMP_USE_REQ_ENT) { + && config.keyComputation != SAMLTokenIssuerConfig.KeyComputation.KEY_COMP_USE_REQ_ENT) { // Add the RequestedProofToken TokenIssuerUtil.handleRequestedProofToken(data, wstVersion, - config, rstrElem, assertionToken, doc); + config, rstrElem, assertionToken, doc); } return env; @@ -346,9 +355,10 @@ public class SAML2TokenIssuer implements * @return Subject * @throws Exception */ - private Subject createSubject(SAMLTokenIssuerConfig config, - Document doc, Crypto crypto, DateTime creationTime, - DateTime expirationTime, RahasData data) throws Exception { + private Subject createSubjectWithHolderOfKeySC(SAMLTokenIssuerConfig config, + Document doc, Crypto crypto, + DateTime creationTime, + DateTime expirationTime, RahasData data) throws Exception { XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory(); @@ -422,7 +432,7 @@ public class SAML2TokenIssuer implements } // If it is a public Key - else { + else if(data.getKeyType().endsWith(RahasConstants.KEY_TYPE_PUBLIC_KEY)){ try { String subjectNameId = data.getPrincipal().getName(); @@ -456,15 +466,13 @@ public class SAML2TokenIssuer implements x509CertElem.appendChild(base64CertText); Element x509DataElem = doc.createElementNS(WSConstants.SIG_NS, "ds:X509Data"); - + x509DataElem.appendChild(x509CertElem); + + if (x509DataElem != null) { - x509DataElem.appendChild(x509CertElem); keyInfoElem = doc.createElementNS(WSConstants.SIG_NS, "ds:KeyInfo"); ((OMElement) x509DataElem).declareNamespace( WSConstants.SIG_NS, WSConstants.SIG_PREFIX); - ((OMElement) x509DataElem).declareNamespace( - WSConstants.ENC_NS, WSConstants.ENC_PREFIX); - keyInfoElem.appendChild(x509DataElem); } @@ -522,10 +530,40 @@ public class SAML2TokenIssuer implements //set the subject confirmation subject.getSubjectConfirmations().add(subjectConfirmation); + log.debug("SAML2.0 subject is constructed successfully."); return subject; } + /** + * This method creates a subject element with the bearer subject confirmation method + * @param data RahasData element + * @return SAML 2.0 Subject element with Bearer subject confirmation + */ + private Subject createSubjectWithBearerSC(RahasData data){ + XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory(); + SAMLObjectBuilder<Subject> subjectBuilder = + (SAMLObjectBuilder<Subject>) builderFactory.getBuilder(Subject.DEFAULT_ELEMENT_NAME); + Subject subject = subjectBuilder.buildObject(); + + //Create NameID and attach it to the subject + NameID nameID = new NameIDBuilder().buildObject(); + nameID.setValue(data.getPrincipal().getName()); + nameID.setFormat(NameIdentifier.EMAIL); + subject.setNameID(nameID); + + //Build the Subject Confirmation + SAMLObjectBuilder<SubjectConfirmation> subjectConfirmationBuilder = + (SAMLObjectBuilder<SubjectConfirmation>) builderFactory.getBuilder(SubjectConfirmation.DEFAULT_ELEMENT_NAME); + SubjectConfirmation subjectConfirmation = subjectConfirmationBuilder.buildObject(); + + //Set the subject Confirmation method + subjectConfirmation.setMethod("urn:oasis:names:tc:SAML:2.0:cm:bearer"); + + subject.getSubjectConfirmations().add(subjectConfirmation); + return subject; + } + /** * This method is used to sign the assertion @@ -534,7 +572,7 @@ public class SAML2TokenIssuer implements * @return Assertion * @throws Exception */ - public Assertion setSignature(Assertion assertion, SignKeyHolder cred) throws Exception{ + public Assertion setSignature(Assertion assertion, SignKeyHolder cred) throws Exception { // Build the signature object and set the credentials. Signature signature = (Signature) buildXMLObject(Signature.DEFAULT_ELEMENT_NAME); @@ -552,22 +590,18 @@ public class SAML2TokenIssuer implements data.getX509Certificates().add(cert); keyInfo.getX509Datas().add(data); signature.setKeyInfo(keyInfo); + assertion.setSignature(signature); + signatureList.add(signature); - - - - assertion.setSignature(signature); - signatureList.add(signature); - - //Marshall and Sign - MarshallerFactory marshallerFactory = org.opensaml.xml.Configuration.getMarshallerFactory(); - Marshaller marshaller = marshallerFactory.getMarshaller(assertion); - marshaller.marshall(assertion); - org.apache.xml.security.Init.init(); - Signer.signObjects(signatureList); + //Marshall and Sign + MarshallerFactory marshallerFactory = org.opensaml.xml.Configuration.getMarshallerFactory(); + Marshaller marshaller = marshallerFactory.getMarshaller(assertion); + marshaller.marshall(assertion); + org.apache.xml.security.Init.init(); + Signer.signObjects(signatureList); } catch (CertificateEncodingException e) { throw new TrustException("Error in setting the signature", e); - } catch (SignatureException e) { + } catch (SignatureException e) { throw new TrustException("errorMarshellingOrSigning", e); } catch (MarshallingException e) { throw new TrustException("errorMarshellingOrSigning", e); Modified: axis/axis2/java/rampart/trunk/modules/rampart-trust/src/main/java/org/apache/rahas/impl/SAMLTokenIssuer.java URL: http://svn.apache.org/viewvc/axis/axis2/java/rampart/trunk/modules/rampart-trust/src/main/java/org/apache/rahas/impl/SAMLTokenIssuer.java?rev=1074447&r1=1074446&r2=1074447&view=diff ============================================================================== --- axis/axis2/java/rampart/trunk/modules/rampart-trust/src/main/java/org/apache/rahas/impl/SAMLTokenIssuer.java (original) +++ axis/axis2/java/rampart/trunk/modules/rampart-trust/src/main/java/org/apache/rahas/impl/SAMLTokenIssuer.java Fri Feb 25 09:14:38 2011 @@ -16,13 +16,6 @@ package org.apache.rahas.impl; -import java.security.Principal; -import java.security.SecureRandom; -import java.security.cert.X509Certificate; -import java.text.DateFormat; -import java.util.Arrays; -import java.util.Date; - import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMNode; import org.apache.axiom.om.impl.dom.jaxp.DocumentBuilderFactoryImpl; @@ -62,6 +55,15 @@ import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.Text; +import java.security.Principal; +import java.security.SecureRandom; +import java.security.cert.X509Certificate; +import java.text.DateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + /** * Issuer to issue SAMl tokens */ @@ -251,6 +253,7 @@ public class SAMLTokenIssuer implements Date expirationTime, RahasData data) throws TrustException { try { Principal principal = data.getPrincipal(); + SAMLAssertion assertion; // In the case where the principal is a UT if (principal instanceof WSUsernameTokenPrincipal) { SAMLNameIdentifier nameId = null; @@ -264,10 +267,10 @@ public class SAMLTokenIssuer implements nameId = new SAMLNameIdentifier( principal.getName(), null, SAMLNameIdentifier.FORMAT_EMAIL); } - - return createAuthAssertion(doc, SAMLSubject.CONF_BEARER, + assertion = createAuthAssertion(doc, SAMLSubject.CONF_BEARER, nameId, null, config, crypto, creationTime, - expirationTime); + expirationTime, data); + return assertion; } else { throw new TrustException("samlUnsupportedPrincipal", new String[] { principal.getClass().getName() }); @@ -338,7 +341,7 @@ public class SAMLTokenIssuer implements String subjectNameId = data.getPrincipal().getName(); SAMLNameIdentifier nameId = new SAMLNameIdentifier( - subjectNameId, null, SAMLNameIdentifier.FORMAT_X509); + subjectNameId, null, SAMLNameIdentifier.FORMAT_EMAIL); // Create the ds:KeyValue element with the ds:X509Data X509Certificate clientCert = data.getClientCert(); @@ -363,7 +366,7 @@ public class SAMLTokenIssuer implements return this.createAuthAssertion(doc, SAMLSubject.CONF_HOLDER_KEY, nameId, x509DataElem, - config, crypto, creationTime, expirationTime); + config, crypto, creationTime, expirationTime, data); } catch (Exception e) { throw new TrustException("samlAssertionCreationError", e); } @@ -508,7 +511,7 @@ public class SAMLTokenIssuer implements private SAMLAssertion createAuthAssertion(Document doc, String confMethod, SAMLNameIdentifier subjectNameId, Element keyInfoContent, SAMLTokenIssuerConfig config, Crypto crypto, Date notBefore, - Date notAfter) throws TrustException { + Date notAfter, RahasData data) throws TrustException { try { String[] confirmationMethods = new String[] { confMethod }; @@ -531,10 +534,16 @@ public class SAMLTokenIssuer implements subject, SAMLAuthenticationStatement.AuthenticationMethod_Password, notBefore, null, null, null); - SAMLStatement[] statements = { authStmt }; + + List<SAMLStatement> statements = new ArrayList<SAMLStatement>(); + if (data.getClaimDialect() != null && data.getClaimElem() != null) { + SAMLStatement attrStatement = createSAMLAttributeStatement((SAMLSubject)subject.clone(), data, config); + statements.add(attrStatement); + } + statements.add(authStmt); SAMLAssertion assertion = new SAMLAssertion(config.issuerName, - notBefore, notAfter, null, null, Arrays.asList(statements)); + notBefore, notAfter, null, null, statements); // sign the assertion X509Certificate[] issuerCerts = crypto @@ -602,4 +611,53 @@ public class SAMLTokenIssuer implements this.configParamName = configParamName; } + private SAMLAttributeStatement createSAMLAttributeStatement(SAMLSubject subject, + RahasData rahasData, + SAMLTokenIssuerConfig config) + throws TrustException { + try { + SAMLAttribute[] attrs = null; + if (config.getCallbackHandler() != null) { + SAMLAttributeCallback cb = new SAMLAttributeCallback(rahasData); + SAMLCallbackHandler handler = config.getCallbackHandler(); + handler.handle(cb); + attrs = cb.getAttributes(); + } else if (config.getCallbackHandlerName() != null + && config.getCallbackHandlerName().trim().length() > 0) { + SAMLAttributeCallback cb = new SAMLAttributeCallback(rahasData); + SAMLCallbackHandler handler = null; + MessageContext msgContext = rahasData.getInMessageContext(); + ClassLoader classLoader = msgContext.getAxisService().getClassLoader(); + Class cbClass = null; + try { + cbClass = Loader.loadClass(classLoader, config.getCallbackHandlerName()); + } catch (ClassNotFoundException e) { + throw new TrustException("cannotLoadPWCBClass", + new String[]{config.getCallbackHandlerName()}, e); + } + try { + handler = (SAMLCallbackHandler) cbClass.newInstance(); + } catch (Exception e) { + throw new TrustException("cannotCreatePWCBInstance", + new String[]{config.getCallbackHandlerName()}, e); + } + handler.handle(cb); + attrs = cb.getAttributes(); + } else { + //TODO Remove this after discussing + SAMLAttribute attribute = new SAMLAttribute("Name", + "https://rahas.apache.org/saml/attrns", + null, -1, + Arrays.asList(new String[]{"Colombo/Rahas"})); + attrs = new SAMLAttribute[]{attribute}; + } + + SAMLAttributeStatement attrStmt = new SAMLAttributeStatement( + subject, Arrays.asList(attrs)); + return attrStmt; + } catch (SAMLException e) { + throw new TrustException(e.getMessage(), e); + } + } + }