| <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../.resources/report.css" type="text/css"/><link rel="shortcut icon" href="../.resources/report.gif" type="image/gif"/><title>SAMLTokenValidator.java</title><link rel="stylesheet" href="../.resources/prettify.css" type="text/css"/><script type="text/javascript" src="../.resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="right"><a href="../.sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Coverage Report</a> > <a href="index.html" class="el_package">org.apache.rahas.impl</a> > <span class="el_source">SAMLTokenValidator.java</span></div><h1>SAMLTokenValidator.java</h1><pre class="source lang-java linenums">package org.apache.rahas.impl; |
| |
| import java.security.PublicKey; |
| import java.security.cert.X509Certificate; |
| |
| import javax.xml.namespace.QName; |
| |
| import org.apache.axiom.om.OMElement; |
| import org.apache.axiom.soap.SOAPEnvelope; |
| import org.apache.axis2.context.MessageContext; |
| import org.apache.axis2.description.Parameter; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.rahas.RahasConstants; |
| import org.apache.rahas.RahasData; |
| import org.apache.rahas.Token; |
| import org.apache.rahas.TokenStorage; |
| import org.apache.rahas.TokenValidator; |
| import org.apache.rahas.TrustException; |
| import org.apache.rahas.TrustUtil; |
| import org.apache.rahas.impl.util.CommonUtil; |
| import org.apache.rahas.impl.util.SAMLUtils; |
| import org.apache.ws.security.components.crypto.Crypto; |
| import org.apache.ws.security.components.crypto.CryptoFactory; |
| import org.opensaml.saml1.core.Assertion; |
| import org.opensaml.xml.signature.SignatureValidator; |
| import org.opensaml.xml.validation.ValidationException; |
| import org.w3c.dom.Element; |
| |
| /** |
| * Implementation of a SAML Token Validator for the Security Token Service. |
| */ |
| @SuppressWarnings({"UnusedDeclaration"}) |
| <span class="nc" id="L34">public class SAMLTokenValidator implements TokenValidator {</span> |
| |
| <span class="nc" id="L36"> Log log = LogFactory.getLog(SAMLTokenValidator.class);</span> |
| |
| private String configFile; |
| private OMElement configElement; |
| private String configParamName; |
| |
| /** |
| * Returns a SOAPEnvelope with the result of the validation. |
| * |
| * @param data |
| * the RahasData object, containing information about the |
| * request. |
| */ |
| public SOAPEnvelope validate(RahasData data) throws TrustException { |
| // retrieve the message context |
| <span class="nc" id="L51"> MessageContext inMsgCtx = data.getInMessageContext();</span> |
| |
| // retrieve the list of tokens from the message context |
| <span class="nc" id="L54"> TokenStorage tkStorage = TrustUtil.getTokenStore(inMsgCtx);</span> |
| |
| // Create envelope |
| <span class="nc" id="L57"> SOAPEnvelope env = TrustUtil.createSOAPEnvelope(inMsgCtx</span> |
| .getEnvelope().getNamespace().getNamespaceURI()); |
| |
| // Create RSTR element, with respective version |
| OMElement rstrElem; |
| <span class="nc" id="L62"> int wstVersion = data.getVersion();</span> |
| <span class="nc bnc" id="L63" title="All 2 branches missed."> if (RahasConstants.VERSION_05_02 == wstVersion) {</span> |
| <span class="nc" id="L64"> rstrElem = TrustUtil.createRequestSecurityTokenResponseElement(</span> |
| wstVersion, env.getBody()); |
| } else { |
| <span class="nc" id="L67"> OMElement rstrcElem = TrustUtil</span> |
| .createRequestSecurityTokenResponseCollectionElement( |
| wstVersion, env.getBody()); |
| <span class="nc" id="L70"> rstrElem = TrustUtil.createRequestSecurityTokenResponseElement(</span> |
| wstVersion, rstrcElem); |
| } |
| |
| // Create TokenType element, set to RSTR/Status |
| <span class="nc" id="L75"> TrustUtil.createTokenTypeElement(wstVersion, rstrElem).setText(</span> |
| TrustUtil.getWSTNamespace(wstVersion) |
| + RahasConstants.TOK_TYPE_STATUS); |
| |
| // Create Status element |
| <span class="nc" id="L80"> OMElement statusElement = createMessageElement(wstVersion,</span> |
| rstrElem, RahasConstants.LocalNames.STATUS); |
| |
| // Obtain the token |
| <span class="nc" id="L84"> Token tk = tkStorage.getToken(data.getTokenId());</span> |
| |
| // create the crypto object |
| <span class="nc" id="L87"> PublicKey issuerPBKey = getIssuerPublicKey(inMsgCtx);</span> |
| |
| <span class="nc" id="L89"> boolean valid = isValid(tk, issuerPBKey);</span> |
| String validityCode; |
| |
| <span class="nc bnc" id="L92" title="All 2 branches missed."> if (valid) {</span> |
| <span class="nc" id="L93"> validityCode = RahasConstants.STATUS_CODE_VALID;</span> |
| } else { |
| <span class="nc" id="L95"> validityCode = RahasConstants.STATUS_CODE_INVALID;</span> |
| } |
| |
| // Create Code element (inside Status) and set it to the |
| // correspondent value |
| <span class="nc" id="L100"> createMessageElement(wstVersion, statusElement,</span> |
| RahasConstants.LocalNames.CODE).setText( |
| TrustUtil.getWSTNamespace(wstVersion) + validityCode); |
| |
| <span class="nc" id="L104"> return env;</span> |
| } |
| |
| /** |
| * Checks whether the token is valid or not, by verifying the issuer's own |
| * signature. If it has been signed by the token issuer, then it is a valid |
| * token. |
| * |
| * @param token |
| * the token to validate. |
| * @param issuerPBKey Public key which should be used during validation. |
| * @return true if the token has been signed by the issuer. |
| */ |
| private boolean isValid(Token token, PublicKey issuerPBKey) { |
| // extract SAMLAssertion object from token |
| <span class="nc" id="L119"> OMElement assertionOMElement = token.getToken();</span> |
| Assertion samlAssertion; |
| |
| try { |
| <span class="nc" id="L123"> samlAssertion = SAMLUtils.buildAssertion((Element) assertionOMElement);</span> |
| |
| <span class="nc" id="L125"> log.info("Verifying token validity...");</span> |
| |
| // check if the token has been signed by the issuer. |
| <span class="nc" id="L128"> SignatureValidator validator = new SignatureValidator(samlAssertion.getSignature().getSigningCredential());</span> |
| <span class="nc" id="L129"> validator.validate(samlAssertion.getSignature());</span> |
| |
| <span class="nc" id="L131"> } catch (ValidationException e) {</span> |
| <span class="nc" id="L132"> log.error("Signature verification failed on SAML token.", e);</span> |
| <span class="nc" id="L133"> return false;</span> |
| <span class="nc" id="L134"> }</span> |
| |
| // if there was no exception, then the token is valid |
| <span class="nc" id="L137"> return true;</span> |
| } |
| |
| //here we basically reuse the SAMLTokenIssuer config |
| // to create the crypto object, so we can load the issuer's certificates |
| private PublicKey getIssuerPublicKey(MessageContext inMsgCtx) { |
| <span class="nc" id="L143"> PublicKey issuerPBKey = null;</span> |
| <span class="nc" id="L144"> SAMLTokenIssuerConfig config = null;</span> |
| |
| try { |
| <span class="nc bnc" id="L147" title="All 2 branches missed."> if (configElement != null) {</span> |
| <span class="nc" id="L148"> config = new SAMLTokenIssuerConfig(</span> |
| configElement |
| .getFirstChildWithName(SAMLTokenIssuerConfig.SAML_ISSUER_CONFIG)); |
| } |
| |
| // Look for the file |
| <span class="nc bnc" id="L154" title="All 4 branches missed."> if ((config == null) && (configFile != null)) {</span> |
| <span class="nc" id="L155"> config = new SAMLTokenIssuerConfig(configFile);</span> |
| } |
| |
| // Look for the param |
| <span class="nc bnc" id="L159" title="All 4 branches missed."> if ((config == null) && (configParamName != null)) {</span> |
| <span class="nc" id="L160"> Parameter param = inMsgCtx.getParameter(configParamName);</span> |
| <span class="nc bnc" id="L161" title="All 4 branches missed."> if ((param != null) && (param.getParameterElement() != null)) {</span> |
| <span class="nc" id="L162"> config = new SAMLTokenIssuerConfig(param</span> |
| .getParameterElement().getFirstChildWithName( |
| SAMLTokenIssuerConfig.SAML_ISSUER_CONFIG)); |
| } else { |
| <span class="nc" id="L166"> throw new TrustException("expectedParameterMissing",</span> |
| new String[] { configParamName }); |
| } |
| } |
| |
| <span class="nc bnc" id="L171" title="All 2 branches missed."> if (config == null) {</span> |
| <span class="nc" id="L172"> throw new TrustException("configurationIsNull");</span> |
| } |
| |
| Crypto crypto; |
| <span class="nc bnc" id="L176" title="All 2 branches missed."> if (config.cryptoElement != null) { // crypto props</span> |
| // defined as |
| // elements |
| <span class="nc" id="L179"> crypto = CryptoFactory.getInstance(TrustUtil</span> |
| .toProperties(config.cryptoElement), inMsgCtx |
| .getAxisService().getClassLoader()); |
| } else { // crypto props defined in a properties file |
| <span class="nc" id="L183"> crypto = CryptoFactory.getInstance(config.cryptoPropertiesFile,</span> |
| inMsgCtx.getAxisService().getClassLoader()); |
| } |
| |
| <span class="nc" id="L187"> X509Certificate issuerCert = CommonUtil.getCertificateByAlias(crypto,config.getIssuerKeyAlias());</span> |
| |
| <span class="nc" id="L189"> issuerPBKey = issuerCert.getPublicKey();</span> |
| |
| <span class="nc" id="L191"> } catch (Exception e) {</span> |
| <span class="nc" id="L192"> log.error("Could not retrieve issuer public key", e);</span> |
| <span class="nc" id="L193"> }</span> |
| <span class="nc" id="L194"> return issuerPBKey;</span> |
| } |
| |
| |
| private static OMElement createMessageElement(int version, |
| OMElement parent, String elementName) throws TrustException { |
| <span class="nc" id="L200"> return createOMElement(parent, TrustUtil.getWSTNamespace(version),</span> |
| elementName, RahasConstants.WST_PREFIX); |
| } |
| |
| private static OMElement createOMElement(OMElement parent, String ns, |
| String ln, String prefix) { |
| <span class="nc" id="L206"> return parent.getOMFactory().createOMElement(new QName(ns, ln, prefix),</span> |
| parent); |
| } |
| |
| // ======================================================================== |
| |
| /** |
| * Set the configuration file of this TokenValidator. <p/> This is the text |
| * value of the &lt;configuration-file&gt; element of the |
| * token-dispatcher-configuration |
| * |
| * @param configFile configuration file to be used. |
| */ |
| public void setConfigurationFile(String configFile) { |
| <span class="nc" id="L220"> this.configFile = configFile;</span> |
| <span class="nc" id="L221"> }</span> |
| |
| /** |
| * Set the name of the configuration parameter. <p/> If this is used then |
| * there must be a <code>org.apache.axis2.description.Parameter</code> |
| * object available in the via the messageContext when the |
| * <code>TokenValidator</code> is called. |
| * |
| * @param configParamName Parameter name. |
| * @see org.apache.axis2.description.Parameter |
| */ |
| public void setConfigurationParamName(String configParamName) { |
| <span class="nc" id="L233"> this.configParamName = configParamName;</span> |
| <span class="nc" id="L234"> }</span> |
| |
| public void setConfigurationElement(OMElement configElement) { |
| <span class="nc" id="L237"> this.configElement = configElement;</span> |
| <span class="nc" id="L238"> }</span> |
| |
| } |
| </pre><div class="footer"><span class="right">Created with <a href="http://www.eclemma.org/jacoco">JaCoCo</a> 0.6.1.201212231917</span></div></body></html> |