/* * Copyright 2005-2014 WSO2, Inc. (http://wso2.com) * * 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.wso2.carbon.identity.tools.saml.validator.processors; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.opensaml.common.SAMLVersion; import org.opensaml.saml2.core.AuthnRequest; import org.opensaml.saml2.core.Issuer; import org.opensaml.saml2.core.RequestAbstractType; import org.opensaml.saml2.core.Subject; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.identity.base.IdentityConstants; import org.wso2.carbon.identity.base.IdentityException; import org.wso2.carbon.identity.core.model.SAMLSSOServiceProviderDO; import org.wso2.carbon.identity.core.util.IdentityUtil; import org.wso2.carbon.identity.sso.saml.SAMLSSOConstants; import org.wso2.carbon.identity.sso.saml.util.SAMLSSOUtil; import org.wso2.carbon.identity.tools.saml.validator.dto.ValidatedItemDTO; import org.wso2.carbon.identity.tools.saml.validator.util.SAMLValidatorConstants; import org.wso2.carbon.identity.tools.saml.validator.util.SAMLValidatorUtil; import java.util.List; public class SAMLAuthnRequestValidator { private static Log log = LogFactory.getLog(SAMLAuthnRequestValidator.class); private AuthnRequest authnRequest; private boolean isPost = false; private String queryString = null; private String issuerStr = null; public SAMLAuthnRequestValidator(AuthnRequest authnRequest) { this.setAuthnRequest(authnRequest); } /** * Validate SP initiated SAML AuthnRequest * * @param validatedItems * @throws IdentityException */ public void validate(List<ValidatedItemDTO> validatedItems) throws IdentityException { // Validate version - version must be SAML 2.0 if (authnRequest.getVersion().equals(SAMLVersion.VERSION_20)) { validatedItems.add(new ValidatedItemDTO( SAMLValidatorConstants.ValidationType.VAL_VERSION, true, SAMLValidatorConstants.ValidationMessage.VAL_VERSION_SUCCESS)); } else { validatedItems.add(new ValidatedItemDTO( SAMLValidatorConstants.ValidationType.VAL_VERSION, false, String.format(SAMLValidatorConstants.ValidationMessage.VAL_VERSION_FAIL, authnRequest.getVersion()))); throw IdentityException.error(SAMLValidatorConstants.ValidationMessage.EXIT_WITH_ERROR); } Issuer issuer = authnRequest.getIssuer(); Subject subject = authnRequest.getSubject(); // Validate Issuer/ProviderName - at least one should not be null if (issuer.getValue() == null && issuer.getSPProvidedID() == null) { validatedItems.add(new ValidatedItemDTO( SAMLValidatorConstants.ValidationType.VAL_ISSUER, false, SAMLValidatorConstants.ValidationMessage.VAL_ISSUER_FAIL)); throw IdentityException.error(SAMLValidatorConstants.ValidationMessage.EXIT_WITH_ERROR); } else { issuerStr = issuer.getValue() != null ? issuer.getValue() : issuer.getSPProvidedID(); validatedItems.add(new ValidatedItemDTO( SAMLValidatorConstants.ValidationType.VAL_ISSUER, true, SAMLValidatorConstants.ValidationMessage.VAL_ISSUER_SUCCESS)); } if (issuer.getFormat() != null) { if (issuer.getFormat().equals(SAMLValidatorConstants.Attribute.ISSUER_FORMAT)) { validatedItems.add(new ValidatedItemDTO( SAMLValidatorConstants.ValidationType.VAL_ISSUER_FORMAT, true, SAMLValidatorConstants.ValidationMessage.VAL_ISSUER_FMT_SUCCESS)); } else { validatedItems.add(new ValidatedItemDTO( SAMLValidatorConstants.ValidationType.VAL_ISSUER_FORMAT, false, SAMLValidatorConstants.ValidationMessage.VAL_ISSUER_FMT_FAIL)); throw IdentityException.error( SAMLValidatorConstants.ValidationMessage.EXIT_WITH_ERROR); } } // Load SSO IdP configuration for issuer SAMLSSOServiceProviderDO ssoIdPConfigs = null; try { ssoIdPConfigs = SAMLValidatorUtil.getServiceProviderConfig(issuer.getValue()); } catch (IdentityException e) { log.error(e.getMessage()); validatedItems.add(new ValidatedItemDTO( SAMLValidatorConstants.ValidationType.VAL_IDP_CONFIGS, false, String.format(SAMLValidatorConstants.ValidationMessage.VAL_IDP_CONFIGS_FAIL, authnRequest.getIssuer() .getValue()))); throw IdentityException.error(SAMLValidatorConstants.ValidationMessage.EXIT_WITH_ERROR); } if (ssoIdPConfigs == null) { validatedItems.add(new ValidatedItemDTO( SAMLValidatorConstants.ValidationType.VAL_IDP_CONFIGS, false, String.format(SAMLValidatorConstants.ValidationMessage.VAL_IDP_CONFIGS_FAIL, authnRequest.getIssuer() .getValue()))); throw IdentityException.error(SAMLValidatorConstants.ValidationMessage.EXIT_WITH_ERROR); } else { validatedItems.add(new ValidatedItemDTO( SAMLValidatorConstants.ValidationType.VAL_IDP_CONFIGS, true, String.format(SAMLValidatorConstants.ValidationMessage.VAL_IDP_CONFIGS_SUCCESS, authnRequest.getIssuer() .getValue()))); } // Validating Assertion Consumer URL String consumerServiceURL = authnRequest.getAssertionConsumerServiceURL(); if (consumerServiceURL != null && ssoIdPConfigs.getAssertionConsumerUrl().equals(consumerServiceURL)) { validatedItems.add(new ValidatedItemDTO( SAMLValidatorConstants.ValidationType.VAL_CONSUM_URL, true, String.format(SAMLValidatorConstants.ValidationMessage.VAL_CONSUM_URL_SUCCESS, consumerServiceURL))); } else { validatedItems.add(new ValidatedItemDTO( SAMLValidatorConstants.ValidationType.VAL_CONSUM_URL, false, String.format(SAMLValidatorConstants.ValidationMessage.VAL_CONSUM_URL_FAIL, consumerServiceURL, ssoIdPConfigs.getAssertionConsumerUrl()))); throw IdentityException.error(SAMLValidatorConstants.ValidationMessage.EXIT_WITH_ERROR); } // Validating SubjectID format if (subject != null && subject.getNameID() != null && subject.getNameID().getFormat() != null && ssoIdPConfigs.getNameIDFormat() != null && subject.getNameID().getFormat().equals(ssoIdPConfigs.getNameIDFormat())) { validatedItems.add(new ValidatedItemDTO( SAMLValidatorConstants.ValidationType.VAL_SUB_NAMEID_FMT, true, SAMLValidatorConstants.ValidationMessage.VAL_SUB_NAMEID_SUCCESS)); } // Subject Confirmation methods should NOT be available if (subject != null && subject.getSubjectConfirmations() != null) { validatedItems.add(new ValidatedItemDTO( SAMLValidatorConstants.ValidationType.VAL_SUB_CONF_MTHD, false, SAMLValidatorConstants.ValidationMessage.VAL_SUB_CONF_MTHD_FAIL)); } if (ssoIdPConfigs.isDoValidateSignatureInRequests()) { // Validate Destination String idPUrl = IdentityUtil.getProperty(IdentityConstants.ServerConfig.SSO_IDP_URL); if(StringUtils.isBlank(idPUrl)) { idPUrl = IdentityUtil.getServerURL(SAMLSSOConstants.SAMLSSO_URL, true, true); } if (authnRequest.getDestination() != null && idPUrl.equals(authnRequest.getDestination())) { validatedItems.add(new ValidatedItemDTO( SAMLValidatorConstants.ValidationType.VAL_DESTINATION, true, String.format(SAMLValidatorConstants.ValidationMessage.VAL_DESTINATION_SUCCESS, authnRequest.getDestination()))); } else { validatedItems.add(new ValidatedItemDTO( SAMLValidatorConstants.ValidationType.VAL_DESTINATION, false, String.format(SAMLValidatorConstants.ValidationMessage.VAL_DESTINATION_FAIL, authnRequest.getDestination(), idPUrl))); throw IdentityException.error( SAMLValidatorConstants.ValidationMessage.EXIT_WITH_ERROR); } // Validate Signature String alias = ssoIdPConfigs.getCertAlias(); String domainName = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); try { boolean isValid = false; if (isPost) { isValid = SAMLSSOUtil.validateXMLSignature((RequestAbstractType) authnRequest, alias, domainName); } else { isValid = SAMLSSOUtil.validateDeflateSignature(queryString, issuerStr, alias, domainName); } if (isValid) { validatedItems.add(new ValidatedItemDTO( SAMLValidatorConstants.ValidationType.VAL_SIGNATURE, true, SAMLValidatorConstants.ValidationMessage.VAL_SIGNATURE_SUCCESS)); } else { validatedItems.add(new ValidatedItemDTO( SAMLValidatorConstants.ValidationType.VAL_SIGNATURE, false, SAMLValidatorConstants.ValidationMessage.VAL_SIGNATURE_FAIL)); } } catch (IdentityException e) { validatedItems.add(new ValidatedItemDTO( SAMLValidatorConstants.ValidationType.VAL_SIGNATURE, false, String.format(SAMLValidatorConstants.ValidationMessage.VAL_SIGNATURE_ERROR, e.getMessage()))); throw IdentityException.error( SAMLValidatorConstants.ValidationMessage.EXIT_WITH_ERROR); } } } public AuthnRequest getAuthnRequest() { return authnRequest; } public void setAuthnRequest(AuthnRequest authnRequest) { this.authnRequest = authnRequest; } public void setPost(boolean isPost) { this.isPost = isPost; } public void setQueryString(String queryString) { this.queryString = queryString; } }