blob: 5184a885fa625e733ae735aaf123a94533055960 [file] [log] [blame]
package org.apache.rahas.impl;
import java.security.PublicKey;
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;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.description.Parameter;
import org.apache.rahas.RahasConstants;
import org.apache.rahas.RahasData;
import org.apache.rahas.Token;
import org.apache.rahas.TokenRenewer;
import org.apache.rahas.TokenStorage;
import org.apache.rahas.TrustException;
import org.apache.rahas.TrustUtil;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.components.crypto.CryptoFactory;
import org.apache.ws.security.util.XmlSchemaDateFormat;
import org.apache.xml.security.signature.XMLSignature;
import org.opensaml.SAMLAssertion;
import org.opensaml.SAMLException;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public class SAMLTokenRenewer implements TokenRenewer {
private String configParamName;
private OMElement configElement;
private String configFile;
public SOAPEnvelope renew(RahasData data) throws TrustException {
// retrieve the message context
MessageContext inMsgCtx = data.getInMessageContext();
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");
}
// retrieve the list of tokens from the message context
TokenStorage tkStorage = TrustUtil.getTokenStore(inMsgCtx);
try {
// Set the DOM impl to DOOM
DocumentBuilderFactoryImpl.setDOOMRequired(true);
// Create envelope
SOAPEnvelope env = TrustUtil.createSOAPEnvelope(inMsgCtx
.getEnvelope().getNamespace().getNamespaceURI());
// Create RSTR element, with respective version
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);
}
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());
}
// Create TokenType element
TrustUtil.createTokenTypeElement(wstVersion, rstrElem).setText(
RahasConstants.TOK_TYPE_SAML_10);
// Creation and expiration times
Date creationTime = new Date();
Date expirationTime = new Date();
expirationTime.setTime(creationTime.getTime() + config.ttl);
// Use GMT time in milliseconds
DateFormat zulu = new XmlSchemaDateFormat();
// Add the Lifetime element
TrustUtil.createLifetimeElement(wstVersion, rstrElem, zulu
.format(creationTime), zulu.format(expirationTime));
// Obtain the token
Token tk = tkStorage.getToken(data.getTokenId());
OMElement assertionOMElement = tk.getToken();
SAMLAssertion samlAssertion = null;
try {
samlAssertion = new SAMLAssertion((Element) assertionOMElement);
samlAssertion.unsign();
samlAssertion.setNotBefore(creationTime);
samlAssertion.setNotOnOrAfter(expirationTime);
// sign the assertion
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);
samlAssertion.sign(sigAlgo, issuerPK, Arrays.asList(issuerCerts));
// Create the RequestedSecurityToken element and add the SAML token
// to it
OMElement reqSecTokenElem = TrustUtil
.createRequestedSecurityTokenElement(wstVersion, rstrElem);
Node tempNode = samlAssertion.toDOM();
reqSecTokenElem.addChild((OMNode) ((Element) rstrElem)
.getOwnerDocument().importNode(tempNode, true));
} catch (SAMLException e) {
throw new TrustException("Cannot create SAML Assertion",e);
} catch (WSSecurityException e) {
throw new TrustException("Cannot create SAML Assertion",e);
} catch (Exception e) {
throw new TrustException("Cannot create SAML Assertion",e);
}
return env;
} finally {
DocumentBuilderFactoryImpl.setDOOMRequired(false);
}
}
/**
* {@inheritDoc}
*/
public void setConfigurationFile(String configFile) {
this.configFile = configFile;
}
/**
* {@inheritDoc}
*/
public void setConfigurationElement(OMElement configElement) {
this.configElement = configElement;
}
/**
* {@inheritDoc}
*/
public void setConfigurationParamName(String configParamName) {
this.configParamName = configParamName;
}
}