You are viewing a plain text version of this content. The canonical link for it is here.
Posted to rampart-dev@ws.apache.org by na...@apache.org on 2009/09/01 22:31:55 UTC
svn commit: r810217 -
/webservices/rampart/branches/java/1_5/modules/rampart-trust/src/main/java/org/apache/rahas/impl/SAML2TokenIssuer.java
Author: nandana
Date: Tue Sep 1 20:31:54 2009
New Revision: 810217
URL: http://svn.apache.org/viewvc?rev=810217&view=rev
Log:
RAMPART-258 Applying the patch. Thanks Prabath
Modified:
webservices/rampart/branches/java/1_5/modules/rampart-trust/src/main/java/org/apache/rahas/impl/SAML2TokenIssuer.java
Modified: webservices/rampart/branches/java/1_5/modules/rampart-trust/src/main/java/org/apache/rahas/impl/SAML2TokenIssuer.java
URL: http://svn.apache.org/viewvc/webservices/rampart/branches/java/1_5/modules/rampart-trust/src/main/java/org/apache/rahas/impl/SAML2TokenIssuer.java?rev=810217&r1=810216&r2=810217&view=diff
==============================================================================
--- webservices/rampart/branches/java/1_5/modules/rampart-trust/src/main/java/org/apache/rahas/impl/SAML2TokenIssuer.java (original)
+++ webservices/rampart/branches/java/1_5/modules/rampart-trust/src/main/java/org/apache/rahas/impl/SAML2TokenIssuer.java Tue Sep 1 20:31:54 2009
@@ -34,6 +34,7 @@
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.util.Base64;
+import org.apache.ws.security.util.Loader;
import org.apache.ws.security.util.XmlSchemaDateFormat;
import org.apache.xml.security.utils.EncryptionConstants;
import org.apache.xml.security.c14n.Canonicalizer;
@@ -46,18 +47,14 @@
import org.opensaml.xml.*;
import org.opensaml.xml.schema.impl.XSStringBuilder;
import org.opensaml.xml.schema.XSString;
-import org.opensaml.xml.security.x509.X509Credential;
import org.opensaml.xml.signature.*;
import org.opensaml.xml.io.*;
import org.opensaml.common.SAMLVersion;
import org.opensaml.common.SAMLObjectBuilder;
-import org.opensaml.common.xml.SAMLConstants;
import org.opensaml.saml2.core.impl.AssertionBuilder;
import org.opensaml.saml2.core.impl.IssuerBuilder;
import org.opensaml.saml2.core.impl.NameIDBuilder;
-import org.opensaml.saml2.core.impl.SubjectBuilder;
import org.opensaml.saml2.core.*;
-import org.opensaml.saml2.metadata.EntitiesDescriptor;
import org.joda.time.DateTime;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -85,661 +82,672 @@
public class SAML2TokenIssuer implements TokenIssuer {
- private Assertion SAMLAssertion;
+ private Assertion SAMLAssertion;
- private String configParamName;
+ private String configParamName;
- private OMElement configElement;
+ private OMElement configElement;
- private String configFile;
+ private String configFile;
- protected List<Signature> signatureList = new ArrayList<Signature>();
-
- private boolean isSymmetricKeyBasedHoK = false;
-
- private Log log = LogFactory.getLog(SAML2TokenIssuer.class);
-
- public SOAPEnvelope issue(RahasData data) throws TrustException {
- MessageContext inMsgCtx = data.getInMessageContext();
-
- try {
- SAMLTokenIssuerConfig config = null;
- if (this.configElement != null) {
- config = new SAMLTokenIssuerConfig(configElement
- .getFirstChildWithName(SAMLTokenIssuerConfig.SAML_ISSUER_CONFIG));
- }
-
- // Look for the file
- if (config == null && this.configFile != null) {
- config = new SAMLTokenIssuerConfig(this.configFile);
- //config = new SAMLTokenIssuerConfig("/home/thilina/Desktop/saml-issuer-config.xml");
- }
-
- // Look for the param
- if (config == null && this.configParamName != null) {
- Parameter param = inMsgCtx.getParameter(this.configParamName);
- if (param != null && param.getParameterElement() != null) {
- config = new SAMLTokenIssuerConfig(param
- .getParameterElement().getFirstChildWithName(
- SAMLTokenIssuerConfig.SAML_ISSUER_CONFIG));
- } else {
- throw new TrustException("expectedParameterMissing",
- new String[]{this.configParamName});
- }
- }
-
- if (config == null) {
- throw new TrustException("configurationIsNull");
- }
-
- SOAPEnvelope env = TrustUtil.createSOAPEnvelope(inMsgCtx
- .getEnvelope().getNamespace().getNamespaceURI());
-
- Crypto crypto;
- if (config.cryptoElement != null) { // crypto props
- // defined as
- // elements
- crypto = CryptoFactory.getInstance(TrustUtil
- .toProperties(config.cryptoElement), inMsgCtx
- .getAxisService().getClassLoader());
- } else { // crypto props defined in a properties file
- crypto = CryptoFactory.getInstance(config.cryptoPropertiesFile,
- inMsgCtx.getAxisService().getClassLoader());
- }
-
-
-
- // Get the document
- Document doc = ((Element) env).getOwnerDocument();
-
- // Get the key size and create a new byte array of that size
- int keySize = data.getKeysize();
- String keyType = data.getKeyType();
-
- keySize = (keySize == -1) ? config.keySize : keySize;
-
- // Set the "javax.xml.parsers.DocumentBuilderFactory" sys. property to the endorsed JAMP impl.
- String property = System.getProperty("javax.xml.parsers.DocumentBuilderFactory");
- System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
-
-
- //start building SAML 2.0 token
- DefaultBootstrap.bootstrap();
-
- //Build the assertion
- AssertionBuilder assertionBuilder = new AssertionBuilder();
- Assertion assertion = assertionBuilder.buildObject();
- assertion.setVersion(SAMLVersion.VERSION_20);
-
- // Set an UUID as the ID of an assertion
- assertion.setID(UUIDGenerator.getUUID());
-
- //Set the issuer
- IssuerBuilder issuerBuilder = new IssuerBuilder();
- Issuer issuer = issuerBuilder.buildObject();
- issuer.setValue(config.issuerName);
- assertion.setIssuer(issuer);
-
- // Set the issued time.
- assertion.setIssueInstant(new DateTime());
-
- // Validity period
- DateTime creationDate = new DateTime();
- DateTime expirationDate = new DateTime(creationDate.getMillis() + config.ttl);
-
- // These variables are used to build the trust assertion
- Date creationTime = creationDate.toDate();
- Date expirationTime = expirationDate.toDate();
-
- // Create the subject
- Subject subject = createSubject(config, doc, crypto, creationDate, expirationDate, data);
-
- // Set the subject
- assertion.setSubject(subject);
-
- // If a SymmetricKey is used build an attr stmt, if a public key is build an authn stmt.
- if (isSymmetricKeyBasedHoK) {
- AttributeStatement attrStmt = createAttributeStatement(data, config);
- assertion.getAttributeStatements().add(attrStmt);
- } else {
- AuthnStatement authStmt = createAuthnStatement(data);
- assertion.getAuthnStatements().add(authStmt);
- }
-
- // Create a SignKeyHolder to hold the crypto objects that are used to sign the assertion
- SignKeyHolder signKeyHolder = createSignKeyHolder(config, crypto);
-
- // Sign the assertion
- assertion = setSignature(assertion, signKeyHolder);
-
-
- OMElement rstrElem;
- int wstVersion = data.getVersion();
- if (RahasConstants.VERSION_05_02 == wstVersion) {
- rstrElem = TrustUtil.createRequestSecurityTokenResponseElement(
- wstVersion, env.getBody());
- } else {
- OMElement rstrcElem = TrustUtil
- .createRequestSecurityTokenResponseCollectionElement(
- wstVersion, env.getBody());
- rstrElem = TrustUtil.createRequestSecurityTokenResponseElement(
- wstVersion, rstrcElem);
- }
-
- TrustUtil.createTokenTypeElement(wstVersion, rstrElem).setText(
- RahasConstants.TOK_TYPE_SAML_20);
-
- if (keyType.endsWith(RahasConstants.KEY_TYPE_SYMM_KEY)) {
- TrustUtil.createKeySizeElement(wstVersion, rstrElem, keySize);
- }
-
- if (config.addRequestedAttachedRef) {
- TrustUtil.createRequestedAttachedRef(wstVersion, rstrElem, "#"
- + assertion.getID(), RahasConstants.TOK_TYPE_SAML_20);
- }
-
- if (config.addRequestedUnattachedRef) {
- TrustUtil.createRequestedUnattachedRef(wstVersion, rstrElem,
- assertion.getID(), RahasConstants.TOK_TYPE_SAML_20);
- }
-
- if (data.getAppliesToAddress() != null) {
- TrustUtil.createAppliesToElement(rstrElem, data
- .getAppliesToAddress(), data.getAddressingNs());
- }
-
- // Use GMT time in milliseconds
- DateFormat zulu = new XmlSchemaDateFormat();
-
- // Add the Lifetime element
- TrustUtil.createLifetimeElement(wstVersion, rstrElem, zulu
- .format(creationTime), zulu.format(expirationTime));
-
- // Create the RequestedSecurityToken element and add the SAML token
- // to it
- OMElement reqSecTokenElem = TrustUtil
- .createRequestedSecurityTokenElement(wstVersion, rstrElem);
- Token assertionToken;
-
- Node tempNode = assertion.getDOM();
-
- //Serializing and re-generating the AXIOM element using the DOM Element created using xerces
- Element element = assertion.getDOM();
-
- ByteArrayOutputStream byteArrayOutputStrm = new ByteArrayOutputStream();
-
- DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
-
- DOMImplementationLS impl =
- (DOMImplementationLS) registry.getDOMImplementation("LS");
-
- LSSerializer writer = impl.createLSSerializer();
- LSOutput output = impl.createLSOutput();
- output.setByteStream(byteArrayOutputStrm);
- writer.write(element, output);
- String elementString = byteArrayOutputStrm.toString();
-
- DocumentBuilderFactoryImpl.setDOOMRequired(true);
-
- DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
- documentBuilderFactory.setNamespaceAware(true);
- 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));
-
- // Store the token
- assertionToken = new Token(assertion.getID(),
- (OMElement) assertionElement, creationTime,
- expirationTime);
-
- // At this point we definitely have the secret
- // Otherwise it should fail with an exception earlier
- assertionToken.setSecret(data.getEphmeralKey());
- TrustUtil.getTokenStore(inMsgCtx).add(assertionToken);
-
- if (keyType.endsWith(RahasConstants.KEY_TYPE_SYMM_KEY)
- && config.keyComputation != SAMLTokenIssuerConfig.KeyComputation.KEY_COMP_USE_REQ_ENT) {
-
- // Add the RequestedProofToken
- TokenIssuerUtil.handleRequestedProofToken(data, wstVersion,
- config, rstrElem, assertionToken, doc);
- }
-
- return env;
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- finally {
- // Unset the DOM impl to default
- DocumentBuilderFactoryImpl.setDOOMRequired(false);
- }
-
-
- return null;
- }
-
- /**
- * This method is used to create the subject of an assertion
- * @param config
- * @param doc
- * @param crypto
- * @param creationTime
- * @param expirationTime
- * @param data
- * @return Subject
- * @throws Exception
- */
- private Subject createSubject(SAMLTokenIssuerConfig config,
- Document doc, Crypto crypto, DateTime creationTime,
- DateTime expirationTime, RahasData data) throws Exception {
-
-
- XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
- SAMLObjectBuilder<Subject> subjectBuilder =
- (SAMLObjectBuilder<Subject>) builderFactory.getBuilder(Subject.DEFAULT_ELEMENT_NAME);
- Subject subject = subjectBuilder.buildObject();
- Element keyInfoElem = null;
-
- // If it is a Symmetric Key
- if (data.getKeyType().endsWith(RahasConstants.KEY_TYPE_SYMM_KEY)) {
-
- isSymmetricKeyBasedHoK = true;
- Element encryptedKeyElem;
- X509Certificate serviceCert = null;
- try {
-
- // Get ApliesTo to figure out which service to issue the token
- // for
- serviceCert = config.getServiceCert(crypto, data.getAppliesToAddress());
-
- // Create the encrypted key
- WSSecEncryptedKey encrKeyBuilder = new WSSecEncryptedKey();
-
- // Use thumbprint id
- encrKeyBuilder
- .setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);
-
- // SEt the encryption cert
- encrKeyBuilder.setUseThisCert(serviceCert);
-
- // set keysize
- int keysize = data.getKeysize();
- keysize = (keysize != -1) ? keysize : config.keySize;
- encrKeyBuilder.setKeySize(keysize);
-
- encrKeyBuilder.setEphemeralKey(TokenIssuerUtil.getSharedSecret(
- data, config.keyComputation, keysize));
-
- // Set key encryption algo
- encrKeyBuilder
- .setKeyEncAlgo(EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15);
-
- // Build
- encrKeyBuilder.prepare(doc, crypto);
-
- // Extract the base64 encoded secret value
- byte[] tempKey = new byte[keysize / 8];
- System.arraycopy(encrKeyBuilder.getEphemeralKey(), 0, tempKey,
- 0, keysize / 8);
-
- data.setEphmeralKey(tempKey);
-
- // Extract the Encryptedkey DOM element
- encryptedKeyElem = encrKeyBuilder.getEncryptedKeyElement();
- } catch (WSSecurityException e) {
- throw new TrustException(
- "errorInBuildingTheEncryptedKeyForPrincipal",
- new String[]{serviceCert.getSubjectDN().getName()},
- e);
- }
-
- keyInfoElem = doc.createElementNS(WSConstants.SIG_NS,
- "ds:KeyInfo");
- ((OMElement) encryptedKeyElem).declareNamespace(WSConstants.SIG_NS,
- WSConstants.SIG_PREFIX);
- ((OMElement) encryptedKeyElem).declareNamespace(WSConstants.ENC_NS,
- WSConstants.ENC_PREFIX);
-
- keyInfoElem.appendChild(encryptedKeyElem);
-
- }
-
- // If it is a public Key
- else {
- try {
- String subjectNameId = data.getPrincipal().getName();
-
- //Create NameID and attach it to the subject
- NameIDBuilder nb = new NameIDBuilder();
- NameID nameID = nb.buildObject();
- nameID.setValue(subjectNameId);
- nameID.setFormat(NameIdentifier.EMAIL);
- subject.setNameID(nameID);
-
-
- // Create the ds:KeyValue element with the ds:X509Data
- X509Certificate clientCert = data.getClientCert();
-
- if (clientCert == null) {
- X509Certificate[] certs = crypto.getCertificates(
- data.getPrincipal().getName());
- clientCert = certs[0];
- }
-
- byte[] clientCertBytes = clientCert.getEncoded();
-
- String base64Cert = Base64.encode(clientCertBytes);
-
- Text base64CertText = doc.createTextNode(base64Cert);
-
- //-----------------------------------------
-
- Element x509CertElem = doc.createElementNS(WSConstants.SIG_NS,
- "ds:X509Certificate");
- x509CertElem.appendChild(base64CertText);
- Element x509DataElem = doc.createElementNS(WSConstants.SIG_NS,
- "ds:X509Data");
- x509DataElem.appendChild(x509CertElem);
-
-
- if (x509DataElem != null) {
- 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);
- }
-
- } catch (Exception e) {
- throw new TrustException("samlAssertionCreationError", e);
- }
- }
-
- // Unmarshall the keyInfo DOM element into an XMLObject
- String keyInfoElementString = keyInfoElem.toString();
- DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
- documentBuilderFactory.setNamespaceAware(true);
- DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();
- Document document = docBuilder.parse(new ByteArrayInputStream(keyInfoElementString.trim().getBytes()));
- Element element = document.getDocumentElement();
-
-
- // Get appropriate unmarshaller
- UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
- Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(element);
-
- // Unmarshall using the document root element, an keyInfo element in this case
- XMLObject keyInfoElement = null;
- try {
- keyInfoElement = unmarshaller.unmarshall(element);
- } catch (UnmarshallingException e) {
- throw new TrustException("Error unmarshalling KeyInfo Element", e);
- }
-
-
- //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:holder-of-key");
-
- SAMLObjectBuilder<KeyInfoConfirmationDataType> keyInfoSubjectConfirmationDataBuilder =
- (SAMLObjectBuilder<KeyInfoConfirmationDataType>) builderFactory.getBuilder(KeyInfoConfirmationDataType.TYPE_NAME);
-
- //Build the subject confirmation data element
- KeyInfoConfirmationDataType scData = keyInfoSubjectConfirmationDataBuilder.
- buildObject(SubjectConfirmationData.DEFAULT_ELEMENT_NAME, KeyInfoConfirmationDataType.TYPE_NAME);
-
- //Set the keyInfo element
- scData.getKeyInfos().add(keyInfoElement);
-
- // Set the validity period
- scData.setNotBefore(creationTime);
- scData.setNotOnOrAfter(expirationTime);
-
- //Set the subject confirmation data
- subjectConfirmation.setSubjectConfirmationData(scData);
-
- //set the subject confirmation
- subject.getSubjectConfirmations().add(subjectConfirmation);
-
- if(log.isDebugEnabled()){
- log.debug("SAML2.0 subject is constructed successfully.");
- }
- return subject;
- }
-
-
- /**
- * This method is used to sign the assertion
- * @param assertion
- * @param cred
- * @return Assertion
- * @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);
- signature.setSigningCredential(cred);
- signature.setSignatureAlgorithm(cred.getSignatureAlgorithm());
- signature.setCanonicalizationAlgorithm(Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
-
- //Build the KeyInfo element and set the certificate
- try {
- KeyInfo keyInfo = (KeyInfo) buildXMLObject(KeyInfo.DEFAULT_ELEMENT_NAME);
- X509Data data = (X509Data) buildXMLObject(X509Data.DEFAULT_ELEMENT_NAME);
- org.opensaml.xml.signature.X509Certificate cert = (org.opensaml.xml.signature.X509Certificate) buildXMLObject(org.opensaml.xml.signature.X509Certificate.DEFAULT_ELEMENT_NAME);
- String value = org.apache.xml.security.utils.Base64.encode(cred.getEntityCertificate().getEncoded());
- cert.setValue(value);
- data.getX509Certificates().add(cert);
- keyInfo.getX509Datas().add(data);
- signature.setKeyInfo(keyInfo);
-
-
-
-
- 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);
- } catch (CertificateEncodingException e) {
- throw new TrustException("Error in setting the signature", e);
- } catch (SignatureException e) {
- throw new TrustException("errorMarshellingOrSigning", e);
- } catch (MarshallingException e) {
- throw new TrustException("errorMarshellingOrSigning", e);
- }
-
- if(log.isDebugEnabled()){
- log.debug("SAML2.0 assertion is marshalled and signed..");
- }
-
- return assertion;
- }
-
-
- /**
- * This method is used to build the assertion elements
- * @param objectQName
- * @return
- * @throws Exception
- */
- protected static XMLObject buildXMLObject(QName objectQName) throws Exception {
- XMLObjectBuilder builder = org.opensaml.xml.Configuration.getBuilderFactory().getBuilder(objectQName);
- if (builder == null) {
- throw new TrustException("Unable to retrieve builder for object QName "
- + objectQName);
- }
- return builder.buildObject(objectQName.getNamespaceURI(), objectQName.getLocalPart(),
- objectQName.getPrefix());
- }
-
- /**
- * This method is used to create SignKeyHolder instances that contains the credentials required for signing the
- * assertion
- * @param config
- * @param crypto
- * @return
- * @throws TrustException
- */
- public SignKeyHolder createSignKeyHolder(SAMLTokenIssuerConfig config, Crypto crypto) throws TrustException {
-
- SignKeyHolder signKeyHolder = new SignKeyHolder();
-
- try {
- X509Certificate[] issuerCerts = crypto
- .getCertificates(config.issuerKeyAlias);
-
- String sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_RSA;
- String pubKeyAlgo = issuerCerts[0].getPublicKey().getAlgorithm();
- if (pubKeyAlgo.equalsIgnoreCase("DSA")) {
- sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_DSA;
- }
- java.security.Key issuerPK = crypto.getPrivateKey(
- config.issuerKeyAlias, config.issuerKeyPassword);
-
- signKeyHolder.setIssuerCerts(issuerCerts);
- signKeyHolder.setIssuerPK((PrivateKey) issuerPK);
- signKeyHolder.setSignatureAlgorithm(sigAlgo);
-
- } catch (Exception e) {
- throw new TrustException("Error creating issuer signature");
- }
-
- if(log.isDebugEnabled()){
- log.debug("SignKeyHolder object is created with the credentials..");
- }
-
- return signKeyHolder;
- }
-
- /**
- * Creates the Attribute Statement
- * @param data
- * @param config
- * @return
- * @throws SAMLException
- */
- public AttributeStatement createAttributeStatement(RahasData data, SAMLTokenIssuerConfig config) throws SAMLException {
-
- XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
- SAMLObjectBuilder<AttributeStatement> attrStmtBuilder =
- (SAMLObjectBuilder<AttributeStatement>) builderFactory.getBuilder(AttributeStatement.DEFAULT_ELEMENT_NAME);
-
- AttributeStatement attrstmt = attrStmtBuilder.buildObject();
-
- Attribute[] attributes = null;
-
- //Call the attribute callback handlers to get any attributes if exists
- if (config.getCallbackHander() != null) {
- SAMLAttributeCallback cb = new SAMLAttributeCallback(data);
- SAMLCallbackHandler handler = config.getCallbackHander();
- handler.handle(cb);
- attributes = cb.getSAML2Attributes();
- }
-
- //else add the attribute with a default value
- else {
- SAMLObjectBuilder<Attribute> attrBuilder =
- (SAMLObjectBuilder<Attribute>) builderFactory.getBuilder(Attribute.DEFAULT_ELEMENT_NAME);
- Attribute attribute = attrBuilder.buildObject();
- attribute.setName("Name");
- attribute.setNameFormat("urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified");
-
- XSStringBuilder attributeValueBuilder = (XSStringBuilder) builderFactory
- .getBuilder(XSString.TYPE_NAME);
-
- XSString stringValue = attributeValueBuilder.buildObject(
- AttributeValue.DEFAULT_ELEMENT_NAME, XSString.TYPE_NAME);
- stringValue.setValue("Colombo/Rahas");
- attribute.getAttributeValues().add(stringValue);
- attributes = new Attribute[1];
- attributes[0] = attribute;
- }
- //add attributes to the attribute statement
- attrstmt.getAttributes().addAll(Arrays.asList(attributes));
-
- if(log.isDebugEnabled()){
- log.debug("SAML2.0 attribute statement is constructed successfully.");
- }
-
- return attrstmt;
- }
-
- /**
- * build the authentication statement
- * @param data
- * @return
- */
- public AuthnStatement createAuthnStatement(RahasData data) {
- XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
- MessageContext inMsgCtx = data.getInMessageContext();
-
- SAMLObjectBuilder<AuthnStatement> authStmtBuilder =
- (SAMLObjectBuilder<AuthnStatement>) builderFactory.getBuilder(AuthnStatement.DEFAULT_ELEMENT_NAME);
-
- //build the auth stmt
- AuthnStatement authStmt = authStmtBuilder.buildObject();
-
- // set the authn instance
- authStmt.setAuthnInstant(new DateTime());
-
- SAMLObjectBuilder<AuthnContext> authCtxBuilder =
- (SAMLObjectBuilder<AuthnContext>) builderFactory.getBuilder(AuthnContext.DEFAULT_ELEMENT_NAME);
- AuthnContext authContext = authCtxBuilder.buildObject();
-
- SAMLObjectBuilder<AuthnContextClassRef> authCtxClassRefBuilder =
- (SAMLObjectBuilder<AuthnContextClassRef>) builderFactory.getBuilder(AuthnContextClassRef.DEFAULT_ELEMENT_NAME);
- AuthnContextClassRef authCtxClassRef = authCtxClassRefBuilder.buildObject();
-
- //if username/password based authn
- if (inMsgCtx.getProperty(RahasConstants.USERNAME) != null) {
- authCtxClassRef.setAuthnContextClassRef(AuthnContext.PASSWORD_AUTHN_CTX);
- }
- //if X.509 cert based authn
- else if (inMsgCtx.getProperty(RahasConstants.X509_CERT) != null) {
- authCtxClassRef.setAuthnContextClassRef(AuthnContext.X509_AUTHN_CTX);
- }
-
- authContext.setAuthnContextClassRef(authCtxClassRef);
- authStmt.setAuthnContext(authContext);
-
- if(log.isDebugEnabled()){
- log.debug("SAML2.0 authentication statement is constructed successfully.");
- }
-
- return authStmt;
- }
-
-
- public String getResponseAction(RahasData data) throws TrustException {
- return null;
- }
-
- public void setConfigurationFile(String configFile) {
- this.configFile = configFile;
- }
-
- public void setConfigurationElement(OMElement configElement) {
- this.configElement = configElement;
- }
-
- public void setConfigurationParamName(String configParamName) {
- this.configParamName = configParamName;
- }
+ protected List<Signature> signatureList = new ArrayList<Signature>();
+
+ private boolean isSymmetricKeyBasedHoK = false;
+
+ private static Log log = LogFactory.getLog(SAML2TokenIssuer.class);
+
+ static {
+ try {
+ // Set the "javax.xml.parsers.DocumentBuilderFactory" system property
+ // to the endorsed JAXP impl.
+ System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
+ "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
+ DefaultBootstrap.bootstrap();
+ } catch (ConfigurationException e) {
+ log.error("SAML2TokenIssuerBootstrapError", e);
+ throw new RuntimeException(e);
+ } finally {
+ // Unset the DOM impl to default
+ DocumentBuilderFactoryImpl.setDOOMRequired(false);
+ }
+ }
+
+ public SOAPEnvelope issue(RahasData data) throws TrustException {
+ MessageContext inMsgCtx = data.getInMessageContext();
+
+ try {
+ SAMLTokenIssuerConfig config = null;
+ if (this.configElement != null) {
+ config = new SAMLTokenIssuerConfig(configElement
+ .getFirstChildWithName(SAMLTokenIssuerConfig.SAML_ISSUER_CONFIG));
+ }
+
+ // Look for the file
+ if (config == null && this.configFile != null) {
+ config = new SAMLTokenIssuerConfig(this.configFile);
+ }
+
+ // Look for the param
+ if (config == null && this.configParamName != null) {
+ Parameter param = inMsgCtx.getParameter(this.configParamName);
+ if (param != null && param.getParameterElement() != null) {
+ config = new SAMLTokenIssuerConfig(param.getParameterElement()
+ .getFirstChildWithName(SAMLTokenIssuerConfig.SAML_ISSUER_CONFIG));
+ } else {
+ throw new TrustException("expectedParameterMissing",
+ new String[]{this.configParamName});
+ }
+ }
+
+ if (config == null) {
+ throw new TrustException("configurationIsNull");
+ }
+
+ SOAPEnvelope env = TrustUtil.createSOAPEnvelope(inMsgCtx.getEnvelope().getNamespace()
+ .getNamespaceURI());
+
+ Crypto crypto;
+ if (config.cryptoElement != null) { // crypto props
+ // defined as
+ // elements
+ crypto = CryptoFactory.getInstance(TrustUtil.toProperties(config.cryptoElement),
+ inMsgCtx.getAxisService().getClassLoader());
+ } else { // crypto props defined in a properties file
+ crypto = CryptoFactory.getInstance(config.cryptoPropertiesFile, inMsgCtx
+ .getAxisService().getClassLoader());
+ }
+
+ // Get the document
+ Document doc = ((Element) env).getOwnerDocument();
+
+ // Get the key size and create a new byte array of that size
+ int keySize = data.getKeysize();
+ String keyType = data.getKeyType();
+
+ keySize = (keySize == -1) ? config.keySize : keySize;
+
+ // Build the assertion
+ AssertionBuilder assertionBuilder = new AssertionBuilder();
+ Assertion assertion = assertionBuilder.buildObject();
+ assertion.setVersion(SAMLVersion.VERSION_20);
+
+ // Set an UUID as the ID of an assertion
+ assertion.setID(UUIDGenerator.getUUID());
+
+ // Set the issuer
+ IssuerBuilder issuerBuilder = new IssuerBuilder();
+ Issuer issuer = issuerBuilder.buildObject();
+ issuer.setValue(config.issuerName);
+ assertion.setIssuer(issuer);
+
+ // Set the issued time.
+ assertion.setIssueInstant(new DateTime());
+
+ // Validity period
+ DateTime creationDate = new DateTime();
+ DateTime expirationDate = new DateTime(creationDate.getMillis() + config.ttl);
+
+ // These variables are used to build the trust assertion
+ Date creationTime = creationDate.toDate();
+ Date expirationTime = expirationDate.toDate();
+
+ // Create the subject
+ Subject subject = createSubject(config, doc, crypto, creationDate, expirationDate, data);
+
+ // Set the subject
+ assertion.setSubject(subject);
+
+ // If a SymmetricKey is used build an attr stmt, if a public key is build an authn stmt.
+ if (isSymmetricKeyBasedHoK) {
+ AttributeStatement attrStmt = createAttributeStatement(data, config);
+ assertion.getAttributeStatements().add(attrStmt);
+ } else {
+ AuthnStatement authStmt = createAuthnStatement(data);
+ assertion.getAuthnStatements().add(authStmt);
+ }
+
+ // Create a SignKeyHolder to hold the crypto objects that are used to sign the assertion
+ SignKeyHolder signKeyHolder = createSignKeyHolder(config, crypto);
+
+ // Sign the assertion
+ assertion = setSignature(assertion, signKeyHolder);
+
+ OMElement rstrElem;
+ int wstVersion = data.getVersion();
+ if (RahasConstants.VERSION_05_02 == wstVersion) {
+ rstrElem = TrustUtil.createRequestSecurityTokenResponseElement(wstVersion, env
+ .getBody());
+ } else {
+ OMElement rstrcElem = TrustUtil
+ .createRequestSecurityTokenResponseCollectionElement(wstVersion, env
+ .getBody());
+ rstrElem = TrustUtil.createRequestSecurityTokenResponseElement(wstVersion,
+ rstrcElem);
+ }
+
+ TrustUtil.createTokenTypeElement(wstVersion, rstrElem).setText(
+ RahasConstants.TOK_TYPE_SAML_20);
+
+ if (keyType.endsWith(RahasConstants.KEY_TYPE_SYMM_KEY)) {
+ TrustUtil.createKeySizeElement(wstVersion, rstrElem, keySize);
+ }
+
+ if (config.addRequestedAttachedRef) {
+ TrustUtil.createRequestedAttachedRef(wstVersion, rstrElem, "#" + assertion.getID(),
+ RahasConstants.TOK_TYPE_SAML_20);
+ }
+
+ if (config.addRequestedUnattachedRef) {
+ TrustUtil.createRequestedUnattachedRef(wstVersion, rstrElem, assertion.getID(),
+ RahasConstants.TOK_TYPE_SAML_20);
+ }
+
+ if (data.getAppliesToAddress() != null) {
+ TrustUtil.createAppliesToElement(rstrElem, data.getAppliesToAddress(), data
+ .getAddressingNs());
+ }
+
+ // Use GMT time in milliseconds
+ DateFormat zulu = new XmlSchemaDateFormat();
+
+ // Add the Lifetime element
+ TrustUtil.createLifetimeElement(wstVersion, rstrElem, zulu.format(creationTime), zulu
+ .format(expirationTime));
+
+ // Create the RequestedSecurityToken element and add the SAML token
+ // to it
+ OMElement reqSecTokenElem = TrustUtil.createRequestedSecurityTokenElement(wstVersion,
+ rstrElem);
+ Token assertionToken;
+
+ Node tempNode = assertion.getDOM();
+
+ // Serializing and re-generating the AXIOM element using the DOM Element created using
+ // xerces
+ Element element = assertion.getDOM();
+
+ ByteArrayOutputStream byteArrayOutputStrm = new ByteArrayOutputStream();
+
+ DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
+
+ DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS");
+
+ LSSerializer writer = impl.createLSSerializer();
+ LSOutput output = impl.createLSOutput();
+ output.setByteStream(byteArrayOutputStrm);
+ writer.write(element, output);
+ String elementString = byteArrayOutputStrm.toString();
+
+ DocumentBuilderFactoryImpl.setDOOMRequired(true);
+
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ documentBuilderFactory.setNamespaceAware(true);
+ 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));
+
+ // Store the token
+ assertionToken = new Token(assertion.getID(), (OMElement) assertionElement,
+ creationTime, expirationTime);
+
+ // At this point we definitely have the secret
+ // Otherwise it should fail with an exception earlier
+ assertionToken.setSecret(data.getEphmeralKey());
+ TrustUtil.getTokenStore(inMsgCtx).add(assertionToken);
+
+ if (keyType.endsWith(RahasConstants.KEY_TYPE_SYMM_KEY)
+ && config.keyComputation != SAMLTokenIssuerConfig.KeyComputation.KEY_COMP_USE_REQ_ENT) {
+
+ // Add the RequestedProofToken
+ TokenIssuerUtil.handleRequestedProofToken(data, wstVersion, config, rstrElem,
+ assertionToken, doc);
+ }
+
+ return env;
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ // Unset the DOM impl to default
+ DocumentBuilderFactoryImpl.setDOOMRequired(false);
+ }
+
+ return null;
+ }
+
+ /**
+ * This method is used to create the subject of an assertion
+ *
+ * @param config
+ * @param doc
+ * @param crypto
+ * @param creationTime
+ * @param expirationTime
+ * @param data
+ * @return Subject
+ * @throws Exception
+ */
+ private Subject createSubject(SAMLTokenIssuerConfig config, Document doc, Crypto crypto,
+ DateTime creationTime, DateTime expirationTime, RahasData data) throws Exception {
+
+ XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
+ SAMLObjectBuilder<Subject> subjectBuilder = (SAMLObjectBuilder<Subject>) builderFactory
+ .getBuilder(Subject.DEFAULT_ELEMENT_NAME);
+ Subject subject = subjectBuilder.buildObject();
+ Element keyInfoElem = null;
+
+ // If it is a Symmetric Key
+ if (data.getKeyType().endsWith(RahasConstants.KEY_TYPE_SYMM_KEY)) {
+
+ isSymmetricKeyBasedHoK = true;
+ Element encryptedKeyElem;
+ X509Certificate serviceCert = null;
+ try {
+
+ // Get ApliesTo to figure out which service to issue the token
+ // for
+ serviceCert = config.getServiceCert(crypto, data.getAppliesToAddress());
+
+ // Create the encrypted key
+ WSSecEncryptedKey encrKeyBuilder = new WSSecEncryptedKey();
+
+ // Use thumbprint id
+ encrKeyBuilder.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);
+
+ // SEt the encryption cert
+ encrKeyBuilder.setUseThisCert(serviceCert);
+
+ // set keysize
+ int keysize = data.getKeysize();
+ keysize = (keysize != -1) ? keysize : config.keySize;
+ encrKeyBuilder.setKeySize(keysize);
+
+ encrKeyBuilder.setEphemeralKey(TokenIssuerUtil.getSharedSecret(data,
+ config.keyComputation, keysize));
+
+ // Set key encryption algo
+ encrKeyBuilder.setKeyEncAlgo(EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15);
+
+ // Build
+ encrKeyBuilder.prepare(doc, crypto);
+
+ // Extract the base64 encoded secret value
+ byte[] tempKey = new byte[keysize / 8];
+ System.arraycopy(encrKeyBuilder.getEphemeralKey(), 0, tempKey, 0, keysize / 8);
+
+ data.setEphmeralKey(tempKey);
+
+ // Extract the Encryptedkey DOM element
+ encryptedKeyElem = encrKeyBuilder.getEncryptedKeyElement();
+ } catch (WSSecurityException e) {
+ throw new TrustException("errorInBuildingTheEncryptedKeyForPrincipal",
+ new String[]{serviceCert.getSubjectDN().getName()}, e);
+ }
+
+ keyInfoElem = doc.createElementNS(WSConstants.SIG_NS, "ds:KeyInfo");
+ ((OMElement) encryptedKeyElem).declareNamespace(WSConstants.SIG_NS,
+ WSConstants.SIG_PREFIX);
+ ((OMElement) encryptedKeyElem).declareNamespace(WSConstants.ENC_NS,
+ WSConstants.ENC_PREFIX);
+
+ keyInfoElem.appendChild(encryptedKeyElem);
+
+ }
+
+ // If it is a public Key
+ else {
+ try {
+ String subjectNameId = data.getPrincipal().getName();
+
+ // Create NameID and attach it to the subject
+ NameIDBuilder nb = new NameIDBuilder();
+ NameID nameID = nb.buildObject();
+ nameID.setValue(subjectNameId);
+ nameID.setFormat(NameIdentifier.EMAIL);
+ subject.setNameID(nameID);
+
+ // Create the ds:KeyValue element with the ds:X509Data
+ X509Certificate clientCert = data.getClientCert();
+
+ if (clientCert == null) {
+ X509Certificate[] certs = crypto.getCertificates(data.getPrincipal().getName());
+ clientCert = certs[0];
+ }
+
+ byte[] clientCertBytes = clientCert.getEncoded();
+
+ String base64Cert = Base64.encode(clientCertBytes);
+
+ Text base64CertText = doc.createTextNode(base64Cert);
+
+ // -----------------------------------------
+
+ Element x509CertElem = doc
+ .createElementNS(WSConstants.SIG_NS, "ds:X509Certificate");
+ x509CertElem.appendChild(base64CertText);
+ Element x509DataElem = doc.createElementNS(WSConstants.SIG_NS, "ds:X509Data");
+ x509DataElem.appendChild(x509CertElem);
+
+ if (x509DataElem != null) {
+ 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);
+ }
+
+ } catch (Exception e) {
+ throw new TrustException("samlAssertionCreationError", e);
+ }
+ }
+
+ // Unmarshall the keyInfo DOM element into an XMLObject
+ String keyInfoElementString = keyInfoElem.toString();
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ documentBuilderFactory.setNamespaceAware(true);
+ DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();
+ Document document = docBuilder.parse(new ByteArrayInputStream(keyInfoElementString.trim()
+ .getBytes()));
+ Element element = document.getDocumentElement();
+
+ // Get appropriate unmarshaller
+ UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
+ Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(element);
+
+ // Unmarshall using the document root element, an keyInfo element in this case
+ XMLObject keyInfoElement = null;
+ try {
+ keyInfoElement = unmarshaller.unmarshall(element);
+ } catch (UnmarshallingException e) {
+ throw new TrustException("Error unmarshalling KeyInfo Element", e);
+ }
+
+ // 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:holder-of-key");
+
+ SAMLObjectBuilder<KeyInfoConfirmationDataType> keyInfoSubjectConfirmationDataBuilder = (SAMLObjectBuilder<KeyInfoConfirmationDataType>) builderFactory
+ .getBuilder(KeyInfoConfirmationDataType.TYPE_NAME);
+
+ // Build the subject confirmation data element
+ KeyInfoConfirmationDataType scData = keyInfoSubjectConfirmationDataBuilder
+ .buildObject(SubjectConfirmationData.DEFAULT_ELEMENT_NAME,
+ KeyInfoConfirmationDataType.TYPE_NAME);
+
+ // Set the keyInfo element
+ scData.getKeyInfos().add(keyInfoElement);
+
+ // Set the validity period
+ scData.setNotBefore(creationTime);
+ scData.setNotOnOrAfter(expirationTime);
+
+ // Set the subject confirmation data
+ subjectConfirmation.setSubjectConfirmationData(scData);
+
+ // set the subject confirmation
+ subject.getSubjectConfirmations().add(subjectConfirmation);
+
+ if (log.isDebugEnabled()) {
+ log.debug("SAML2.0 subject is constructed successfully.");
+ }
+ return subject;
+ }
+
+ /**
+ * This method is used to sign the assertion
+ *
+ * @param assertion
+ * @param cred
+ * @return Assertion
+ * @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);
+ signature.setSigningCredential(cred);
+ signature.setSignatureAlgorithm(cred.getSignatureAlgorithm());
+ signature.setCanonicalizationAlgorithm(Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
+
+ // Build the KeyInfo element and set the certificate
+ try {
+ KeyInfo keyInfo = (KeyInfo) buildXMLObject(KeyInfo.DEFAULT_ELEMENT_NAME);
+ X509Data data = (X509Data) buildXMLObject(X509Data.DEFAULT_ELEMENT_NAME);
+ org.opensaml.xml.signature.X509Certificate cert = (org.opensaml.xml.signature.X509Certificate) buildXMLObject(org.opensaml.xml.signature.X509Certificate.DEFAULT_ELEMENT_NAME);
+ String value = org.apache.xml.security.utils.Base64.encode(cred.getEntityCertificate()
+ .getEncoded());
+ cert.setValue(value);
+ data.getX509Certificates().add(cert);
+ keyInfo.getX509Datas().add(data);
+ signature.setKeyInfo(keyInfo);
+
+ 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);
+ } catch (CertificateEncodingException e) {
+ throw new TrustException("Error in setting the signature", e);
+ } catch (SignatureException e) {
+ throw new TrustException("errorMarshellingOrSigning", e);
+ } catch (MarshallingException e) {
+ throw new TrustException("errorMarshellingOrSigning", e);
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("SAML2.0 assertion is marshalled and signed..");
+ }
+
+ return assertion;
+ }
+
+ /**
+ * This method is used to build the assertion elements
+ *
+ * @param objectQName
+ * @return
+ * @throws Exception
+ */
+ protected static XMLObject buildXMLObject(QName objectQName) throws Exception {
+ XMLObjectBuilder builder = org.opensaml.xml.Configuration.getBuilderFactory().getBuilder(
+ objectQName);
+ if (builder == null) {
+ throw new TrustException("Unable to retrieve builder for object QName " + objectQName);
+ }
+ return builder.buildObject(objectQName.getNamespaceURI(), objectQName.getLocalPart(),
+ objectQName.getPrefix());
+ }
+
+ /**
+ * This method is used to create SignKeyHolder instances that contains the credentials required
+ * for signing the assertion
+ *
+ * @param config
+ * @param crypto
+ * @return
+ * @throws TrustException
+ */
+ private SignKeyHolder createSignKeyHolder(SAMLTokenIssuerConfig config, Crypto crypto)
+ throws TrustException {
+
+ SignKeyHolder signKeyHolder = new SignKeyHolder();
+
+ try {
+ X509Certificate[] issuerCerts = crypto.getCertificates(config.issuerKeyAlias);
+
+ String sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_RSA;
+ String pubKeyAlgo = issuerCerts[0].getPublicKey().getAlgorithm();
+ if (pubKeyAlgo.equalsIgnoreCase("DSA")) {
+ sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_DSA;
+ }
+ java.security.Key issuerPK = crypto.getPrivateKey(config.issuerKeyAlias,
+ config.issuerKeyPassword);
+
+ signKeyHolder.setIssuerCerts(issuerCerts);
+ signKeyHolder.setIssuerPK((PrivateKey) issuerPK);
+ signKeyHolder.setSignatureAlgorithm(sigAlgo);
+
+ } catch (Exception e) {
+ throw new TrustException("Error creating issuer signature");
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("SignKeyHolder object is created with the credentials..");
+ }
+
+ return signKeyHolder;
+ }
+
+ /**
+ * Creates the Attribute Statement
+ *
+ * @param data
+ * @param config
+ * @return
+ * @throws SAMLException
+ * @throws TrustException
+ */
+ private AttributeStatement createAttributeStatement(RahasData data, SAMLTokenIssuerConfig config)
+ throws SAMLException, TrustException {
+
+ XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
+ SAMLObjectBuilder<AttributeStatement> attrStmtBuilder = (SAMLObjectBuilder<AttributeStatement>) builderFactory
+ .getBuilder(AttributeStatement.DEFAULT_ELEMENT_NAME);
+
+ AttributeStatement attrstmt = attrStmtBuilder.buildObject();
+
+ Attribute[] attributes = null;
+
+ // Call the attribute callback handlers to get any attributes if exists
+ if (config.getCallbackHander() != null) {
+ SAMLAttributeCallback cb = new SAMLAttributeCallback(data);
+ SAMLCallbackHandler handler = config.getCallbackHander();
+ handler.handle(cb);
+ attributes = cb.getSAML2Attributes();
+ } else if (config.getCallbackHandlerName() != null
+ && config.getCallbackHandlerName().trim().length() > 0) {
+ SAMLAttributeCallback cb = new SAMLAttributeCallback(data);
+ SAMLCallbackHandler handler = null;
+ MessageContext msgContext = data.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 (java.lang.Exception e) {
+ throw new TrustException("cannotCreatePWCBInstance", new String[]{config
+ .getCallbackHandlerName()}, e);
+ }
+ handler.handle(cb);
+ attributes = cb.getSAML2Attributes();
+ // else add the attribute with a default value
+ } else {
+ SAMLObjectBuilder<Attribute> attrBuilder = (SAMLObjectBuilder<Attribute>) builderFactory
+ .getBuilder(Attribute.DEFAULT_ELEMENT_NAME);
+ Attribute attribute = attrBuilder.buildObject();
+ attribute.setName("Name");
+ attribute.setNameFormat("urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified");
+
+ XSStringBuilder attributeValueBuilder = (XSStringBuilder) builderFactory
+ .getBuilder(XSString.TYPE_NAME);
+
+ XSString stringValue = attributeValueBuilder.buildObject(
+ AttributeValue.DEFAULT_ELEMENT_NAME, XSString.TYPE_NAME);
+ stringValue.setValue("Colombo/Rahas");
+ attribute.getAttributeValues().add(stringValue);
+ attributes = new Attribute[1];
+ attributes[0] = attribute;
+ }
+ // add attributes to the attribute statement
+ attrstmt.getAttributes().addAll(Arrays.asList(attributes));
+
+ if (log.isDebugEnabled()) {
+ log.debug("SAML2.0 attribute statement is constructed successfully.");
+ }
+
+ return attrstmt;
+ }
+
+ /**
+ * build the authentication statement
+ *
+ * @param data
+ * @return
+ */
+ private AuthnStatement createAuthnStatement(RahasData data) {
+ XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
+ MessageContext inMsgCtx = data.getInMessageContext();
+
+ SAMLObjectBuilder<AuthnStatement> authStmtBuilder = (SAMLObjectBuilder<AuthnStatement>) builderFactory
+ .getBuilder(AuthnStatement.DEFAULT_ELEMENT_NAME);
+
+ // build the auth stmt
+ AuthnStatement authStmt = authStmtBuilder.buildObject();
+
+ // set the authn instance
+ authStmt.setAuthnInstant(new DateTime());
+
+ SAMLObjectBuilder<AuthnContext> authCtxBuilder = (SAMLObjectBuilder<AuthnContext>) builderFactory
+ .getBuilder(AuthnContext.DEFAULT_ELEMENT_NAME);
+ AuthnContext authContext = authCtxBuilder.buildObject();
+
+ SAMLObjectBuilder<AuthnContextClassRef> authCtxClassRefBuilder = (SAMLObjectBuilder<AuthnContextClassRef>) builderFactory
+ .getBuilder(AuthnContextClassRef.DEFAULT_ELEMENT_NAME);
+ AuthnContextClassRef authCtxClassRef = authCtxClassRefBuilder.buildObject();
+
+ // if username/password based authn
+ if (inMsgCtx.getProperty(RahasConstants.USERNAME) != null) {
+ authCtxClassRef.setAuthnContextClassRef(AuthnContext.PASSWORD_AUTHN_CTX);
+ }
+ // if X.509 cert based authn
+ else if (inMsgCtx.getProperty(RahasConstants.X509_CERT) != null) {
+ authCtxClassRef.setAuthnContextClassRef(AuthnContext.X509_AUTHN_CTX);
+ }
+
+ authContext.setAuthnContextClassRef(authCtxClassRef);
+ authStmt.setAuthnContext(authContext);
+
+ if (log.isDebugEnabled()) {
+ log.debug("SAML2.0 authentication statement is constructed successfully.");
+ }
+
+ return authStmt;
+ }
+
+ public String getResponseAction(RahasData data) throws TrustException {
+ return null;
+ }
+
+ public void setConfigurationFile(String configFile) {
+ this.configFile = configFile;
+ }
+
+ public void setConfigurationElement(OMElement configElement) {
+ this.configElement = configElement;
+ }
+
+ public void setConfigurationParamName(String configParamName) {
+ this.configParamName = configParamName;
+ }
}