diff options
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java')
-rw-r--r-- | id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java | 190 |
1 files changed, 150 insertions, 40 deletions
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java index 72691a034..e98e1cb78 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java @@ -37,36 +37,53 @@ import org.opensaml.saml2.core.Attribute; import org.opensaml.saml2.core.AttributeQuery; import org.opensaml.saml2.core.Response; import org.opensaml.ws.message.encoder.MessageEncodingException; +import org.opensaml.ws.soap.common.SOAPException; +import org.opensaml.xml.XMLObject; import org.opensaml.xml.security.SecurityException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Service; -import at.gv.egovernment.moa.id.auth.builder.AuthenticationDataBuilder; +import at.gv.egiz.eaaf.core.api.IRequest; +import at.gv.egiz.eaaf.core.api.idp.IAction; +import at.gv.egiz.eaaf.core.api.idp.IAuthData; +import at.gv.egiz.eaaf.core.api.idp.IAuthenticationDataBuilder; +import at.gv.egiz.eaaf.core.api.idp.slo.SLOInformationInterface; +import at.gv.egiz.eaaf.core.exceptions.EAAFAuthenticationException; +import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException; +import at.gv.egiz.eaaf.core.exceptions.EAAFException; +import at.gv.egiz.eaaf.core.impl.data.Trible; +import at.gv.egiz.eaaf.modules.pvp2.api.IPVP2BasicConfiguration; +import at.gv.egiz.eaaf.modules.pvp2.exception.AttributQueryException; +import at.gv.egiz.eaaf.modules.pvp2.idp.impl.PVPSProfilePendingRequest; +import at.gv.egiz.eaaf.modules.pvp2.idp.impl.builder.AuthResponseBuilder; +import at.gv.egiz.eaaf.modules.pvp2.idp.impl.builder.PVP2AssertionBuilder; +import at.gv.egiz.eaaf.modules.pvp2.impl.binding.SoapBinding; +import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PVPAttributeBuilder; +import at.gv.egiz.eaaf.modules.pvp2.impl.message.PVPSProfileRequest; +import at.gv.egiz.eaaf.modules.pvp2.impl.validation.TrustEngineFactory; +import at.gv.egiz.eaaf.modules.pvp2.sp.exception.AssertionAttributeExtractorExeption; +import at.gv.egiz.eaaf.modules.pvp2.sp.exception.AssertionValidationExeption; +import at.gv.egiz.eaaf.modules.pvp2.sp.impl.utils.AssertionAttributeExtractor; import at.gv.egovernment.moa.id.auth.builder.DynamicOAAuthParameterBuilder; import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; +import at.gv.egovernment.moa.id.auth.exception.BuildException; 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.IRequest; +import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; import at.gv.egovernment.moa.id.commons.db.dao.session.InterfederationSessionStore; import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; -import at.gv.egovernment.moa.id.data.IAuthData; -import at.gv.egovernment.moa.id.data.SLOInformationInterface; -import at.gv.egovernment.moa.id.data.Trible; -import at.gv.egovernment.moa.id.moduls.IAction; -import at.gv.egovernment.moa.id.protocols.pvp2x.binding.SoapBinding; -import at.gv.egovernment.moa.id.protocols.pvp2x.builder.AuthResponseBuilder; -import at.gv.egovernment.moa.id.protocols.pvp2x.builder.PVPAttributeBuilder; -import at.gv.egovernment.moa.id.protocols.pvp2x.builder.assertion.PVP2AssertionBuilder; -import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration; -import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOARequest; +import at.gv.egovernment.moa.id.config.auth.OAAuthParameterDecorator; +import at.gv.egovernment.moa.id.data.IMOAAuthData; +import at.gv.egovernment.moa.id.protocols.pvp2x.builder.AttributQueryBuilder; import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider; import at.gv.egovernment.moa.id.protocols.pvp2x.signer.IDPCredentialProvider; -import at.gv.egovernment.moa.id.protocols.pvp2x.utils.AssertionAttributeExtractor; +import at.gv.egovernment.moa.id.protocols.pvp2x.utils.MOASAMLSOAPClient; +import at.gv.egovernment.moa.id.protocols.pvp2x.verification.SAMLVerificationEngineSP; import at.gv.egovernment.moa.id.storage.IAuthenticationSessionStoreage; import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.MiscUtil; /** * @author tlenz @@ -76,12 +93,17 @@ import at.gv.egovernment.moa.logging.Logger; public class AttributQueryAction implements IAction { @Autowired private IAuthenticationSessionStoreage authenticationSessionStorage; - @Autowired private AuthenticationDataBuilder authDataBuilder; + @Autowired private IAuthenticationDataBuilder authDataBuilder; @Autowired private IDPCredentialProvider pvpCredentials; @Autowired private AuthConfiguration authConfig; @Autowired(required=true) private MOAMetadataProvider metadataProvider; @Autowired(required=true) ApplicationContext springContext; + @Autowired private AttributQueryBuilder attributQueryBuilder; + @Autowired private SAMLVerificationEngineSP samlVerificationEngine; + @Autowired(required=true) IPVP2BasicConfiguration pvpBasicConfiguration; + @Autowired(required=true) PVP2AssertionBuilder assertionBuilder; + private final static List<String> DEFAULTSTORKATTRIBUTES = Arrays.asList( new String[]{PVPConstants.EID_STORK_TOKEN_NAME}); @@ -97,11 +119,11 @@ public class AttributQueryAction implements IAction { @Override public SLOInformationInterface processRequest(IRequest pendingReq, HttpServletRequest httpReq, HttpServletResponse httpResp, - IAuthData authData) throws MOAIDException { + IAuthData authData) throws EAAFException { - if (pendingReq instanceof PVPTargetConfiguration && - ((PVPTargetConfiguration) pendingReq).getRequest() instanceof MOARequest && - ((MOARequest)((PVPTargetConfiguration) pendingReq).getRequest()).getSamlRequest() instanceof AttributeQuery) { + if (pendingReq instanceof PVPSProfilePendingRequest && + ((PVPSProfilePendingRequest) pendingReq).getRequest() instanceof PVPSProfileRequest && + ((PVPSProfileRequest)((PVPSProfilePendingRequest) pendingReq).getRequest()).getSamlRequest() instanceof AttributeQuery) { //set time reference DateTime date = new DateTime(); @@ -116,10 +138,10 @@ public class AttributQueryAction implements IAction { } InterfederationSessionStore nextIDPInformation = - authenticationSessionStorage.searchInterfederatedIDPFORAttributeQueryWithSessionID(moaSession.getSessionID()); + authenticationSessionStorage.searchInterfederatedIDPFORAttributeQueryWithSessionID(moaSession.getSSOSessionID()); AttributeQuery attrQuery = - (AttributeQuery)((MOARequest)((PVPTargetConfiguration) pendingReq).getRequest()).getSamlRequest(); + (AttributeQuery)((PVPSProfileRequest)((PVPSProfilePendingRequest) pendingReq).getRequest()).getSamlRequest(); //build PVP 2.1 response-attribute information for this AttributQueryRequest Trible<List<Attribute>, Date, String> responseInfo = @@ -131,10 +153,9 @@ public class AttributQueryAction implements IAction { //build PVP 2.1 assertion - String issuerEntityID = PVPConfiguration.getInstance().getIDPSSOMetadataService( - pendingReq.getAuthURL()); + String issuerEntityID = pvpBasicConfiguration.getIDPEntityId(pendingReq.getAuthURL()); - Assertion assertion = PVP2AssertionBuilder.buildAssertion(issuerEntityID, + Assertion assertion = assertionBuilder.buildAssertion(issuerEntityID, attrQuery, responseInfo.getFirst(), date, new DateTime(responseInfo.getSecond().getTime()), responseInfo.getThird(), authData.getSessionIndex()); @@ -184,39 +205,42 @@ public class AttributQueryAction implements IAction { */ @Override public String getDefaultActionName() { - return PVP2XProtocol.ATTRIBUTEQUERY; + return at.gv.egiz.eaaf.modules.pvp2.PVPConstants.ATTRIBUTEQUERY; } private Trible<List<Attribute>, Date, String> buildResponseInformationForAttributQuery(IRequest pendingReq, - AuthenticationSession session, List<Attribute> reqAttributes, InterfederationSessionStore nextIDPInformation) throws MOAIDException { + AuthenticationSession session, List<Attribute> reqAttributes, InterfederationSessionStore nextIDPInformation) throws MOAIDException, AssertionAttributeExtractorExeption, AttributQueryException, AssertionValidationExeption { try { //mark AttributeQuery as used if it exists - if ( pendingReq instanceof PVPTargetConfiguration && - ((PVPTargetConfiguration) pendingReq).getRequest() instanceof MOARequest && - ((PVPTargetConfiguration) pendingReq).getRequest().getInboundMessage() instanceof AttributeQuery) { + if ( pendingReq instanceof PVPSProfileRequest && + ((PVPSProfilePendingRequest) pendingReq).getRequest() instanceof PVPSProfileRequest && + ((PVPSProfilePendingRequest) pendingReq).getRequest().getInboundMessage() instanceof AttributeQuery) { - authenticationSessionStorage.markOAWithAttributeQueryUsedFlag(session, pendingReq.getOAURL(), pendingReq.requestedModule()); + authenticationSessionStorage.markOAWithAttributeQueryUsedFlag(session, pendingReq.getSPEntityId(), pendingReq.requestedModule()); } //build OnlineApplication dynamic from requested attributes (AttributeQuerry Request) and configuration IOAAuthParameters spConfig = DynamicOAAuthParameterBuilder.buildFromAttributeQuery(reqAttributes); - //search federated IDP information for this MOASession + //search federated IDP information for this MOASession if (nextIDPInformation != null) { Logger.info("Find active federated IDP information." + ". --> Request next IDP:" + nextIDPInformation.getIdpurlprefix() + " for authentication information."); //load configuration of next IDP - IOAAuthParameters idpLoaded = authConfig.getOnlineApplicationParameter(nextIDPInformation.getIdpurlprefix()); - if (idpLoaded == null || !(idpLoaded instanceof OAAuthParameter)) { + IOAAuthParameters idpLoaded = + authConfig.getServiceProviderConfiguration( + nextIDPInformation.getIdpurlprefix(), + OAAuthParameterDecorator.class); + if (idpLoaded == null || !(idpLoaded instanceof IOAAuthParameters)) { Logger.warn("Configuration for federated IDP:" + nextIDPInformation.getIdpurlprefix() + "is not loadable."); throw new MOAIDException("auth.32", new Object[]{nextIDPInformation.getIdpurlprefix()}); } - OAAuthParameter idp = (OAAuthParameter) idpLoaded; + IOAAuthParameters idp = idpLoaded; //check if next IDP config allows inbound messages if (!idp.isInboundSSOInterfederationAllowed()) { @@ -227,7 +251,7 @@ public class AttributQueryAction implements IAction { } //check next IDP service area policy. BusinessService IDPs can only request wbPKs - if (!spConfig.hasBaseIdTransferRestriction() && !idp.isIDPPublicService()) { + if (!spConfig.hasBaseIdTransferRestriction() && idp.hasBaseIdTransferRestriction()) { Logger.error("Interfederated IDP " + idp.getPublicURLPrefix() + " is a BusinessService-IDP but requests PublicService attributes."); throw new MOAIDException("auth.34", new Object[]{nextIDPInformation.getIdpurlprefix()}); @@ -235,8 +259,12 @@ public class AttributQueryAction implements IAction { } //validation complete --> start AttributeQuery Request - AssertionAttributeExtractor extractor = authDataBuilder.getAuthDataFromAttributeQuery(reqAttributes, - nextIDPInformation.getUserNameID(), idp); + /*TODO: + * 'pendingReq.getAuthURL() + "/sp/federated/metadata"' is implemented in federated_authentication module + * but used in moa-id-lib. This should be refactored!!! + */ + AssertionAttributeExtractor extractor = getAuthDataFromAttributeQuery(reqAttributes, + nextIDPInformation.getUserNameID(), idp, pendingReq.getAuthURL() + "/sp/federated/metadata"); //mark attribute request as used if (nextIDPInformation.isStoreSSOInformation()) { @@ -258,7 +286,7 @@ public class AttributQueryAction implements IAction { } else { Logger.debug("Build authData for AttributQuery from local MOASession."); - IAuthData authData = authDataBuilder.buildAuthenticationData(pendingReq, session, spConfig); + IAuthData authData = authDataBuilder.buildAuthenticationData(pendingReq); //add default attributes in case of mandates or STORK is in use List<String> attrList = addDefaultAttributes(reqAttributes, authData); @@ -266,12 +294,19 @@ public class AttributQueryAction implements IAction { //build Set of response attributes List<Attribute> respAttr = PVPAttributeBuilder.buildSetOfResponseAttributes(authData, attrList); - return Trible.newInstance(respAttr, authData.getSsoSessionValidTo(), authData.getQAALevel()); + return Trible.newInstance(respAttr, authData.getSsoSessionValidTo(), authData.getEIDASQAALevel()); } } catch (MOAIDException e) { throw e; + + } catch (EAAFAuthenticationException e) { + throw new MOAIDException(e.getErrorId(), e.getParams(), e); + + } catch (EAAFConfigurationException e) { + throw new MOAIDException(e.getErrorId(), e.getParams(), e); + } } @@ -303,7 +338,8 @@ public class AttributQueryAction implements IAction { } //add default mandate attributes if it is a authentication with mandates - if (authData.isUseMandate() && !reqAttributeNames.containsAll(DEFAULTMANDATEATTRIBUTES)) { + if (authData instanceof IMOAAuthData) + if (((IMOAAuthData)authData).isUseMandate() && !reqAttributeNames.containsAll(DEFAULTMANDATEATTRIBUTES)) { for (String el : DEFAULTMANDATEATTRIBUTES) { if (!reqAttributeNames.contains(el)) reqAttributeNames.add(el); @@ -313,4 +349,78 @@ public class AttributQueryAction implements IAction { return reqAttributeNames; } + /** + * Get PVP authentication attributes by using a SAML2 AttributeQuery + * + * @param reqQueryAttr List of PVP attributes which are requested + * @param userNameID SAML2 UserNameID of the user for which attributes are requested + * @param idpConfig Configuration of the IDP, which is requested + * @return + * @return PVP attribute DAO, which contains all received information + * @throws MOAIDException + * @throws AttributQueryException + * @throws AssertionValidationExeption + */ + public AssertionAttributeExtractor getAuthDataFromAttributeQuery(List<Attribute> reqQueryAttr, + String userNameID, IOAAuthParameters idpConfig, String spEntityID) throws MOAIDException, AttributQueryException, AssertionValidationExeption{ + String idpEnityID = idpConfig.getPublicURLPrefix(); + + try { + Logger.debug("Starting AttributeQuery process ..."); + //collect attributes by using BackChannel communication + String endpoint = idpConfig.getIDPAttributQueryServiceURL(); + if (MiscUtil.isEmpty(endpoint)) { + Logger.error("No AttributeQueryURL for interfederationIDP " + idpEnityID); + throw new ConfigurationException("config.26", new Object[]{idpEnityID}); + + } + + //build attributQuery request + AttributeQuery query = attributQueryBuilder.buildAttributQueryRequest(spEntityID, userNameID, endpoint, reqQueryAttr); + + //build SOAP request + List<XMLObject> xmlObjects = MOASAMLSOAPClient.send(endpoint, query); + + if (xmlObjects.size() == 0) { + Logger.error("Receive emptry AttributeQuery response-body."); + throw new AttributQueryException("auth.27", + new Object[]{idpEnityID, "Receive emptry AttributeQuery response-body."}); + + } + + Response intfResp; + if (xmlObjects.get(0) instanceof Response) { + intfResp = (Response) xmlObjects.get(0); + + //validate PVP 2.1 response + try { + samlVerificationEngine.verifyIDPResponse(intfResp, + TrustEngineFactory.getSignatureKnownKeysTrustEngine( + metadataProvider)); + + //create assertion attribute extractor from AttributeQuery response + return new AssertionAttributeExtractor(intfResp); + + } catch (Exception e) { + Logger.warn("PVP 2.1 assertion validation FAILED.", e); + throw new AssertionValidationExeption("auth.27", + new Object[]{idpEnityID, e.getMessage()}, e); + } + + } else { + Logger.error("Receive AttributeQuery response-body include no PVP 2.1 response"); + throw new AttributQueryException("auth.27", + new Object[]{idpEnityID, "Receive AttributeQuery response-body include no PVP 2.1 response"}); + + } + + } catch (SOAPException e) { + throw new BuildException("builder.06", null, e); + + } catch (SecurityException e) { + throw new BuildException("builder.06", null, e); + + } + } + } |