summaryrefslogtreecommitdiff
path: root/eaaf_modules/eaaf_module_pvp2_idp/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'eaaf_modules/eaaf_module_pvp2_idp/src/main')
-rw-r--r--eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AbstractPvp2XProtocol.java1041
1 files changed, 513 insertions, 528 deletions
diff --git a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AbstractPvp2XProtocol.java b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AbstractPvp2XProtocol.java
index a56c8726..597d3c22 100644
--- a/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AbstractPvp2XProtocol.java
+++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AbstractPvp2XProtocol.java
@@ -1,22 +1,29 @@
-/*
- * 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.
+/*******************************************************************************
+ * 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:
+ * 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.
-*/
-
+ * 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.idp.impl;
import java.util.List;
@@ -25,540 +32,518 @@ import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.joda.time.DateTime;
+import org.opensaml.common.xml.SAMLConstants;
+import org.opensaml.saml2.core.AuthnRequest;
+import org.opensaml.saml2.core.Issuer;
+import org.opensaml.saml2.core.NameID;
+import org.opensaml.saml2.core.Response;
+import org.opensaml.saml2.core.Status;
+import org.opensaml.saml2.core.StatusCode;
+import org.opensaml.saml2.core.StatusMessage;
+import org.opensaml.saml2.metadata.AssertionConsumerService;
+import org.opensaml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml2.metadata.SPSSODescriptor;
+import org.opensaml.ws.security.SecurityPolicyException;
+import org.opensaml.xml.security.x509.X509Credential;
+import org.opensaml.xml.signature.SignableXMLObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
import at.gv.egiz.components.eventlog.api.EventConstants;
import at.gv.egiz.eaaf.core.api.IRequest;
-import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
import at.gv.egiz.eaaf.core.api.idp.IModulInfo;
import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger;
import at.gv.egiz.eaaf.core.exceptions.AuthnRequestValidatorException;
-import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
import at.gv.egiz.eaaf.core.exceptions.InvalidProtocolRequestException;
import at.gv.egiz.eaaf.core.exceptions.NoPassivAuthenticationException;
-import at.gv.egiz.eaaf.core.exceptions.SloException;
+import at.gv.egiz.eaaf.core.exceptions.SLOException;
import at.gv.egiz.eaaf.core.impl.idp.controller.AbstractController;
-import at.gv.egiz.eaaf.modules.pvp2.PvpEventConstants;
-import at.gv.egiz.eaaf.modules.pvp2.api.IPvp2BasicConfiguration;
+import at.gv.egiz.eaaf.modules.pvp2.PVPEventConstants;
+import at.gv.egiz.eaaf.modules.pvp2.api.IPVP2BasicConfiguration;
import at.gv.egiz.eaaf.modules.pvp2.api.binding.IEncoder;
-import at.gv.egiz.eaaf.modules.pvp2.api.credential.EaafX509Credential;
-import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider;
-import at.gv.egiz.eaaf.modules.pvp2.api.utils.IPvp2CredentialProvider;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPVPMetadataProvider;
import at.gv.egiz.eaaf.modules.pvp2.api.validation.IAuthnRequestPostProcessor;
-import at.gv.egiz.eaaf.modules.pvp2.exception.InvalidPvpRequestException;
-import at.gv.egiz.eaaf.modules.pvp2.exception.NameIdFormatNotSupportedException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.InvalidPVPRequestException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.NameIDFormatNotSupportedException;
import at.gv.egiz.eaaf.modules.pvp2.exception.NoMetadataInformationException;
-import at.gv.egiz.eaaf.modules.pvp2.exception.Pvp2Exception;
-import at.gv.egiz.eaaf.modules.pvp2.exception.SamlSigningException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.PVP2Exception;
import at.gv.egiz.eaaf.modules.pvp2.idp.exception.InvalidAssertionConsumerServiceException;
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.binding.SoapBinding;
import at.gv.egiz.eaaf.modules.pvp2.impl.message.InboundMessage;
-import at.gv.egiz.eaaf.modules.pvp2.impl.message.PvpSProfileRequest;
-import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils;
-import at.gv.egiz.eaaf.modules.pvp2.impl.validation.EaafUriCompare;
+import at.gv.egiz.eaaf.modules.pvp2.impl.message.PVPSProfileRequest;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.SAML2Utils;
+import at.gv.egiz.eaaf.modules.pvp2.impl.validation.EAAFURICompare;
import at.gv.egiz.eaaf.modules.pvp2.impl.validation.TrustEngineFactory;
-import at.gv.egiz.eaaf.modules.pvp2.impl.verification.SamlVerificationEngine;
-
-import org.apache.commons.lang.StringEscapeUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.joda.time.DateTime;
-import org.opensaml.saml.common.xml.SAMLConstants;
-import org.opensaml.saml.saml2.core.AuthnRequest;
-import org.opensaml.saml.saml2.core.Issuer;
-import org.opensaml.saml.saml2.core.NameIDType;
-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.StatusMessage;
-import org.opensaml.saml.saml2.metadata.AssertionConsumerService;
-import org.opensaml.saml.saml2.metadata.EntityDescriptor;
-import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
-import org.opensaml.xmlsec.signature.SignableXMLObject;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public abstract class AbstractPvp2XProtocol extends AbstractController implements IModulInfo {
- private static final Logger log = LoggerFactory.getLogger(AbstractPvp2XProtocol.class);
-
- private static final String HTTP_PARAM_SAMLREQ = "SAMLRequest";
- private static final String ERROR_INVALID_REQUEST = "Receive INVALID protocol request: {}";
-
- @Autowired(required = true)
- protected IPvp2BasicConfiguration pvpBasicConfiguration;
- @Autowired(required = true)
- protected IPvp2MetadataProvider metadataProvider;
- @Autowired(required = true)
- protected SamlVerificationEngine samlVerificationEngine;
- @Autowired(required = false)
- protected List<IAuthnRequestPostProcessor> authRequestPostProcessors;
-
- private IPvp2CredentialProvider pvpIdpCredentials;
-
- /**
- * Sets a specific credential provider for PVP S-Profile IDP component.
- *
- * @param pvpIdpCredentials credential provider
- */
- public void setPvpIdpCredentials(final IPvp2CredentialProvider pvpIdpCredentials) {
- this.pvpIdpCredentials = pvpIdpCredentials;
-
- }
-
- @Override
- public boolean generateErrorMessage(final Throwable e, final HttpServletRequest request,
- final HttpServletResponse response, final IRequest protocolRequest) throws Throwable {
-
- if (protocolRequest == null) {
- throw e;
- }
-
- if (!(protocolRequest instanceof PvpSProfilePendingRequest)) {
- throw e;
- }
- final PvpSProfilePendingRequest pvpRequest = (PvpSProfilePendingRequest) protocolRequest;
-
- final Response samlResponse = Saml2Utils.createSamlObject(Response.class);
- final Status status = Saml2Utils.createSamlObject(Status.class);
- final StatusCode statusCode = Saml2Utils.createSamlObject(StatusCode.class);
- final StatusMessage statusMessage = Saml2Utils.createSamlObject(StatusMessage.class);
-
- String moaError = null;
-
- if (e instanceof NoPassivAuthenticationException) {
- statusCode.setValue(StatusCode.NO_PASSIVE);
- statusMessage.setMessage(StringEscapeUtils.escapeXml(e.getLocalizedMessage()));
-
- } else if (e instanceof NameIdFormatNotSupportedException) {
- statusCode.setValue(StatusCode.INVALID_NAMEID_POLICY);
- statusMessage.setMessage(StringEscapeUtils.escapeXml(e.getLocalizedMessage()));
-
- } else if (e instanceof SloException) {
- // SLOExecpetions only occurs if session information is lost
- return false;
-
- } else if (e instanceof Pvp2Exception) {
- final Pvp2Exception ex = (Pvp2Exception) e;
- statusCode.setValue(ex.getStatusCodeValue());
- final String statusMessageValue = ex.getStatusMessageValue();
- if (statusMessageValue != null) {
- statusMessage.setMessage(StringEscapeUtils.escapeXml(statusMessageValue));
- }
- moaError = statusMessager.mapInternalErrorToExternalError(ex.getErrorId());
-
- } else {
- statusCode.setValue(StatusCode.RESPONDER);
- statusMessage.setMessage(StringEscapeUtils.escapeXml(e.getLocalizedMessage()));
- moaError = statusMessager.getResponseErrorCode(e);
- }
-
- if (StringUtils.isNotEmpty(moaError)) {
- final StatusCode moaStatusCode = Saml2Utils.createSamlObject(StatusCode.class);
- moaStatusCode.setValue(moaError);
- statusCode.setStatusCode(moaStatusCode);
- }
-
- status.setStatusCode(statusCode);
- if (statusMessage.getMessage() != null) {
- status.setStatusMessage(statusMessage);
- }
- samlResponse.setStatus(status);
- final String remoteSessionID = Saml2Utils.getSecureIdentifier();
- samlResponse.setID(remoteSessionID);
-
- samlResponse.setIssueInstant(new DateTime());
- final Issuer nissuer = Saml2Utils.createSamlObject(Issuer.class);
- nissuer.setValue(pvpBasicConfiguration.getIdpEntityId(pvpRequest.getAuthUrl()));
- nissuer.setFormat(NameIDType.ENTITY);
- samlResponse.setIssuer(nissuer);
-
- IEncoder encoder = null;
-
- if (pvpRequest.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)) {
- encoder = applicationContext.getBean("PVPRedirectBinding", RedirectBinding.class);
-
- } else if (pvpRequest.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) {
- encoder = applicationContext.getBean("PVPPOSTBinding", PostBinding.class);
-
- } else if (pvpRequest.getBinding().equals(SAMLConstants.SAML2_SOAP11_BINDING_URI)) {
- encoder = applicationContext.getBean("PVPSOAPBinding", SoapBinding.class);
- }
-
- if (encoder == null) {
- // default to redirect binding
- encoder = new RedirectBinding();
- }
-
- String relayState = null;
- if (pvpRequest.getRequest() != null) {
- relayState = pvpRequest.getRequest().getRelayState();
- }
-
- final EaafX509Credential signCred = pvpIdpCredentials.getMessageSigningCredential();
-
- encoder.encodeResponse(request, response, samlResponse, pvpRequest.getConsumerUrl(), relayState,
- signCred, protocolRequest);
- return true;
- }
-
- @Override
- public boolean validate(final HttpServletRequest request, final HttpServletResponse response,
- final IRequest pending) {
-
- return true;
- }
-
- protected void pvpMetadataRequest(final HttpServletRequest req, final HttpServletResponse resp)
- throws EaafException {
- // create pendingRequest object
- final PvpSProfilePendingRequest pendingReq =
- applicationContext.getBean(PvpSProfilePendingRequest.class);
- pendingReq.initialize(req, authConfig);
- pendingReq.setModule(getName());
-
- revisionsLogger.logEvent(pendingReq.getUniqueSessionIdentifier(),
- pendingReq.getUniqueTransactionIdentifier(), EventConstants.TRANSACTION_IP,
- req.getRemoteAddr());
-
- final MetadataAction metadataAction = applicationContext.getBean(MetadataAction.class);
- metadataAction.processRequest(pendingReq, req, resp, null);
-
- }
-
- protected void pvpIdpPostRequest(final HttpServletRequest req, final HttpServletResponse resp)
- throws EaafException {
- PvpSProfilePendingRequest pendingReq = null;
-
- try {
- // create pendingRequest object
- pendingReq = applicationContext.getBean(PvpSProfilePendingRequest.class);
- pendingReq.initialize(req, authConfig);
- pendingReq.setModule(getName());
-
- revisionsLogger.logEvent(EventConstants.SESSION_CREATED,
- pendingReq.getUniqueSessionIdentifier());
- revisionsLogger.logEvent(EventConstants.TRANSACTION_CREATED,
- pendingReq.getUniqueTransactionIdentifier());
- revisionsLogger.logEvent(pendingReq.getUniqueSessionIdentifier(),
- pendingReq.getUniqueTransactionIdentifier(), EventConstants.TRANSACTION_IP,
- req.getRemoteAddr());
-
- // get POST-Binding decoder implementation
- final InboundMessage msg = (InboundMessage) new PostBinding().decode(req, resp,
- metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME,
- new EaafUriCompare(pvpBasicConfiguration.getIdpSsoPostService(pendingReq.getAuthUrl())));
- pendingReq.setRequest(msg);
-
- // preProcess Message
- preProcess(req, resp, pendingReq);
-
- } catch (final SamlSigningException e) {
- final String samlRequest = req.getParameter(HTTP_PARAM_SAMLREQ);
- log.warn(ERROR_INVALID_REQUEST, samlRequest, null, e);
-
- // write revision log entries
- if (pendingReq != null) {
- revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR,
- pendingReq.getUniqueTransactionIdentifier());
- }
-
- throw new InvalidProtocolRequestException("pvp2.21", new Object[] {});
-
- } catch (final Pvp2Exception e) {
- final String samlRequest = req.getParameter(HTTP_PARAM_SAMLREQ);
- log.warn(ERROR_INVALID_REQUEST, samlRequest, null, e);
-
- // write revision log entries
- if (pendingReq != null) {
- revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR,
- pendingReq.getUniqueTransactionIdentifier());
- }
-
- throw new InvalidProtocolRequestException("pvp2.22", new Object[] { e.getMessage() });
-
- } catch (final EaafException e) {
-
- // write revision log entries
- if (pendingReq != null) {
- revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR,
- pendingReq.getUniqueTransactionIdentifier());
- }
-
- throw e;
-
- } catch (final Throwable e) {
- final String samlRequest = req.getParameter(HTTP_PARAM_SAMLREQ);
- log.warn(ERROR_INVALID_REQUEST, samlRequest, null, e);
-
- // write revision log entries
- if (pendingReq != null) {
- revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR,
- pendingReq.getUniqueTransactionIdentifier());
- }
-
- throw new EaafException("pvp2.24", new Object[] { e.getMessage() }, e);
- }
- }
-
- protected void pvpIdpRedirecttRequest(final HttpServletRequest req,
- final HttpServletResponse resp) throws EaafException {
- PvpSProfilePendingRequest pendingReq = null;
- try {
- // create pendingRequest object
- pendingReq = applicationContext.getBean(PvpSProfilePendingRequest.class);
- pendingReq.initialize(req, authConfig);
- pendingReq.setModule(getName());
-
- revisionsLogger.logEvent(EventConstants.SESSION_CREATED,
- pendingReq.getUniqueSessionIdentifier());
- revisionsLogger.logEvent(EventConstants.TRANSACTION_CREATED,
- pendingReq.getUniqueTransactionIdentifier());
- revisionsLogger.logEvent(pendingReq.getUniqueSessionIdentifier(),
- pendingReq.getUniqueTransactionIdentifier(), EventConstants.TRANSACTION_IP,
- req.getRemoteAddr());
-
- // get POST-Binding decoder implementation
- final InboundMessage msg = (InboundMessage) new RedirectBinding().decode(req, resp,
- metadataProvider, SPSSODescriptor.DEFAULT_ELEMENT_NAME, new EaafUriCompare(
- pvpBasicConfiguration.getIdpSsoRedirectService(pendingReq.getAuthUrl())));
- pendingReq.setRequest(msg);
-
- // preProcess Message
- preProcess(req, resp, pendingReq);
-
- } catch (final SamlSigningException e) {
- final String samlRequest = req.getParameter(HTTP_PARAM_SAMLREQ);
- log.warn(ERROR_INVALID_REQUEST, samlRequest, null, e);
-
- // write revision log entries
- if (pendingReq != null) {
- revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR,
- pendingReq.getUniqueTransactionIdentifier());
- }
-
- throw new InvalidProtocolRequestException("pvp2.21", new Object[] {});
-
- } catch (final Pvp2Exception e) {
- final String samlRequest = req.getParameter(HTTP_PARAM_SAMLREQ);
- log.warn(ERROR_INVALID_REQUEST, samlRequest, null, e);
-
- // write revision log entries
- if (pendingReq != null) {
- revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR,
- pendingReq.getUniqueTransactionIdentifier());
- }
-
- throw new InvalidProtocolRequestException("pvp2.22", new Object[] { e.getMessage() });
-
- } catch (final EaafException e) {
- final String samlRequest = req.getParameter(HTTP_PARAM_SAMLREQ);
- log.info(ERROR_INVALID_REQUEST, samlRequest, null, e);
-
- // write revision log entries
- if (pendingReq != null) {
- revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR,
- pendingReq.getUniqueTransactionIdentifier());
- }
-
- throw e;
-
- } catch (final Throwable e) {
- final String samlRequest = req.getParameter(HTTP_PARAM_SAMLREQ);
- log.warn(ERROR_INVALID_REQUEST, samlRequest, null, e);
-
- // write revision log entries
- if (pendingReq != null) {
- revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR,
- pendingReq.getUniqueTransactionIdentifier());
- }
-
- throw new EaafException("pvp2.24", new Object[] { e.getMessage() }, e);
- }
- }
-
- /**
- * Authentication request pre-processor.
- *
- * @param request http request
- * @param response http response
- * @param pendingReq current pending request
- * @return true if preprocess can handle this request type, otherwise false
- * @throws Throwable In case of an error
- */
- protected abstract boolean childPreProcess(HttpServletRequest request,
- HttpServletResponse response, PvpSProfilePendingRequest pendingReq) throws Throwable;
-
- protected void preProcess(final HttpServletRequest request, final HttpServletResponse response,
- final PvpSProfilePendingRequest pendingReq) throws Throwable {
-
- final InboundMessage msg = pendingReq.getRequest();
-
- if (StringUtils.isEmpty(msg.getEntityID())) {
- throw new InvalidProtocolRequestException("pvp2.20", new Object[] {});
-
- }
-
- if (!msg.isVerified()) {
- samlVerificationEngine.verify(msg,
- TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider));
- msg.setVerified(true);
-
- }
-
- revisionsLogger.logEvent(pendingReq, IRevisionLogger.AUTHPROTOCOL_TYPE,
- getAuthProtocolIdentifier());
-
- if (msg instanceof PvpSProfileRequest
- && ((PvpSProfileRequest) msg).getSamlRequest() instanceof AuthnRequest) {
- preProcessAuthRequest(request, pendingReq);
- } else if (childPreProcess(request, response, pendingReq)) {
- log.debug("Find protocol handler in child implementation");
- } else {
- log.error("Receive unsupported PVP21 message of type: "
- + ((PvpSProfileRequest) msg).getSamlRequest().getClass().getName());
- throw new InvalidPvpRequestException("pvp2.09",
- new Object[] { ((PvpSProfileRequest) msg).getSamlRequest().getClass().getName() });
- }
-
- // switch to session authentication
- protAuthService.performAuthentication(request, response, pendingReq);
- }
-
- /**
- * PreProcess Authn request.
- *
- * @param request http request
- * @param pendingReq current pending request
- * @throws Throwable in case of an error
- */
- protected void preProcessAuthRequest(final HttpServletRequest request,
- final PvpSProfilePendingRequest pendingReq)
- throws Throwable {
-
- final PvpSProfileRequest moaRequest = (PvpSProfileRequest) pendingReq.getRequest();
- final SignableXMLObject samlReq = moaRequest.getSamlRequest();
-
- if (!(samlReq instanceof AuthnRequest)) {
- throw new InvalidPvpRequestException("Unsupported request", new Object[] {});
- }
-
- final EntityDescriptor metadata = moaRequest.getEntityMetadata(metadataProvider);
- if (metadata == null) {
- throw new NoMetadataInformationException();
- }
- final SPSSODescriptor spSsoDescriptor = metadata.getSPSSODescriptor(SAMLConstants.SAML20P_NS);
-
- final AuthnRequest authnRequest = (AuthnRequest) samlReq;
-
- if (authnRequest.getIssueInstant() == null) {
- log.warn("Unsupported request: No IssueInstant Attribute found.");
- throw new AuthnRequestValidatorException("pvp2.22",
- new Object[] { "Unsupported request: No IssueInstant Attribute found" }, pendingReq);
-
- }
-
- if (authnRequest.getIssueInstant().minusMinutes(EaafConstants.ALLOWED_TIME_JITTER)
- .isAfterNow()) {
- log.warn("Unsupported request: No IssueInstant DateTime is not valid anymore.");
- throw new AuthnRequestValidatorException("pvp2.22",
- new Object[] { "Unsupported request: No IssueInstant DateTime is not valid anymore." },
- pendingReq);
-
- }
-
- // parse AssertionConsumerService
- AssertionConsumerService consumerService = null;
- if (StringUtils.isNotEmpty(authnRequest.getAssertionConsumerServiceURL())
- && StringUtils.isNotEmpty(authnRequest.getProtocolBinding())) {
- // use AssertionConsumerServiceURL from request
-
- // check requested AssertionConsumingService URL against metadata
- final List<AssertionConsumerService> metadataAssertionServiceList =
- spSsoDescriptor.getAssertionConsumerServices();
- for (final AssertionConsumerService service : metadataAssertionServiceList) {
- if (authnRequest.getProtocolBinding().equals(service.getBinding())
- && authnRequest.getAssertionConsumerServiceURL().equals(service.getLocation())) {
- consumerService = Saml2Utils.createSamlObject(AssertionConsumerService.class);
- consumerService.setBinding(authnRequest.getProtocolBinding());
- consumerService.setLocation(authnRequest.getAssertionConsumerServiceURL());
- log.debug("Requested AssertionConsumerServiceURL is valid.");
- }
- }
-
- if (consumerService == null) {
- throw new InvalidAssertionConsumerServiceException(
- authnRequest.getAssertionConsumerServiceURL());
-
- }
-
- } else {
- // use AssertionConsumerServiceIndex and select consumerService from metadata
- final Integer aIdx = authnRequest.getAssertionConsumerServiceIndex();
- int assertionidx = 0;
-
- if (aIdx != null) {
- assertionidx = aIdx;
-
- } else {
- assertionidx = Saml2Utils.getDefaultAssertionConsumerServiceIndex(spSsoDescriptor);
-
- }
- consumerService = spSsoDescriptor.getAssertionConsumerServices().get(assertionidx);
-
- if (consumerService == null) {
- throw new InvalidAssertionConsumerServiceException(aIdx);
-
- }
- }
-
- // validate AuthnRequest
- final AuthnRequest authReq = (AuthnRequest) samlReq;
- final String oaUrl = moaRequest.getEntityMetadata(metadataProvider).getEntityID();
- log.info(
- "Dispatch PVP2 AuthnRequest: OAURL=" + oaUrl + " Binding=" + consumerService.getBinding());
-
- pendingReq.setSpEntityId(StringEscapeUtils.escapeHtml(oaUrl));
- pendingReq.setOnlineApplicationConfiguration(
- authConfig.getServiceProviderConfiguration(pendingReq.getSpEntityId()));
- pendingReq.setBinding(consumerService.getBinding());
- pendingReq.setRequest(moaRequest);
- pendingReq.setConsumerUrl(consumerService.getLocation());
-
- // parse AuthRequest
- pendingReq.setPassiv(authReq.isPassive());
- pendingReq.setForce(authReq.isForceAuthn());
-
- // AuthnRequest needs authentication
- pendingReq.setNeedAuthentication(true);
-
- // set protocol action, which should be executed after authentication
- pendingReq.setAction(AuthenticationAction.class.getName());
-
- // do post-processing if required
+import at.gv.egiz.eaaf.modules.pvp2.impl.verification.SAMLVerificationEngine;
+
+public abstract class AbstractPVP2XProtocol extends AbstractController implements IModulInfo {
+ private static final Logger log = LoggerFactory.getLogger(AbstractPVP2XProtocol.class);
+
+ @Autowired(required=true) protected IPVP2BasicConfiguration pvpBasicConfiguration;
+ @Autowired(required=true) protected IPVPMetadataProvider metadataProvider;
+ @Autowired(required=true) protected SAMLVerificationEngine samlVerificationEngine;
+ @Autowired(required=false) protected List<IAuthnRequestPostProcessor> authRequestPostProcessors;
+
+ private AbstractCredentialProvider pvpIDPCredentials;
+
+
+
+ /**
+ * Sets a specific credential provider for PVP S-Profile IDP component.
+ * @param pvpIDPCredentials credential provider
+ */
+ public void setPvpIDPCredentials(AbstractCredentialProvider pvpIDPCredentials) {
+ this.pvpIDPCredentials = pvpIDPCredentials;
+
+ }
+
+ public boolean generateErrorMessage(Throwable e,
+ HttpServletRequest request, HttpServletResponse response,
+ IRequest protocolRequest) throws Throwable {
+
+ if(protocolRequest == null) {
+ throw e;
+ }
+
+ if(!(protocolRequest instanceof PVPSProfilePendingRequest) ) {
+ throw e;
+ }
+ PVPSProfilePendingRequest pvpRequest = (PVPSProfilePendingRequest)protocolRequest;
+
+ Response samlResponse =
+ SAML2Utils.createSAMLObject(Response.class);
+ Status status = SAML2Utils.createSAMLObject(Status.class);
+ StatusCode statusCode = SAML2Utils.createSAMLObject(StatusCode.class);
+ StatusMessage statusMessage = SAML2Utils.createSAMLObject(StatusMessage.class);
+
+ String moaError = null;
+
+ if(e instanceof NoPassivAuthenticationException) {
+ statusCode.setValue(StatusCode.NO_PASSIVE_URI);
+ statusMessage.setMessage(StringEscapeUtils.escapeXml(e.getLocalizedMessage()));
+
+ } else if (e instanceof NameIDFormatNotSupportedException) {
+ statusCode.setValue(StatusCode.INVALID_NAMEID_POLICY_URI);
+ statusMessage.setMessage(StringEscapeUtils.escapeXml(e.getLocalizedMessage()));
+
+ } else if (e instanceof SLOException) {
+ //SLOExecpetions only occurs if session information is lost
+ return false;
+
+ } else if(e instanceof PVP2Exception) {
+ PVP2Exception ex = (PVP2Exception) e;
+ statusCode.setValue(ex.getStatusCodeValue());
+ String statusMessageValue = ex.getStatusMessageValue();
+ if(statusMessageValue != null) {
+ statusMessage.setMessage(StringEscapeUtils.escapeXml(statusMessageValue));
+ }
+ moaError = statusMessager.mapInternalErrorToExternalError(ex.getErrorId());
+
+ } else {
+ statusCode.setValue(StatusCode.RESPONDER_URI);
+ statusMessage.setMessage(StringEscapeUtils.escapeXml(e.getLocalizedMessage()));
+ moaError = statusMessager.getResponseErrorCode(e);
+ }
+
+
+ if (StringUtils.isNotEmpty(moaError)) {
+ StatusCode moaStatusCode = SAML2Utils.createSAMLObject(StatusCode.class);
+ moaStatusCode.setValue(moaError);
+ statusCode.setStatusCode(moaStatusCode);
+ }
+
+ status.setStatusCode(statusCode);
+ if(statusMessage.getMessage() != null) {
+ status.setStatusMessage(statusMessage);
+ }
+ samlResponse.setStatus(status);
+ String remoteSessionID = SAML2Utils.getSecureIdentifier();
+ samlResponse.setID(remoteSessionID);
+
+ samlResponse.setIssueInstant(new DateTime());
+ Issuer nissuer = SAML2Utils.createSAMLObject(Issuer.class);
+ nissuer.setValue(pvpBasicConfiguration.getIDPEntityId(pvpRequest.getAuthURL()));
+ nissuer.setFormat(NameID.ENTITY);
+ samlResponse.setIssuer(nissuer);
+
+ IEncoder encoder = null;
+
+ if(pvpRequest.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)) {
+ encoder = applicationContext.getBean("PVPRedirectBinding", RedirectBinding.class);
+
+ } else if(pvpRequest.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) {
+ encoder = applicationContext.getBean("PVPPOSTBinding", PostBinding.class);
+
+ } else if (pvpRequest.getBinding().equals(SAMLConstants.SAML2_SOAP11_BINDING_URI)) {
+ encoder = applicationContext.getBean("PVPSOAPBinding", SoapBinding.class);
+ }
+
+ if(encoder == null) {
+ // default to redirect binding
+ encoder = new RedirectBinding();
+ }
+
+ String relayState = null;
+ if (pvpRequest.getRequest() != null)
+ relayState = pvpRequest.getRequest().getRelayState();
+
+ X509Credential signCred = pvpIDPCredentials.getIDPAssertionSigningCredential();
+
+ encoder.encodeRespone(request, response, samlResponse, pvpRequest.getConsumerURL(),
+ relayState, signCred, protocolRequest);
+ return true;
+ }
+
+ public boolean validate(HttpServletRequest request,
+ HttpServletResponse response, IRequest pending) {
+
+ return true;
+ }
+
+ protected void pvpMetadataRequest(HttpServletRequest req, HttpServletResponse resp) throws EAAFException {
+ //create pendingRequest object
+ PVPSProfilePendingRequest pendingReq = applicationContext.getBean(PVPSProfilePendingRequest.class);
+ pendingReq.initialize(req, authConfig);
+ pendingReq.setModule(getName());
+
+ revisionsLogger.logEvent(
+ pendingReq.getUniqueSessionIdentifier(),
+ pendingReq.getUniqueTransactionIdentifier(),
+ EventConstants.TRANSACTION_IP,
+ req.getRemoteAddr());
+
+ MetadataAction metadataAction = applicationContext.getBean(MetadataAction.class);
+ metadataAction.processRequest(pendingReq,
+ req, resp, null);
+
+ }
+
+ protected void PVPIDPPostRequest(HttpServletRequest req, HttpServletResponse resp) throws EAAFException {
+ PVPSProfilePendingRequest pendingReq = null;
+
+ try {
+ //create pendingRequest object
+ pendingReq = applicationContext.getBean(PVPSProfilePendingRequest.class);
+ pendingReq.initialize(req, authConfig);
+ pendingReq.setModule(getName());
+
+ revisionsLogger.logEvent(EventConstants.SESSION_CREATED, pendingReq.getUniqueSessionIdentifier());
+ revisionsLogger.logEvent(EventConstants.TRANSACTION_CREATED, pendingReq.getUniqueTransactionIdentifier());
+ revisionsLogger.logEvent(
+ pendingReq.getUniqueSessionIdentifier(),
+ pendingReq.getUniqueTransactionIdentifier(),
+ EventConstants.TRANSACTION_IP,
+ req.getRemoteAddr());
+
+ //get POST-Binding decoder implementation
+ InboundMessage msg = (InboundMessage) new PostBinding().decode(
+ req, resp, metadataProvider, false,
+ new EAAFURICompare(pvpBasicConfiguration.getIDPSSOPostService(pendingReq.getAuthURL())));
+ pendingReq.setRequest(msg);
+
+ //preProcess Message
+ preProcess(req, resp, pendingReq);
+
+ } catch (SecurityPolicyException e) {
+ String samlRequest = req.getParameter("SAMLRequest");
+ log.warn("Receive INVALID protocol request: " + samlRequest, e);
+
+ //write revision log entries
+ if (pendingReq != null)
+ revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier());
+
+ throw new InvalidProtocolRequestException("pvp2.21", new Object[] {});
+
+ } catch (SecurityException e) {
+ String samlRequest = req.getParameter("SAMLRequest");
+ log.warn("Receive INVALID protocol request: " + samlRequest, e);
+
+ //write revision log entries
+ if (pendingReq != null)
+ revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier());
+
+ throw new InvalidProtocolRequestException("pvp2.22", new Object[] {e.getMessage()});
+
+ } catch (EAAFException e) {
+
+ //write revision log entries
+ if (pendingReq != null)
+ revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier());
+
+ throw e;
+
+ } catch (Throwable e) {
+ String samlRequest = req.getParameter("SAMLRequest");
+ log.warn("Receive INVALID protocol request: " + samlRequest, e);
+
+ //write revision log entries
+ if (pendingReq != null)
+ revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier());
+
+ throw new EAAFException("pvp2.24", new Object[] {e.getMessage()}, e);
+ }
+ }
+
+ protected void PVPIDPRedirecttRequest(HttpServletRequest req, HttpServletResponse resp) throws EAAFException {
+ PVPSProfilePendingRequest pendingReq = null;
+ try {
+ //create pendingRequest object
+ pendingReq = applicationContext.getBean(PVPSProfilePendingRequest.class);
+ pendingReq.initialize(req, authConfig);
+ pendingReq.setModule(getName());
+
+ revisionsLogger.logEvent(EventConstants.SESSION_CREATED, pendingReq.getUniqueSessionIdentifier());
+ revisionsLogger.logEvent(EventConstants.TRANSACTION_CREATED, pendingReq.getUniqueTransactionIdentifier());
+ revisionsLogger.logEvent(
+ pendingReq.getUniqueSessionIdentifier(),
+ pendingReq.getUniqueTransactionIdentifier(),
+ EventConstants.TRANSACTION_IP,
+ req.getRemoteAddr());
+
+ //get POST-Binding decoder implementation
+ InboundMessage msg = (InboundMessage) new RedirectBinding().decode(
+ req, resp, metadataProvider, false,
+ new EAAFURICompare(pvpBasicConfiguration.getIDPSSORedirectService(pendingReq.getAuthURL())));
+ pendingReq.setRequest(msg);
+
+ //preProcess Message
+ preProcess(req, resp, pendingReq);
+
+ } catch (SecurityPolicyException e) {
+ String samlRequest = req.getParameter("SAMLRequest");
+ log.warn("Receive INVALID protocol request: " + samlRequest, e);
+
+ //write revision log entries
+ if (pendingReq != null)
+ revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier());
+
+ throw new InvalidProtocolRequestException("pvp2.21", new Object[] {});
+
+ } catch (SecurityException e) {
+ String samlRequest = req.getParameter("SAMLRequest");
+ log.warn("Receive INVALID protocol request: " + samlRequest, e);
+
+ //write revision log entries
+ if (pendingReq != null)
+ revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier());
+
+ throw new InvalidProtocolRequestException("pvp2.22", new Object[] {e.getMessage()});
+
+ } catch (EAAFException e) {
+ String samlRequest = req.getParameter("SAMLRequest");
+ log.info("Receive INVALID protocol request: " + samlRequest);
+
+ //write revision log entries
+ if (pendingReq != null)
+ revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier());
+
+ throw e;
+
+ } catch (Throwable e) {
+ String samlRequest = req.getParameter("SAMLRequest");
+ log.warn("Receive INVALID protocol request: " + samlRequest, e);
+
+ //write revision log entries
+ if (pendingReq != null)
+ revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier());
+
+ throw new EAAFException("pvp2.24", new Object[] {e.getMessage()}, e);
+ }
+ }
+
+
+
+ /**
+ *
+ *
+ * @param request
+ * @param response
+ * @param msg
+ * @return true if preprocess can handle this request type, otherwise false
+ * @throws Throwable
+ */
+ abstract protected boolean childPreProcess(HttpServletRequest request,
+ HttpServletResponse response, PVPSProfilePendingRequest pendingReq) throws Throwable;
+
+ protected void preProcess(HttpServletRequest request,
+ HttpServletResponse response, PVPSProfilePendingRequest pendingReq) throws Throwable {
+
+ InboundMessage msg = pendingReq.getRequest();
+
+ if (StringUtils.isEmpty(msg.getEntityID())) {
+ throw new InvalidProtocolRequestException("pvp2.20", new Object[] {});
+
+ }
+
+ if(!msg.isVerified()) {
+ samlVerificationEngine.verify(msg,
+ TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider));
+ msg.setVerified(true);
+
+ }
+
+ revisionsLogger.logEvent(pendingReq, IRevisionLogger.AUTHPROTOCOL_TYPE, getAuthProtocolIdentifier());
+
+ if (msg instanceof PVPSProfileRequest &&
+ ((PVPSProfileRequest)msg).getSamlRequest() instanceof AuthnRequest)
+ preProcessAuthRequest(request, response, pendingReq);
+
+ else if (childPreProcess(request, response, pendingReq))
+ log.debug("Find protocol handler in child implementation");
+
+ else {
+ log.error("Receive unsupported PVP21 message of type: " + ((PVPSProfileRequest)msg).getSamlRequest().getClass().getName());
+ throw new InvalidPVPRequestException("pvp2.09",
+ new Object[] {((PVPSProfileRequest)msg).getSamlRequest().getClass().getName()});
+ }
+
+
+
+ //switch to session authentication
+ protAuthService.performAuthentication(request, response, pendingReq);
+ }
+
+
+ /**
+ * PreProcess Authn request
+ * @param request
+ * @param response
+ * @param pendingReq
+ * @throws Throwable
+ */
+ private void preProcessAuthRequest(HttpServletRequest request,
+ HttpServletResponse response, PVPSProfilePendingRequest pendingReq) throws Throwable {
+
+ PVPSProfileRequest moaRequest = ((PVPSProfileRequest)pendingReq.getRequest());
+ SignableXMLObject samlReq = moaRequest.getSamlRequest();
+
+ if(!(samlReq instanceof AuthnRequest)) {
+ throw new InvalidPVPRequestException("Unsupported request", new Object[] {});
+ }
+
+ EntityDescriptor metadata = moaRequest.getEntityMetadata(metadataProvider);
+ if(metadata == null) {
+ throw new NoMetadataInformationException();
+ }
+ SPSSODescriptor spSSODescriptor = metadata.getSPSSODescriptor(SAMLConstants.SAML20P_NS);
+
+ AuthnRequest authnRequest = (AuthnRequest)samlReq;
+
+ if (authnRequest.getIssueInstant() == null) {
+ log.warn("Unsupported request: No IssueInstant Attribute found.");
+ throw new AuthnRequestValidatorException("pvp2.22",
+ new Object[] {"Unsupported request: No IssueInstant Attribute found"},
+ pendingReq);
+
+ }
+
+ if (authnRequest.getIssueInstant().minusMinutes(EAAFConstants.ALLOWED_TIME_JITTER).isAfterNow()) {
+ log.warn("Unsupported request: No IssueInstant DateTime is not valid anymore.");
+ throw new AuthnRequestValidatorException("pvp2.22",
+ new Object[] {"Unsupported request: No IssueInstant DateTime is not valid anymore."},
+ pendingReq);
+
+ }
+
+ //parse AssertionConsumerService
+ AssertionConsumerService consumerService = null;
+ if (StringUtils.isNotEmpty(authnRequest.getAssertionConsumerServiceURL()) &&
+ StringUtils.isNotEmpty(authnRequest.getProtocolBinding())) {
+ //use AssertionConsumerServiceURL from request
+
+ //check requested AssertionConsumingService URL against metadata
+ List<AssertionConsumerService> metadataAssertionServiceList = spSSODescriptor.getAssertionConsumerServices();
+ for (AssertionConsumerService service : metadataAssertionServiceList) {
+ if (authnRequest.getProtocolBinding().equals(service.getBinding())
+ && authnRequest.getAssertionConsumerServiceURL().equals(service.getLocation())) {
+ consumerService = SAML2Utils.createSAMLObject(AssertionConsumerService.class);
+ consumerService.setBinding(authnRequest.getProtocolBinding());
+ consumerService.setLocation(authnRequest.getAssertionConsumerServiceURL());
+ log.debug("Requested AssertionConsumerServiceURL is valid.");
+ }
+ }
+
+ if (consumerService == null) {
+ throw new InvalidAssertionConsumerServiceException(authnRequest.getAssertionConsumerServiceURL());
+
+ }
+
+
+ } else {
+ //use AssertionConsumerServiceIndex and select consumerService from metadata
+ Integer aIdx = authnRequest.getAssertionConsumerServiceIndex();
+ int assertionidx = 0;
+
+ if(aIdx != null) {
+ assertionidx = aIdx.intValue();
+
+ } else {
+ assertionidx = SAML2Utils.getDefaultAssertionConsumerServiceIndex(spSSODescriptor);
+
+ }
+ consumerService = spSSODescriptor.getAssertionConsumerServices().get(assertionidx);
+
+ if (consumerService == null) {
+ throw new InvalidAssertionConsumerServiceException(aIdx);
+
+ }
+ }
+
+
+ //validate AuthnRequest
+ AuthnRequest authReq = (AuthnRequest) samlReq;
+ String oaURL = moaRequest.getEntityMetadata(metadataProvider).getEntityID();
+ log.info("Dispatch PVP2 AuthnRequest: OAURL=" + oaURL + " Binding=" + consumerService.getBinding());
+
+ pendingReq.setSPEntityId(StringEscapeUtils.escapeHtml(oaURL));
+ pendingReq.setOnlineApplicationConfiguration(authConfig.getServiceProviderConfiguration(pendingReq.getSPEntityId()));
+ pendingReq.setBinding(consumerService.getBinding());
+ pendingReq.setRequest(moaRequest);
+ pendingReq.setConsumerURL(consumerService.getLocation());
+
+ //parse AuthRequest
+ pendingReq.setPassiv(authReq.isPassive());
+ pendingReq.setForce(authReq.isForceAuthn());
+
+ //AuthnRequest needs authentication
+ pendingReq.setNeedAuthentication(true);
+
+ //set protocol action, which should be executed after authentication
+ pendingReq.setAction(AuthenticationAction.class.getName());
+
+ // do post-processing if required
log.trace("Starting extended AuthnRequest validation and processing ... ");
if (authRequestPostProcessors != null) {
for (final IAuthnRequestPostProcessor processor : authRequestPostProcessors) {
log.trace("Post-process AuthnRequest with module: {}", processor.getClass().getSimpleName());
- processor.process(request, pendingReq, authReq, spSsoDescriptor);
+ processor.process(request, pendingReq, authReq, spSSODescriptor);
}
}
-
- log.debug("Extended AuthnRequest validation and processing finished");
-
- // write revisionslog entry
- revisionsLogger.logEvent(pendingReq, PvpEventConstants.AUTHPROTOCOL_PVP_REQUEST_AUTHREQUEST,
- authReq.getID());
-
- }
-
- @PostConstruct
- private void verifyInitialization() {
- if (pvpIdpCredentials == null) {
- log.error("No SAML2 credentialProvider injected!");
- throw new RuntimeException("No SAML2 credentialProvider injected!");
-
- }
- }
-
+
+ log.debug("Extended AuthnRequest validation and processing finished");
+
+ //write revisionslog entry
+ revisionsLogger.logEvent(pendingReq, PVPEventConstants.AUTHPROTOCOL_PVP_REQUEST_AUTHREQUEST, authReq.getID());
+
+ }
+
+ @PostConstruct
+ private void verifyInitialization() {
+ if (pvpIDPCredentials == null) {
+ log.error("No SAML2 credentialProvider injected!");
+ throw new RuntimeException("No SAML2 credentialProvider injected!");
+
+ }
+ }
+
}