/*
* 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;
}
}