diff options
| author | Thomas Lenz <thomas.lenz@egiz.gv.at> | 2019-12-12 14:52:41 +0100 | 
|---|---|---|
| committer | Thomas Lenz <thomas.lenz@egiz.gv.at> | 2020-02-28 10:40:00 +0100 | 
| commit | 68b3ee5b9f1f0f3b3e2312ce94132132d15761de (patch) | |
| tree | b673b9cff545510112a6527e8e8e0c8a985b178d | |
| parent | 31d3d82044bf71bfa343460eb03bf05e071ee3c8 (diff) | |
| download | EAAF-Components-68b3ee5b9f1f0f3b3e2312ce94132132d15761de.tar.gz EAAF-Components-68b3ee5b9f1f0f3b3e2312ce94132132d15761de.tar.bz2 EAAF-Components-68b3ee5b9f1f0f3b3e2312ce94132132d15761de.zip | |
back-port of PVP IDP-module request post-processor
| -rw-r--r-- | eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AbstractPVP2XProtocol.java | 549 | 
1 files changed, 549 insertions, 0 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 new file mode 100644 index 00000000..597d3c22 --- /dev/null +++ b/eaaf_modules/eaaf_module_pvp2_idp/src/main/java/at/gv/egiz/eaaf/modules/pvp2/idp/impl/AbstractPVP2XProtocol.java @@ -0,0 +1,549 @@ +/******************************************************************************* + * 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.idp.impl; + +import java.util.List; + +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.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.InvalidProtocolRequestException; +import at.gv.egiz.eaaf.core.exceptions.NoPassivAuthenticationException; +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.api.binding.IEncoder; +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.NoMetadataInformationException; +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.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; +  +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); + +      } +    } +     +		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!"); +			 +		}		 +	} +	 +} | 
