diff options
| author | Thomas Lenz <tlenz@iaik.tugraz.at> | 2018-06-20 15:32:44 +0200 | 
|---|---|---|
| committer | Thomas Lenz <tlenz@iaik.tugraz.at> | 2018-06-20 15:32:44 +0200 | 
| commit | 016663e3a46f5f41f4d621c19e49063c78ccca70 (patch) | |
| tree | 4da66229fb91f8f1d0ca0f2329082aaee1ffeeb2 | |
| parent | 139926faa31ae3ed34dc0083fee503d439112281 (diff) | |
| download | moa-id-spss-016663e3a46f5f41f4d621c19e49063c78ccca70.tar.gz moa-id-spss-016663e3a46f5f41f4d621c19e49063c78ccca70.tar.bz2 moa-id-spss-016663e3a46f5f41f4d621c19e49063c78ccca70.zip | |
add some missing files
3 files changed, 451 insertions, 1 deletions
| diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java new file mode 100644 index 000000000..a59033177 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java @@ -0,0 +1,396 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 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: + * http://www.osor.eu/eupl/ + * + * 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.egovernment.moa.id.protocols.pvp2x; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Arrays; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang.StringEscapeUtils; +import org.opensaml.common.xml.SAMLConstants; +import org.opensaml.saml2.core.AttributeQuery; +import org.opensaml.saml2.core.LogoutRequest; +import org.opensaml.saml2.core.LogoutResponse; +import org.opensaml.saml2.metadata.EntityDescriptor; +import org.opensaml.ws.security.SecurityPolicyException; +import org.opensaml.xml.security.SecurityException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration; +import at.gv.egiz.eaaf.core.exceptions.EAAFException; +import at.gv.egiz.eaaf.core.exceptions.InvalidProtocolRequestException; +import at.gv.egiz.eaaf.core.exceptions.ProtocolNotActiveException; +import at.gv.egiz.eaaf.core.impl.gui.velocity.VelocityLogAdapter; +import at.gv.egiz.eaaf.core.impl.utils.HTTPUtils; +import at.gv.egiz.eaaf.modules.pvp2.exception.AttributQueryException; +import at.gv.egiz.eaaf.modules.pvp2.exception.NoMetadataInformationException; +import at.gv.egiz.eaaf.modules.pvp2.idp.impl.AbstractPVP2XProtocol; +import at.gv.egiz.eaaf.modules.pvp2.idp.impl.PVPSProfilePendingRequest; +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.message.PVPSProfileResponse; +import at.gv.egiz.eaaf.modules.pvp2.impl.validation.EAAFURICompare; +import at.gv.egiz.eaaf.modules.pvp2.sp.exception.AssertionValidationExeption; +import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; +import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; +import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters; +import at.gv.egovernment.moa.id.commons.api.data.IAuthenticationSession; +import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; +import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration; +import at.gv.egovernment.moa.id.storage.IAuthenticationSessionStoreage; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.MiscUtil; +  +@Controller +public class PVP2XProtocol extends AbstractPVP2XProtocol { + +	@Autowired(required=true) AuthConfiguration moaAuthConfig; +	@Autowired protected IAuthenticationSessionStoreage authenticatedSessionStorage; +	 +	public static final String NAME = PVP2XProtocol.class.getName(); +	public static final String PATH = "id_pvp2-sprofile"; + +	 +	public static final List<String> DEFAULTREQUESTEDATTRFORINTERFEDERATION = Arrays.asList( +			new String[] { +					PVPConstants.EID_SECTOR_FOR_IDENTIFIER_NAME +			}); +	 +	static {			 +		new VelocityLogAdapter(); +		 +	} + +	public String getName() { +		return NAME; +	} + +	public String getAuthProtocolIdentifier() { +		return PATH; +	} +	 +	public PVP2XProtocol() { +		super(); +	}  +		 +	//PVP2.x metadata end-point +	@RequestMapping(value = PVPConfiguration.PVP2_METADATA, method = {RequestMethod.POST, RequestMethod.GET}) +	public void PVPMetadataRequest(HttpServletRequest req, HttpServletResponse resp) throws EAAFException { +		if (!moaAuthConfig.getAllowedProtocols().isPVP21Active()) { +			Logger.info("PVP2.1 is deaktivated!"); +			throw new ProtocolNotActiveException("auth.22", new java.lang.Object[] { NAME }, "PVP2.1 is deaktivated!"); +			 +		} +		 +		super.pvpMetadataRequest(req, resp); +		 +	} +	 +	//PVP2.x IDP POST-Binding end-point +	@RequestMapping(value = PVPConfiguration.PVP2_IDP_POST, method = {RequestMethod.POST}) +	public void PVPIDPPostRequest(HttpServletRequest req, HttpServletResponse resp) throws EAAFException { +		if (!moaAuthConfig.getAllowedProtocols().isPVP21Active()) { +			Logger.info("PVP2.1 is deaktivated!"); +			throw new ProtocolNotActiveException("auth.22", new java.lang.Object[] { NAME }, "PVP2.1 is deaktivated!"); +			 +		} +		 +		super.PVPIDPPostRequest(req, resp); +						 +	} +	 +	//PVP2.x IDP Redirect-Binding end-point +	@RequestMapping(value = PVPConfiguration.PVP2_IDP_REDIRECT, method = {RequestMethod.GET}) +	public void PVPIDPRedirecttRequest(HttpServletRequest req, HttpServletResponse resp) throws EAAFException { +		if (!AuthConfigurationProviderFactory.getInstance().getAllowedProtocols().isPVP21Active()) { +			Logger.info("PVP2.1 is deaktivated!"); +			throw new ProtocolNotActiveException("auth.22", new java.lang.Object[] { NAME }, "PVP2.1 is deaktivated!"); +			 +		} +		 +		super.PVPIDPRedirecttRequest(req, resp); +				 +	} +	 +	 +	//PVP2.x IDP SOAP-Binding end-point +	@RequestMapping(value = "/pvp2/soap", method = {RequestMethod.POST}) +	public void PVPIDPSOAPRequest(HttpServletRequest req, HttpServletResponse resp) throws EAAFException { +//		if (!authConfig.getAllowedProtocols().isPVP21Active()) { +//			Logger.info("PVP2.1 is deaktivated!"); +//			throw new ProtocolNotActiveException("auth.22", new java.lang.Object[] { NAME }, "PVP2.1 is deaktivated!"); +//			 +//		} +				 +		PVPSProfilePendingRequest pendingReq = null; +		try { +			//create pendingRequest object +			pendingReq = applicationContext.getBean(PVPSProfilePendingRequest.class); +			pendingReq.initialize(req, authConfig); +			pendingReq.setModule(NAME); +			 +			revisionsLogger.logEvent(MOAIDEventConstants.SESSION_CREATED, pendingReq.getUniqueSessionIdentifier()); +			revisionsLogger.logEvent(MOAIDEventConstants.TRANSACTION_CREATED, pendingReq.getUniqueTransactionIdentifier());						 +			revisionsLogger.logEvent( +					pendingReq.getUniqueSessionIdentifier(),  +					pendingReq.getUniqueTransactionIdentifier(),  +					MOAIDEventConstants.TRANSACTION_IP,  +					req.getRemoteAddr()); +			 +			//get POST-Binding decoder implementation +			InboundMessage msg = (InboundMessage) new SoapBinding().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");			 +			Logger.warn("Receive INVALID protocol request: " + samlRequest, e); +						 +			//write revision log entries +			if (pendingReq != null) +				revisionsLogger.logEvent(pendingReq, MOAIDEventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier()); +			 +			throw new InvalidProtocolRequestException("pvp2.21", new Object[] {}, e.getMessage()); +			 +		} catch (SecurityException e) { +			String samlRequest = req.getParameter("SAMLRequest");			 +			Logger.warn("Receive INVALID protocol request: " + samlRequest, e); +			 +			//write revision log entries +			if (pendingReq != null) +				revisionsLogger.logEvent(pendingReq, MOAIDEventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier()); +			 +			throw new InvalidProtocolRequestException("pvp2.22", new Object[] {e.getMessage()}, e.getMessage()); +		 +		} catch (MOAIDException e) {			 +			//write revision log entries +			if (pendingReq != null) +				revisionsLogger.logEvent(pendingReq, MOAIDEventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier()); +			 +			throw e; +						 +		} catch (Throwable e) {			 +			String samlRequest = req.getParameter("SAMLRequest");			 +			Logger.warn("Receive INVALID protocol request: " + samlRequest, e); +			 +			//write revision log entries +			if (pendingReq != null) +				revisionsLogger.logEvent(pendingReq, MOAIDEventConstants.TRANSACTION_ERROR, pendingReq.getUniqueTransactionIdentifier()); +			 +			throw new MOAIDException("pvp2.24", new Object[] {e.getMessage()}); +		}					 +	} +	 +	 +	protected boolean childPreProcess(HttpServletRequest request, +			HttpServletResponse response, PVPSProfilePendingRequest pendingReq) throws Throwable {				 +		InboundMessage msg = pendingReq.getRequest(); +		if (msg instanceof PVPSProfileRequest &&  +				((PVPSProfileRequest)msg).getSamlRequest() instanceof AttributeQuery) +			preProcessAttributQueryRequest(request, response, pendingReq); + +		else if (msg instanceof PVPSProfileRequest &&  +				((PVPSProfileRequest)msg).getSamlRequest() instanceof LogoutRequest) +			preProcessLogOut(request, response, pendingReq); +			 +		else if (msg instanceof PVPSProfileResponse &&  +				((PVPSProfileResponse)msg).getResponse() instanceof LogoutResponse) +			preProcessLogOut(request, response, pendingReq); +			 +		else  +			return false; +			 +			 +		return true; +	} +	 +	/** +	 * PreProcess Single LogOut request +	 * @param request +	 * @param response +	 * @param msg +	 * @return +	 * @throws EAAFException  +	 * @throws MOAIDException  +	 */ +	private void preProcessLogOut(HttpServletRequest request, +			HttpServletResponse response, PVPSProfilePendingRequest pendingReq) throws EAAFException { + +		InboundMessage inMsg = pendingReq.getRequest();		 +		PVPSProfileRequest msg; +		if (inMsg instanceof PVPSProfileRequest &&  +				((PVPSProfileRequest)inMsg).getSamlRequest() instanceof LogoutRequest) { +			//preProcess single logout request from service provider +			 +			msg = (PVPSProfileRequest) inMsg; +			 +			EntityDescriptor metadata = msg.getEntityMetadata(metadataProvider); +			if(metadata == null) { +				throw new NoMetadataInformationException(); +			} + +			String oaURL = metadata.getEntityID(); +			oaURL = StringEscapeUtils.escapeHtml(oaURL); +			ISPConfiguration oa = authConfig.getServiceProviderConfiguration(oaURL); +			 +			Logger.info("Dispatch PVP2 SingleLogOut: OAURL=" + oaURL + " Binding=" + msg.getRequestBinding()); +						 +			pendingReq.setSPEntityId(oaURL); +			pendingReq.setOnlineApplicationConfiguration(oa); +			pendingReq.setBinding(msg.getRequestBinding()); +			 +			revisionsLogger.logEvent(pendingReq, MOAIDEventConstants.AUTHPROTOCOL_PVP_REQUEST_SLO); +			 + +						 +		} else if (inMsg instanceof PVPSProfileResponse &&  +				((PVPSProfileResponse)inMsg).getResponse() instanceof LogoutResponse) { +			//preProcess single logour response from service provider +						 +			LogoutResponse resp = (LogoutResponse) (((PVPSProfileResponse)inMsg).getResponse()); +			 +			Logger.debug("PreProcess SLO Response from " + resp.getIssuer()); +			 +//			List<String> allowedPublicURLPrefix = authConfig.getIDPPublicURLPrefixes(); +//					AuthConfigurationProviderFactory.getInstance().getPublicURLPrefix(); +			 +			boolean isAllowedDestination = false;			 +			try { +				isAllowedDestination = MiscUtil.isNotEmpty(authConfig.validateIDPURL(new URL(resp.getDestination()))); +				 +			} catch (MalformedURLException e) { +				Logger.info(resp.getDestination() + " is NOT valid. Reason: " + e.getMessage()); +				 +			} +			 +//			for (String prefix : allowedPublicURLPrefix) { +//				if (resp.getDestination().startsWith( +//					prefix)) { +//					isAllowedDestination = true; +//					break; +//				} +//			} +						 +			if (!isAllowedDestination) { +				Logger.warn("PVP 2.1 single logout response destination does not match to IDP URL"); +				throw new AssertionValidationExeption("PVP 2.1 single logout response destination does not match to IDP URL", null); +				 +			} +			 +			//TODO: check if relayState exists +			inMsg.getRelayState(); +						 +						 +		} else  +			throw new EAAFException("Unsupported request"); +		 +		 +		pendingReq.setRequest(inMsg); +		pendingReq.setAction(PVPConstants.SINGLELOGOUT); +		 +		//Single LogOut Request needs no authentication  +		pendingReq.setNeedAuthentication(false); +		 +		//set protocol action, which should be executed +		pendingReq.setAction(SingleLogOutAction.class.getName()); +	} +	 +	/** +	 * PreProcess AttributeQuery request  +	 * @param request +	 * @param response +	 * @param pendingReq +	 * @throws Throwable +	 */ +	private void preProcessAttributQueryRequest(HttpServletRequest request, +			HttpServletResponse response, PVPSProfilePendingRequest pendingReq) throws Throwable { +		PVPSProfileRequest moaRequest = ((PVPSProfileRequest)pendingReq.getRequest()); +		AttributeQuery attrQuery = (AttributeQuery) moaRequest.getSamlRequest(); +		moaRequest.setEntityID(attrQuery.getIssuer().getValue()); +		 +		//validate destination +		String destinaten = attrQuery.getDestination(); +		if (!pvpBasicConfiguration.getIDPSSOSOAPService(HTTPUtils.extractAuthURLFromRequest(request)).equals(destinaten)) { +			Logger.warn("AttributeQuery destination does not match IDP AttributeQueryService URL"); +			throw new AttributQueryException("AttributeQuery destination does not match IDP AttributeQueryService URL", null); +			 +		} + +		//check if Issuer is an interfederation IDP		 +		IOAAuthParameters oa = authConfig.getServiceProviderConfiguration(moaRequest.getEntityID(), IOAAuthParameters.class); +		if (!oa.isInderfederationIDP()) { +			Logger.warn("AttributeQuery requests are only allowed for interfederation IDPs."); +			throw new AttributQueryException("AttributeQuery requests are only allowed for interfederation IDPs.", null); +			 +		} +		 +		if (!oa.isOutboundSSOInterfederationAllowed()) { +			Logger.warn("Interfederation IDP " + oa.getPublicURLPrefix() + " does not allow outgoing SSO interfederation."); +			throw new AttributQueryException("Interfederation IDP does not allow outgoing SSO interfederation.", null); +			 +		} +					 +		//check active MOASession +		String nameID = attrQuery.getSubject().getNameID().getValue();			 +		IAuthenticationSession session = authenticatedSessionStorage.getSessionWithUserNameID(nameID); +		if (session == null) { +			Logger.warn("AttributeQuery nameID does not match to an active single sign-on session."); +			throw new AttributQueryException("auth.31", null); +			 +		} +		 +		//set preProcessed information into pending-request +		pendingReq.setRequest(moaRequest); +		pendingReq.setSPEntityId(moaRequest.getEntityID()); +		pendingReq.setOnlineApplicationConfiguration(oa); +		pendingReq.setBinding(SAMLConstants.SAML2_SOAP11_BINDING_URI); +		 +		//Attribute-Query Request needs authentication, because session MUST be already authenticated  +		pendingReq.setNeedAuthentication(false); +				 +		//set protocol action, which should be executed after authentication +		pendingReq.setAction(AttributQueryAction.class.getName()); + +		//add moasession +		pendingReq.setSSOSessionIdentifier(session.getSSOSessionID()); +				 +		//write revisionslog entry +		revisionsLogger.logEvent(pendingReq, MOAIDEventConstants.AUTHPROTOCOL_PVP_REQUEST_ATTRIBUTQUERY); +		 +		 +	} + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/metadata/PVPMetadataFilterChain.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/metadata/PVPMetadataFilterChain.java new file mode 100644 index 000000000..615a0eaa7 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/metadata/PVPMetadataFilterChain.java @@ -0,0 +1,54 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 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: + * http://www.osor.eu/eupl/ + * + * 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.egovernment.moa.id.protocols.pvp2x.verification.metadata; + +import java.security.cert.CertificateException; + +import at.gv.egiz.eaaf.modules.pvp2.impl.metadata.MetadataFilterChain; + +/** + * @author tlenz + * + */ +public class PVPMetadataFilterChain extends MetadataFilterChain { + +		 +	/** +	 * @throws CertificateException  +	 *  +	 */ +	public PVPMetadataFilterChain(String url, byte[] certificate) throws CertificateException { +		addDefaultFilters(url, certificate); +	} +	 +	public void addDefaultFilters(String url, byte[] certificate) throws CertificateException { +		addFilter(new MetadataSignatureFilter(url, certificate)); +		 +	} + + + + + +	 +} diff --git a/id/server/modules/moa-id-module-bkaMobilaAuthSAML2Test/src/main/java/at/gv/egovernment/moa/id/auth/modules/bkamobileauthtests/tasks/FirstBKAMobileAuthTask.java b/id/server/modules/moa-id-module-bkaMobilaAuthSAML2Test/src/main/java/at/gv/egovernment/moa/id/auth/modules/bkamobileauthtests/tasks/FirstBKAMobileAuthTask.java index 68b944814..76563c8ca 100644 --- a/id/server/modules/moa-id-module-bkaMobilaAuthSAML2Test/src/main/java/at/gv/egovernment/moa/id/auth/modules/bkamobileauthtests/tasks/FirstBKAMobileAuthTask.java +++ b/id/server/modules/moa-id-module-bkaMobilaAuthSAML2Test/src/main/java/at/gv/egovernment/moa/id/auth/modules/bkamobileauthtests/tasks/FirstBKAMobileAuthTask.java @@ -210,7 +210,7 @@ public class FirstBKAMobileAuthTask extends AbstractAuthServletTask {  			moaSession.setUseMandates(false);  			moaSession.setForeigner(false);			  			moaSession.setBkuURL("http://egiz.gv.at/BKA_MobileAuthTest");			 -			moaSession.setQAALevel(PVPConstants.STORK_QAA_1_3); +			moaSession.setQAALevel(PVPConstants.EIDAS_QAA_SUBSTANTIAL);  			Logger.info("Session Restore completed"); | 
