summaryrefslogtreecommitdiff
path: root/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/impl/PvpAuthnRequestBuilder.java
diff options
context:
space:
mode:
Diffstat (limited to 'eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/impl/PvpAuthnRequestBuilder.java')
-rw-r--r--eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/impl/PvpAuthnRequestBuilder.java263
1 files changed, 263 insertions, 0 deletions
diff --git a/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/impl/PvpAuthnRequestBuilder.java b/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/impl/PvpAuthnRequestBuilder.java
new file mode 100644
index 00000000..36f43cc8
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_sp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/sp/impl/PvpAuthnRequestBuilder.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a
+ * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European
+ * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in
+ * compliance with the Licence. You may obtain a copy of the Licence at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence
+ * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the Licence for the specific language governing permissions and limitations under
+ * the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text file for details on the
+ * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative
+ * works that you distribute must include a readable copy of the "NOTICE" text file.
+*/
+
+package at.gv.egiz.eaaf.modules.pvp2.sp.impl;
+
+import java.security.NoSuchAlgorithmException;
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.modules.pvp2.api.binding.IEncoder;
+import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttribute;
+import at.gv.egiz.eaaf.modules.pvp2.api.reqattr.EaafRequestedAttributes;
+import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception;
+import at.gv.egiz.eaaf.modules.pvp2.impl.binding.PostBinding;
+import at.gv.egiz.eaaf.modules.pvp2.impl.binding.RedirectBinding;
+import at.gv.egiz.eaaf.modules.pvp2.impl.builder.reqattr.EaafRequestExtensionBuilder;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils;
+import at.gv.egiz.eaaf.modules.pvp2.sp.api.IPvpAuthnRequestBuilderConfiguruation;
+import at.gv.egiz.eaaf.modules.pvp2.sp.exception.AuthnRequestBuildException;
+import org.apache.commons.lang3.StringUtils;
+import org.joda.time.DateTime;
+import org.opensaml.common.impl.SecureRandomIdentifierGenerator;
+import org.opensaml.common.xml.SAMLConstants;
+import org.opensaml.saml2.common.Extensions;
+import org.opensaml.saml2.core.AuthnContextClassRef;
+import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration;
+import org.opensaml.saml2.core.AuthnRequest;
+import org.opensaml.saml2.core.Issuer;
+import org.opensaml.saml2.core.NameID;
+import org.opensaml.saml2.core.NameIDPolicy;
+import org.opensaml.saml2.core.NameIDType;
+import org.opensaml.saml2.core.RequestedAuthnContext;
+import org.opensaml.saml2.core.RequesterID;
+import org.opensaml.saml2.core.Scoping;
+import org.opensaml.saml2.core.Subject;
+import org.opensaml.saml2.core.SubjectConfirmation;
+import org.opensaml.saml2.core.SubjectConfirmationData;
+import org.opensaml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml2.metadata.SingleSignOnService;
+import org.opensaml.ws.message.encoder.MessageEncodingException;
+import org.opensaml.xml.security.SecurityException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Service;
+
+/**
+ * PVP2 S-Profil Authentication-Request builder-implementation.
+ *
+ * @author tlenz
+ *
+ */
+@Service("pvpAuthnRequestBuilder")
+public class PvpAuthnRequestBuilder {
+ private static final Logger log = LoggerFactory.getLogger(PvpAuthnRequestBuilder.class);
+
+
+ @Autowired(required = true)
+ ApplicationContext springContext;
+
+
+ /**
+ * Build a PVP2.x specific authentication request
+ *
+ * @param pendingReq Currently processed pendingRequest
+ * @param config AuthnRequest builder configuration, never null
+ * @param httpResp http response object
+ * @throws NoSuchAlgorithmException In case of error
+ * @throws SecurityException In case of error
+ * @throws Pvp2Exception In case of error
+ * @throws MessageEncodingException In case of error
+ */
+ public void buildAuthnRequest(final IRequest pendingReq,
+ final IPvpAuthnRequestBuilderConfiguruation config, final HttpServletResponse httpResp)
+ throws NoSuchAlgorithmException, MessageEncodingException, Pvp2Exception, SecurityException {
+ // get IDP Entity element from config
+ final EntityDescriptor idpEntity = config.getIdpEntityDescriptor();
+
+ final AuthnRequest authReq = Saml2Utils.createSamlObject(AuthnRequest.class);
+
+ // select SingleSignOn Service endpoint from IDP metadata
+ SingleSignOnService endpoint = null;
+ for (final SingleSignOnService sss : idpEntity.getIDPSSODescriptor(SAMLConstants.SAML20P_NS)
+ .getSingleSignOnServices()) {
+
+ // use POST binding as default if it exists
+ if (sss.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) {
+ endpoint = sss;
+
+ } else if (sss.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)
+ && endpoint == null) {
+ endpoint = sss;
+ }
+
+ }
+
+ if (endpoint == null) {
+ log.warn("Building AuthnRequest FAILED: > Requested IDP " + idpEntity.getEntityID()
+ + " does not support POST or Redirect Binding.");
+ throw new AuthnRequestBuildException("sp.pvp2.00",
+ new Object[] {config.getSpNameForLogging(), idpEntity.getEntityID()});
+
+ } else {
+ authReq.setDestination(endpoint.getLocation());
+ }
+
+
+ // set basic AuthnRequest information
+ final String reqID = config.getRequestID();
+ if (StringUtils.isNotEmpty(reqID)) {
+ authReq.setID(reqID);
+ } else {
+ final SecureRandomIdentifierGenerator gen = new SecureRandomIdentifierGenerator();
+ authReq.setID(gen.generateIdentifier());
+
+ }
+
+ authReq.setIssueInstant(new DateTime());
+
+ // set isPassive flag
+ if (config.isPassivRequest() == null) {
+ authReq.setIsPassive(false);
+ } else {
+ authReq.setIsPassive(config.isPassivRequest());
+ }
+
+ // set EntityID of the service provider
+ final Issuer issuer = Saml2Utils.createSamlObject(Issuer.class);
+ issuer.setFormat(NameIDType.ENTITY);
+ issuer.setValue(config.getSpEntityID());
+ authReq.setIssuer(issuer);
+
+ // set AssertionConsumerService ID
+ if (config.getAssertionConsumerServiceId() != null) {
+ authReq.setAssertionConsumerServiceIndex(config.getAssertionConsumerServiceId());
+ }
+
+ // set NameIDPolicy
+ if (config.getNameIdPolicyFormat() != null) {
+ final NameIDPolicy policy = Saml2Utils.createSamlObject(NameIDPolicy.class);
+ policy.setAllowCreate(config.getNameIdPolicyAllowCreation());
+ policy.setFormat(config.getNameIdPolicyFormat());
+ authReq.setNameIDPolicy(policy);
+ }
+
+ // set requested QAA level
+ if (config.getAuthnContextClassRef() != null) {
+ final RequestedAuthnContext reqAuthContext =
+ Saml2Utils.createSamlObject(RequestedAuthnContext.class);
+ final AuthnContextClassRef authnClassRef =
+ Saml2Utils.createSamlObject(AuthnContextClassRef.class);
+
+ authnClassRef.setAuthnContextClassRef(config.getAuthnContextClassRef());
+
+ if (config.getAuthnContextComparison() == null) {
+ reqAuthContext.setComparison(AuthnContextComparisonTypeEnumeration.MINIMUM);
+ } else {
+ reqAuthContext.setComparison(config.getAuthnContextComparison());
+ }
+
+ reqAuthContext.getAuthnContextClassRefs().add(authnClassRef);
+ authReq.setRequestedAuthnContext(reqAuthContext);
+ }
+
+ // set request Subject element
+ if (StringUtils.isNotEmpty(config.getSubjectNameID())) {
+ final Subject reqSubject = Saml2Utils.createSamlObject(Subject.class);
+ final NameID subjectNameID = Saml2Utils.createSamlObject(NameID.class);
+
+ subjectNameID.setValue(config.getSubjectNameID());
+ if (StringUtils.isNotEmpty(config.getSubjectNameIdQualifier())) {
+ subjectNameID.setNameQualifier(config.getSubjectNameIdQualifier());
+ }
+
+ if (StringUtils.isNotEmpty(config.getSubjectNameIdFormat())) {
+ subjectNameID.setFormat(config.getSubjectNameIdFormat());
+ } else {
+ subjectNameID.setFormat(NameIDType.TRANSIENT);
+ }
+
+ reqSubject.setNameID(subjectNameID);
+
+ if (config.getSubjectConformationDate() != null) {
+ final SubjectConfirmation subjectConformation =
+ Saml2Utils.createSamlObject(SubjectConfirmation.class);
+ final SubjectConfirmationData subjectConformDate =
+ Saml2Utils.createSamlObject(SubjectConfirmationData.class);
+ subjectConformation.setSubjectConfirmationData(subjectConformDate);
+ reqSubject.getSubjectConfirmations().add(subjectConformation);
+
+ if (config.getSubjectConformationMethode() != null) {
+ subjectConformation.setMethod(config.getSubjectConformationMethode());
+ }
+
+ subjectConformDate.setDOM(config.getSubjectConformationDate());
+
+ }
+
+ authReq.setSubject(reqSubject);
+
+ }
+
+
+ // set ProviderName
+ if (StringUtils.isNotEmpty(config.getProviderName())) {
+ authReq.setProviderName(config.getProviderName());
+ }
+
+ // set RequesterId in case of proxy mode
+ if (StringUtils.isNotEmpty(config.getScopeRequesterId())) {
+ final Scoping scope = Saml2Utils.createSamlObject(Scoping.class);
+ final RequesterID requesterId = Saml2Utils.createSamlObject(RequesterID.class);
+ requesterId.setRequesterID(config.getScopeRequesterId());
+ scope.getRequesterIDs().add(requesterId);
+ authReq.setScoping(scope);
+
+ }
+
+ // add optional requested attributes
+ if (config.getRequestedAttributes() != null) {
+ final List<EaafRequestedAttribute> reqAttr = config.getRequestedAttributes();
+ final Extensions extenstions = new EaafRequestExtensionBuilder().buildObject();
+ final EaafRequestedAttributes reqAttributs =
+ Saml2Utils.createSamlObject(EaafRequestedAttributes.class);
+ reqAttributs.getAttributes().addAll(reqAttr);
+ extenstions.getUnknownXMLObjects().add(reqAttributs);
+ authReq.setExtensions(extenstions);
+
+ }
+
+ // select message encoder
+ IEncoder binding = null;
+ if (endpoint.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)) {
+ binding = springContext.getBean("PVPRedirectBinding", RedirectBinding.class);
+
+ } else if (endpoint.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) {
+ binding = springContext.getBean("PVPPOSTBinding", PostBinding.class);
+
+ }
+
+ // encode message
+ binding.encodeRequest(null, httpResp, authReq, endpoint.getLocation(),
+ pendingReq.getPendingRequestId(), config.getAuthnRequestSigningCredential(), pendingReq);
+ }
+
+}