Commit 5992fd07 authored by michael.simon's avatar michael.simon
Browse files

AttributeQuery gets signature validated

parent 0dc27060
......@@ -11,6 +11,7 @@
package edu.kit.scc.webreg.service.saml;
import org.opensaml.common.SignableSAMLObject;
import org.opensaml.saml2.core.AttributeQuery;
import org.opensaml.saml2.core.Issuer;
import org.opensaml.saml2.core.Response;
import org.opensaml.saml2.metadata.EntityDescriptor;
......@@ -20,7 +21,7 @@ import edu.kit.scc.webreg.exc.SamlAuthenticationException;
public interface Saml2ResponseValidationService {
public void verifyIssuer(SamlMetadataEntity idpEntity, Response samlResponse)
public void verifyIssuer(SamlMetadataEntity metadataEntity, Response samlResponse)
throws SamlAuthenticationException;
void verifyExpiration(Response samlResponse, Long expiryMillis)
......@@ -28,7 +29,18 @@ public interface Saml2ResponseValidationService {
void verifyStatus(Response samlResponse) throws SamlAuthenticationException;
void validateSignature(SignableSAMLObject assertion,
Issuer issuer, EntityDescriptor idpEntityDescriptor) throws SamlAuthenticationException;
void verifyIssuer(SamlMetadataEntity metadataEntity,
AttributeQuery attributeQuery) throws SamlAuthenticationException;
void verifyIssuer(SamlMetadataEntity metadataEntity, Issuer issuer)
throws SamlAuthenticationException;
void validateIdpSignature(SignableSAMLObject signableSamlObject,
Issuer issuer, EntityDescriptor entityDescriptor)
throws SamlAuthenticationException;
void validateSpSignature(SignableSAMLObject signableSamlObject,
Issuer issuer, EntityDescriptor entityDescriptor)
throws SamlAuthenticationException;
}
......@@ -80,7 +80,7 @@ public class Saml2AssertionServiceImpl implements Saml2AssertionService {
if (checkSignature) {
try {
logger.debug("Validating SamlResponse Signature for " + samlResponse.getID());
saml2ValidationService.validateSignature(samlResponse, samlResponse.getIssuer(), idpEntityDescriptor);
saml2ValidationService.validateIdpSignature(samlResponse, samlResponse.getIssuer(), idpEntityDescriptor);
logger.debug("Validating SamlResponse Signature success for " + samlResponse.getID());
responseSignatureValid = true;
} catch (SamlAuthenticationException e) {
......@@ -114,7 +114,7 @@ public class Saml2AssertionServiceImpl implements Saml2AssertionService {
if (checkSignature) {
if (! responseSignatureValid) {
logger.debug("Validating Assertion Signature for " + assertion.getID());
saml2ValidationService.validateSignature(assertion, assertion.getIssuer(), idpEntityDescriptor);
saml2ValidationService.validateIdpSignature(assertion, assertion.getIssuer(), idpEntityDescriptor);
logger.debug("Validating Assertion Signature success for " + assertion.getID());
}
else {
......
......@@ -11,18 +11,21 @@
package edu.kit.scc.webreg.service.saml.impl;
import javax.inject.Inject;
import javax.xml.namespace.QName;
import org.joda.time.Duration;
import org.joda.time.Instant;
import org.opensaml.Configuration;
import org.opensaml.common.SignableSAMLObject;
import org.opensaml.common.xml.SAMLConstants;
import org.opensaml.saml2.core.AttributeQuery;
import org.opensaml.saml2.core.Issuer;
import org.opensaml.saml2.core.Response;
import org.opensaml.saml2.core.Status;
import org.opensaml.saml2.core.StatusCode;
import org.opensaml.saml2.metadata.EntityDescriptor;
import org.opensaml.saml2.metadata.IDPSSODescriptor;
import org.opensaml.saml2.metadata.SPSSODescriptor;
import org.opensaml.saml2.metadata.provider.DOMMetadataProvider;
import org.opensaml.saml2.metadata.provider.MetadataProviderException;
import org.opensaml.security.MetadataCredentialResolver;
......@@ -49,18 +52,28 @@ public class Saml2ResponseValidationServiceImpl implements
private Logger logger;
@Override
public void verifyIssuer(SamlMetadataEntity idpEntity,
public void verifyIssuer(SamlMetadataEntity metadataEntity,
Response samlResponse) throws SamlAuthenticationException {
verifyIssuer(metadataEntity, samlResponse.getIssuer());
}
@Override
public void verifyIssuer(SamlMetadataEntity metadataEntity,
AttributeQuery attributeQuery) throws SamlAuthenticationException {
verifyIssuer(metadataEntity, attributeQuery.getIssuer());
}
@Override
public void verifyIssuer(SamlMetadataEntity metadataEntity,
Issuer issuer) throws SamlAuthenticationException {
Issuer issuer = samlResponse.getIssuer();
if (issuer == null)
throw new SamlAuthenticationException("Response issuer is not set");
String issuerString = issuer.getValue();
if (! issuerString.equals(idpEntity.getEntityId()))
if (! issuerString.equals(metadataEntity.getEntityId()))
throw new SamlAuthenticationException("Response issuer " + issuerString +
" differs from excpected " + idpEntity.getEntityId());
" differs from excpected " + metadataEntity.getEntityId());
}
......@@ -83,17 +96,33 @@ public class Saml2ResponseValidationServiceImpl implements
}
@Override
public void validateSignature(SignableSAMLObject sigObj, Issuer issuer, EntityDescriptor idpEntityDescriptor)
public void validateIdpSignature(SignableSAMLObject signableSamlObject, Issuer issuer, EntityDescriptor entityDescriptor)
throws SamlAuthenticationException {
validateSignature(signableSamlObject, issuer, entityDescriptor,
IDPSSODescriptor.DEFAULT_ELEMENT_NAME, SAMLConstants.SAML20P_NS);
}
@Override
public void validateSpSignature(SignableSAMLObject signableSamlObject, Issuer issuer, EntityDescriptor entityDescriptor)
throws SamlAuthenticationException {
validateSignature(signableSamlObject, issuer, entityDescriptor,
SPSSODescriptor.DEFAULT_ELEMENT_NAME, SAMLConstants.SAML20P_NS);
}
protected void validateSignature(SignableSAMLObject signableSamlObject, Issuer issuer, EntityDescriptor entityDescriptor,
QName role, String protocol)
throws SamlAuthenticationException {
if (sigObj.getSignature() == null)
if (signableSamlObject.getSignature() == null)
throw new SamlAuthenticationException("No Signature on SignableSamlObject");
DOMMetadataProvider mp = new DOMMetadataProvider(idpEntityDescriptor.getDOM());
DOMMetadataProvider mp = new DOMMetadataProvider(entityDescriptor.getDOM());
try {
mp.initialize();
} catch (MetadataProviderException e) {
throw new SamlAuthenticationException("Metadata for IDP " + idpEntityDescriptor.getEntityID() + " could not be established");
throw new SamlAuthenticationException("Metadata for IDP " + entityDescriptor.getEntityID() + " could not be established");
}
MetadataCredentialResolver mdCredResolver = new MetadataCredentialResolver(mp);
......@@ -103,19 +132,19 @@ public class Saml2ResponseValidationServiceImpl implements
SAMLSignatureProfileValidator sigValidator = new SAMLSignatureProfileValidator();
try {
sigValidator.validate(sigObj.getSignature());
sigValidator.validate(signableSamlObject.getSignature());
} catch (ValidationException e) {
throw new SamlAuthenticationException("SAMLSignableObject signature is not valid");
}
CriteriaSet criteriaSet = new CriteriaSet();
criteriaSet.add(new EntityIDCriteria(issuer.getValue()));
criteriaSet.add(new MetadataCriteria(IDPSSODescriptor.DEFAULT_ELEMENT_NAME, SAMLConstants.SAML20P_NS));
criteriaSet.add(new MetadataCriteria(role, protocol));
criteriaSet.add(new UsageCriteria(UsageType.SIGNING));
try {
if (trustEngine.validate(sigObj.getSignature(), criteriaSet))
logger.info("Signutare validation success for " + idpEntityDescriptor.getEntityID());
if (trustEngine.validate(signableSamlObject.getSignature(), criteriaSet))
logger.info("Signutare validation success for " + entityDescriptor.getEntityID());
else {
throw new SamlAuthenticationException("SAMLSignableObject could not be validated.");
}
......
......@@ -59,9 +59,9 @@ public class AttributeQueryBean implements Serializable {
@Inject
private SamlSpConfigurationService spService;
private String spEntityId;
private String idpEntityId;
private String persistentId;
private String spEntityId = "https://bwidm-test.scc.kit.edu/sp";
private String idpEntityId = "https://bwidm.scc.kit.edu/attribute-authority";
private String persistentId = "ls1947@kit.edu";
private Map<String, List<Object>> attributeMap;
......
......@@ -274,7 +274,7 @@ public class EcpController {
try {
logger.debug("Validating Signature for " + assertion.getID());
saml2ResponseValidationService.validateSignature(assertion, assertion.getIssuer(), idpEntityDesc);
saml2ResponseValidationService.validateIdpSignature(assertion, assertion.getIssuer(), idpEntityDesc);
logger.debug("Validating Signature success for " + assertion.getID());
} catch (SamlAuthenticationException e) {
logger.info("Could not validate signature for user {}", user.getEppn());
......
......@@ -11,10 +11,6 @@
package edu.kit.scc.webreg.sec;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Named;
......@@ -28,8 +24,8 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.opensaml.Configuration;
import org.opensaml.saml2.core.Assertion;
import org.opensaml.saml2.core.AttributeQuery;
import org.opensaml.saml2.core.Issuer;
import org.opensaml.saml2.core.Response;
import org.opensaml.saml2.core.Status;
import org.opensaml.saml2.core.StatusCode;
......@@ -38,25 +34,18 @@ import org.opensaml.ws.message.decoder.MessageDecodingException;
import org.opensaml.ws.soap.soap11.Body;
import org.opensaml.ws.soap.soap11.Envelope;
import org.opensaml.xml.XMLObjectBuilderFactory;
import org.opensaml.xml.encryption.DecryptionException;
import org.opensaml.xml.security.SecurityException;
import org.slf4j.Logger;
import edu.kit.scc.webreg.bootstrap.ApplicationConfig;
import edu.kit.scc.webreg.drools.KnowledgeSessionService;
import edu.kit.scc.webreg.entity.SamlIdpMetadataEntity;
import edu.kit.scc.webreg.entity.SamlSpConfigurationEntity;
import edu.kit.scc.webreg.entity.UserEntity;
import edu.kit.scc.webreg.exc.RegisterException;
import edu.kit.scc.webreg.entity.SamlSpMetadataEntity;
import edu.kit.scc.webreg.exc.SamlAuthenticationException;
import edu.kit.scc.webreg.service.SamlIdpMetadataService;
import edu.kit.scc.webreg.service.SamlSpConfigurationService;
import edu.kit.scc.webreg.service.UserService;
import edu.kit.scc.webreg.service.UserUpdateService;
import edu.kit.scc.webreg.service.saml.Saml2AssertionService;
import edu.kit.scc.webreg.service.SamlSpMetadataService;
import edu.kit.scc.webreg.service.saml.Saml2DecoderService;
import edu.kit.scc.webreg.service.saml.Saml2ResponseValidationService;
import edu.kit.scc.webreg.service.saml.SamlHelper;
import edu.kit.scc.webreg.util.SessionManager;
@Named
@WebServlet(urlPatterns = {"/Shibboleth.sso/SAML2/AttributeQuery"})
......@@ -69,7 +58,7 @@ public class Saml2AttributeQueryServlet implements Servlet {
private Saml2DecoderService saml2DecoderService;
@Inject
private Saml2AssertionService saml2AssertionService;
private Saml2ResponseValidationService saml2ValidationService;
@Inject
private SamlHelper samlHelper;
......@@ -78,7 +67,7 @@ public class Saml2AttributeQueryServlet implements Servlet {
private SamlIdpMetadataService idpService;
@Inject
private SamlSpConfigurationService spService;
private SamlSpMetadataService spMetadataService;
@Inject
private ApplicationConfig appConfig;
......@@ -99,7 +88,23 @@ public class Saml2AttributeQueryServlet implements Servlet {
try {
AttributeQuery query = saml2DecoderService.decodeAttributeQuery(request);
logger.debug("SAML AttributeQuery decoded");
Issuer issuer = query.getIssuer();
if (issuer == null || issuer.getValue() == null)
throw new SamlAuthenticationException("Issuer not set");
String issuerString = issuer.getValue();
SamlSpMetadataEntity spEntity = spMetadataService.findByEntityId(issuerString);
if (spEntity == null)
throw new SamlAuthenticationException("Issuer metadata not in database");
EntityDescriptor spEntityDescriptor = samlHelper.unmarshal(
spEntity.getEntityDescriptor(), EntityDescriptor.class);
saml2ValidationService.verifyIssuer(spEntity, query);
saml2ValidationService.validateSpSignature(query, issuer, spEntityDescriptor);
StatusCode statusCode = samlHelper.create(StatusCode.class, StatusCode.DEFAULT_ELEMENT_NAME);
statusCode.setValue(StatusCode.REQUEST_DENIED_URI);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment