Commit 7085d715 authored by michael.simon's avatar michael.simon
Browse files

Issue signed response containing an assertion

parent 9fc391a3
......@@ -18,10 +18,16 @@ import javax.inject.Named;
import org.joda.time.DateTime;
import org.opensaml.saml.common.SAMLVersion;
import org.opensaml.saml.saml2.core.SubjectConfirmation;
import org.opensaml.saml.saml2.core.SubjectConfirmationData;
import org.opensaml.saml.saml2.core.AuthnRequest;
import org.opensaml.saml.saml2.core.Issuer;
import org.opensaml.saml.saml2.core.NameID;
import org.opensaml.saml.saml2.core.NameIDPolicy;
import org.opensaml.saml.saml2.core.Response;
import org.opensaml.saml.saml2.core.Status;
import org.opensaml.saml.saml2.core.StatusCode;
import org.opensaml.saml.saml2.core.Subject;
@Named("ssoHelper")
@ApplicationScoped
......@@ -65,6 +71,40 @@ public class SsoHelper implements Serializable {
issuer.setValue(spEntityId);
response.setIssuer(issuer);
Status status = samlHelper.create(Status.class, Status.DEFAULT_ELEMENT_NAME);
StatusCode statusCode = samlHelper.create(StatusCode.class, StatusCode.DEFAULT_ELEMENT_NAME);
statusCode.setValue(StatusCode.SUCCESS);
status.setStatusCode(statusCode);
response.setStatus(status);
return response;
}
public Issuer buildIssuser(String entityId) {
Issuer issuer = samlHelper.create(Issuer.class, Issuer.DEFAULT_ELEMENT_NAME);
issuer.setValue(entityId);
return issuer;
}
public Subject buildSubject(String nameIdValue, String nameIdType, String inResponseTo) {
NameID nameId = samlHelper.create(NameID.class, NameID.DEFAULT_ELEMENT_NAME);
nameId.setFormat(nameIdType);
nameId.setValue(nameIdValue);
nameId.setNameQualifier("https://bwidm.scc.kit.edu/saml/idp/metadata");
nameId.setSPNameQualifier("https://bwidm-dev.scc.kit.edu/nextcloud/index.php/apps/user_saml/saml/metadata");
SubjectConfirmationData scd = samlHelper.create(SubjectConfirmationData.class, SubjectConfirmationData.DEFAULT_ELEMENT_NAME);
scd.setNotOnOrAfter(new DateTime(System.currentTimeMillis() + (5L * 60L * 1000L)));
//scd.setRecipient("https://bwidm-dev.scc.kit.edu/nextcloud/index.php/apps/user_saml/saml/metadata");
scd.setInResponseTo(inResponseTo);
SubjectConfirmation sc = samlHelper.create(SubjectConfirmation.class, SubjectConfirmation.DEFAULT_ELEMENT_NAME);
sc.setMethod(SubjectConfirmation.METHOD_BEARER);
sc.setSubjectConfirmationData(scd);
Subject subject = samlHelper.create(Subject.class, Subject.DEFAULT_ELEMENT_NAME);
subject.setNameID(nameId);
subject.getSubjectConfirmations().add(sc);
return subject;
}
}
......@@ -50,6 +50,7 @@ import edu.kit.scc.webreg.service.UserService;
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.service.saml.SsoHelper;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
@ApplicationScoped
......@@ -73,6 +74,9 @@ public class Saml2AttributeQueryHandler {
@Inject
private UserService userService;
@Inject
private SsoHelper ssoHelper;
@Inject
private ApplicationConfig appConfig;
......@@ -102,7 +106,7 @@ public class Saml2AttributeQueryHandler {
saml2ValidationService.validateSpSignature(query, issuer, spEntityDescriptor);
Response samlResponse = buildSamlRespone(StatusCode.SUCCESS, null);
samlResponse.setIssuer(buildIssuser(aaConfig.getEntityId()));
samlResponse.setIssuer(ssoHelper.buildIssuser(aaConfig.getEntityId()));
samlResponse.setIssueInstant(new DateTime());
if (query.getSubject() != null && query.getSubject().getNameID() != null) {
......@@ -113,8 +117,8 @@ public class Saml2AttributeQueryHandler {
if (user != null) {
Assertion assertion = samlHelper.create(Assertion.class, Assertion.DEFAULT_ELEMENT_NAME);
assertion.setIssueInstant(new DateTime());
assertion.setIssuer(buildIssuser(aaConfig.getEntityId()));
assertion.setSubject(buildSubject(nameIdValue, NameID.UNSPECIFIED));
assertion.setIssuer(ssoHelper.buildIssuser(aaConfig.getEntityId()));
assertion.setSubject(ssoHelper.buildSubject(nameIdValue, NameID.UNSPECIFIED, query.getID()));
assertion.getAttributeStatements().add(buildAttributeStatement(user));
samlResponse.getAssertions().add(assertion);
}
......@@ -179,23 +183,7 @@ public class Saml2AttributeQueryHandler {
}
return samlStatus;
}
private Issuer buildIssuser(String entityId) {
Issuer issuer = samlHelper.create(Issuer.class, Issuer.DEFAULT_ELEMENT_NAME);
issuer.setValue(entityId);
return issuer;
}
private Subject buildSubject(String nameIdValue, String nameIdType) {
NameID nameId = samlHelper.create(NameID.class, NameID.DEFAULT_ELEMENT_NAME);
nameId.setFormat(nameIdType);
nameId.setValue(nameIdValue);
Subject subject = samlHelper.create(Subject.class, Subject.DEFAULT_ELEMENT_NAME);
subject.setNameID(nameId);
return subject;
}
private AttributeStatement buildAttributeStatement(UserEntity user) {
AttributeStatement attributeStatement = samlHelper.create(AttributeStatement.class, AttributeStatement.DEFAULT_ELEMENT_NAME);
attributeStatement.getAttributes().add(buildAttribute(
......
......@@ -13,6 +13,10 @@ package edu.kit.scc.webreg.sec;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ApplicationScoped;
import javax.inject.Inject;
......@@ -21,24 +25,55 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.velocity.app.VelocityEngine;
import org.joda.time.DateTime;
import org.opensaml.core.xml.io.MarshallingException;
import org.opensaml.core.xml.schema.XSString;
import org.opensaml.messaging.context.MessageContext;
import org.opensaml.messaging.decoder.MessageDecodingException;
import org.opensaml.messaging.encoder.MessageEncodingException;
import org.opensaml.saml.common.SAMLObject;
import org.opensaml.saml.common.messaging.SAMLMessageSecuritySupport;
import org.opensaml.saml.common.messaging.context.SAMLEndpointContext;
import org.opensaml.saml.common.messaging.context.SAMLPeerEntityContext;
import org.opensaml.saml.common.xml.SAMLConstants;
import org.opensaml.saml.criterion.RoleDescriptorCriterion;
import org.opensaml.saml.saml2.binding.encoding.impl.HTTPPostEncoder;
import org.opensaml.saml.saml2.core.Assertion;
import org.opensaml.saml.saml2.core.Attribute;
import org.opensaml.saml.saml2.core.AttributeStatement;
import org.opensaml.saml.saml2.core.AttributeValue;
import org.opensaml.saml.saml2.core.Audience;
import org.opensaml.saml.saml2.core.AudienceRestriction;
import org.opensaml.saml.saml2.core.AuthnContext;
import org.opensaml.saml.saml2.core.AuthnContextClassRef;
import org.opensaml.saml.saml2.core.AuthnRequest;
import org.opensaml.saml.saml2.core.AuthnStatement;
import org.opensaml.saml.saml2.core.Condition;
import org.opensaml.saml.saml2.core.Conditions;
import org.opensaml.saml.saml2.core.NameID;
import org.opensaml.saml.saml2.core.Response;
import org.opensaml.saml.saml2.metadata.AssertionConsumerService;
import org.opensaml.saml.security.impl.SAMLMetadataSignatureSigningParametersResolver;
import org.opensaml.security.SecurityException;
import org.opensaml.security.credential.Credential;
import org.opensaml.security.x509.BasicX509Credential;
import org.opensaml.xmlsec.SignatureSigningParameters;
import org.opensaml.xmlsec.config.impl.DefaultSecurityConfigurationBootstrap;
import org.opensaml.xmlsec.context.SecurityParametersContext;
import org.opensaml.xmlsec.criterion.SignatureSigningConfigurationCriterion;
import org.opensaml.xmlsec.impl.BasicSignatureSigningConfiguration;
import org.opensaml.xmlsec.signature.support.SignatureException;
import org.slf4j.Logger;
import edu.kit.scc.webreg.bootstrap.ApplicationConfig;
import edu.kit.scc.webreg.drools.KnowledgeSessionService;
import edu.kit.scc.webreg.entity.SamlAAConfigurationEntity;
import edu.kit.scc.webreg.entity.UserEntity;
import edu.kit.scc.webreg.exc.SamlAuthenticationException;
import edu.kit.scc.webreg.service.SamlAAConfigurationService;
import edu.kit.scc.webreg.service.SamlIdpMetadataService;
import edu.kit.scc.webreg.service.UserService;
import edu.kit.scc.webreg.service.saml.CryptoHelper;
import edu.kit.scc.webreg.service.saml.Saml2AssertionService;
import edu.kit.scc.webreg.service.saml.Saml2DecoderService;
import edu.kit.scc.webreg.service.saml.SamlHelper;
......@@ -46,6 +81,8 @@ import edu.kit.scc.webreg.service.saml.SamlIdpService;
import edu.kit.scc.webreg.service.saml.SsoHelper;
import edu.kit.scc.webreg.session.SessionManager;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
import net.shibboleth.utilities.java.support.resolver.ResolverException;
@ApplicationScoped
public class Saml2IdpRedirectResponseHandler {
......@@ -66,7 +103,13 @@ public class Saml2IdpRedirectResponseHandler {
private SsoHelper ssoHelper;
@Inject
private Saml2DecoderService saml2DecoderService;
private CryptoHelper cryptoHelper;
@Inject
private UserService userService;
@Inject
private SamlAAConfigurationService aaConfigService;
@Inject
private ApplicationConfig appConfig;
......@@ -79,17 +122,87 @@ public class Saml2IdpRedirectResponseHandler {
return;
}
if (session.getUserId() == null) {
logger.warn("No UserId set in session. Cannot continue");
return;
}
SamlAAConfigurationEntity aaConfig = aaConfigService.findByEntityId("https://bwidm.scc.kit.edu/attribute-authority");
UserEntity user = userService.findById(session.getUserId());
AuthnRequest authnRequest = samlIdpService.resumeAuthnRequest(session.getAuthnRequestId());
logger.debug("Authn request reloaded: {}", samlHelper.prettyPrint(authnRequest));
Response samlResponse = ssoHelper.buildAuthnResponse(authnRequest, "https://bwidm.scc.kit.edu/saml/idp/metadata");
Audience audience = samlHelper.create(Audience.class, Audience.DEFAULT_ELEMENT_NAME);
audience.setAudienceURI("https://bwidm-dev.scc.kit.edu/nextcloud/index.php/apps/user_saml/saml/metadata");
AudienceRestriction ar = samlHelper.create(AudienceRestriction.class, AudienceRestriction.DEFAULT_ELEMENT_NAME);
ar.getAudiences().add(audience);
Conditions conditions = samlHelper.create(Conditions.class, Conditions.DEFAULT_ELEMENT_NAME);
conditions.setNotBefore(new DateTime());
conditions.setNotOnOrAfter(new DateTime(System.currentTimeMillis() + (5L * 60L * 1000L)));
conditions.getAudienceRestrictions().add(ar);
AuthnContextClassRef accr = samlHelper.create(AuthnContextClassRef.class, AuthnContextClassRef.DEFAULT_ELEMENT_NAME);
AuthnContext ac = samlHelper.create(AuthnContext.class, AuthnContext.DEFAULT_ELEMENT_NAME);
ac.setAuthnContextClassRef(accr);
AuthnStatement as = samlHelper.create(AuthnStatement.class, AuthnStatement.DEFAULT_ELEMENT_NAME);
as.setAuthnContext(ac);
as.setAuthnInstant(new DateTime());
as.setSessionNotOnOrAfter(new DateTime(System.currentTimeMillis() + (5L * 60L * 1000L)));
as.setSessionIndex(samlHelper.getRandomId());
Assertion assertion = samlHelper.create(Assertion.class, Assertion.DEFAULT_ELEMENT_NAME);
assertion.setID(samlHelper.getRandomId());
assertion.setIssueInstant(new DateTime());
assertion.setIssuer(ssoHelper.buildIssuser("https://bwidm.scc.kit.edu/saml/idp/metadata"));
assertion.setSubject(ssoHelper.buildSubject(samlHelper.getRandomId(), NameID.TRANSIENT, authnRequest.getID()));
assertion.setConditions(conditions);
assertion.getAttributeStatements().add(buildAttributeStatement(user));
assertion.getAuthnStatements().add(as);
samlResponse.getAssertions().add(assertion);
PrivateKey privateKey;
X509Certificate publicKey;
try {
privateKey = cryptoHelper.getPrivateKey(aaConfig.getPrivateKey());
publicKey = cryptoHelper.getCertificate(aaConfig.getCertificate());
} catch (IOException e) {
throw new ServletException("Private key is not set up properly", e);
}
BasicX509Credential credential = new BasicX509Credential(publicKey, privateKey);
List<Credential> credentialList = new ArrayList<Credential>();
credentialList.add(credential);
BasicSignatureSigningConfiguration ssConfig = DefaultSecurityConfigurationBootstrap.buildDefaultSignatureSigningConfiguration();
ssConfig.setSigningCredentials(credentialList);
CriteriaSet criteriaSet = new CriteriaSet();
criteriaSet.add(new SignatureSigningConfigurationCriterion(ssConfig));
SAMLMetadataSignatureSigningParametersResolver smsspr = new SAMLMetadataSignatureSigningParametersResolver();
SignatureSigningParameters ssp;
try {
ssp = smsspr.resolveSingle(criteriaSet);
} catch (ResolverException e) {
throw new ServletException(e);
}
logger.debug("Resolved algo {} for signing", ssp.getSignatureAlgorithm());
SecurityParametersContext securityContext = new SecurityParametersContext();
securityContext.setSignatureSigningParameters(ssp);
HTTPPostEncoder postEncoder = new HTTPPostEncoder();
postEncoder.setHttpServletResponse(response);
MessageContext<SAMLObject> messageContext = new MessageContext<SAMLObject>();
Response samlResponse = ssoHelper.buildAuthnResponse(authnRequest, "https://bwidm.scc.kit.edu/saml/idp/metadata");
messageContext.setMessage(samlResponse);
messageContext.addSubcontext(securityContext);
SAMLPeerEntityContext entityContext = new SAMLPeerEntityContext();
//entityContext.setEntityId("http://test");
SAMLEndpointContext endpointContext = new SAMLEndpointContext();
AssertionConsumerService acs = samlHelper.create(AssertionConsumerService.class, AssertionConsumerService.DEFAULT_ELEMENT_NAME);
......@@ -98,6 +211,12 @@ public class Saml2IdpRedirectResponseHandler {
entityContext.addSubcontext(endpointContext);
messageContext.addSubcontext(entityContext);
try {
SAMLMessageSecuritySupport.signMessage(messageContext);
} catch (SecurityException | MarshallingException | SignatureException e) {
throw new ServletException(e);
}
postEncoder.setMessageContext(messageContext);
VelocityEngine engine = new VelocityEngine();
......@@ -117,4 +236,30 @@ public class Saml2IdpRedirectResponseHandler {
throw new ServletException(e);
}
}
private AttributeStatement buildAttributeStatement(UserEntity user) {
AttributeStatement attributeStatement = samlHelper.create(AttributeStatement.class, AttributeStatement.DEFAULT_ELEMENT_NAME);
attributeStatement.getAttributes().add(buildAttribute(
"urn:oid:1.3.6.1.4.1.5923.1.1.1.6", "eduPersonPrincipalName", Attribute.URI_REFERENCE, user.getEppn()));
attributeStatement.getAttributes().add(buildAttribute(
"urn:oid:0.9.2342.19200300.100.1.3", "mail", Attribute.URI_REFERENCE, user.getEmail()));
return attributeStatement;
}
private Attribute buildAttribute(String name, String friendlyName, String nameFormat, String... values) {
Attribute attribute = samlHelper.create(Attribute.class, Attribute.DEFAULT_ELEMENT_NAME);
attribute.setName(name);
attribute.setFriendlyName(friendlyName);
attribute.setNameFormat(nameFormat);
for (String value : values) {
XSString xsany = samlHelper.create(XSString.class, XSString.TYPE_NAME, AttributeValue.DEFAULT_ELEMENT_NAME);
xsany.setValue(value);
attribute.getAttributeValues().add(xsany);
}
return attribute;
}
}
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