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 | 212 |
1 files changed, 172 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 042eeeed8..142810d45 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 @@ -25,6 +25,7 @@ package at.gv.egovernment.moa.id.protocols.pvp2x; import java.util.ArrayList; import java.util.Arrays; +import java.util.Date; import java.util.List; import javax.servlet.http.HttpServletRequest; @@ -44,23 +45,28 @@ import at.gv.egovernment.moa.id.auth.builder.AuthenticationDataBuilder; 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.MOAIDException; +import at.gv.egovernment.moa.id.commons.db.MOASessionDBUtils; import at.gv.egovernment.moa.id.commons.db.dao.session.InterfederationSessionStore; import at.gv.egovernment.moa.id.commons.db.dao.session.OASessionStore; +import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; +import at.gv.egovernment.moa.id.config.auth.AuthConfiguration; import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; -import at.gv.egovernment.moa.id.data.FederatedAuthenticatenContainer; +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.moduls.IRequest; 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.messages.MOARequest; +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.storage.IAuthenticationSessionStoreage; -import at.gv.egovernment.moa.id.storage.ITransactionStorage; import at.gv.egovernment.moa.logging.Logger; -import at.gv.egovernment.moa.util.MiscUtil; /** * @author tlenz @@ -72,7 +78,7 @@ public class AttributQueryAction implements IAction { @Autowired private IAuthenticationSessionStoreage authenticationSessionStorage; @Autowired private AuthenticationDataBuilder authDataBuilder; @Autowired private IDPCredentialProvider pvpCredentials; - @Autowired private ITransactionStorage transactionStorage; + @Autowired private AuthConfiguration authConfig; private final static List<String> DEFAULTSTORKATTRIBUTES = Arrays.asList( new String[]{PVPConstants.EID_STORK_TOKEN_NAME}); @@ -98,34 +104,44 @@ public class AttributQueryAction implements IAction { //set time reference DateTime date = new DateTime(); - //get Single Sign-On information for the Service-Provider - // which sends the Attribute-Query request - AuthenticationSession moaSession = authenticationSessionStorage.getSession(pendingReq.getMOASessionIdentifier()); - if (moaSession == null) { - Logger.warn("No MOASession with ID:" + pendingReq.getMOASessionIdentifier() + " FOUND."); - throw new MOAIDException("auth.02", new Object[]{pendingReq.getMOASessionIdentifier()}); - } - - InterfederationSessionStore nextIDPInformation = - authenticationSessionStorage.searchInterfederatedIDPFORAttributeQueryWithSessionID(moaSession.getSessionID()); - - AttributeQuery attrQuery = - (AttributeQuery)((MOARequest)((PVPTargetConfiguration) pendingReq).getRequest()).getSamlRequest(); + try { + //get Single Sign-On information for the Service-Provider + // which sends the Attribute-Query request + AuthenticationSession moaSession = authenticationSessionStorage.getSession(pendingReq.getMOASessionIdentifier()); + if (moaSession == null) { + Logger.warn("No MOASession with ID:" + pendingReq.getMOASessionIdentifier() + " FOUND."); + throw new MOAIDException("auth.02", new Object[]{pendingReq.getMOASessionIdentifier()}); + } - //generate authData for AttributQueryRequest - authData = authDataBuilder.buildAuthenticationDataForAttributQuery(pendingReq, moaSession, attrQuery.getAttributes(), nextIDPInformation); - + InterfederationSessionStore nextIDPInformation = + authenticationSessionStorage.searchInterfederatedIDPFORAttributeQueryWithSessionID(moaSession.getSessionID()); - //add default attributes in case of mandates or STORK is in use - List<String> attrList = addDefaultAttributes(attrQuery, authData); + AttributeQuery attrQuery = + (AttributeQuery)((MOARequest)((PVPTargetConfiguration) pendingReq).getRequest()).getSamlRequest(); + + //build PVP 2.1 response-attribute information for this AttributQueryRequest + Trible<List<Attribute>, Date, String> responseInfo = + buildResponseInformationForAttributQuery(pendingReq, moaSession, attrQuery.getAttributes(), nextIDPInformation); - //build PVP 2.1 assertion - Assertion assertion = PVP2AssertionBuilder.buildAssertion(req, attrQuery, attrList, authData, date, authData.getSessionIndex()); - - //build PVP 2.1 response - Response authResponse = AuthResponseBuilder.buildResponse(req.getAuthURL(), attrQuery, date, assertion); - - try { + Logger.debug("AttributQuery return " + responseInfo.getFirst().size() + + " attributes with QAA-Level:" + responseInfo.getThird() + + " validTo:" + responseInfo.getSecond().toString()); + + //build PVP 2.1 assertion + + String issuerEntityID = pendingReq.getAuthURL(); + if (issuerEntityID.endsWith("/")) + issuerEntityID = issuerEntityID.substring(0, issuerEntityID.length()-1); + + Assertion assertion = PVP2AssertionBuilder.buildAssertion(issuerEntityID, + attrQuery, responseInfo.getFirst(), date, new DateTime(responseInfo.getSecond().getTime()), + responseInfo.getThird(), authData.getSessionIndex()); + + //build PVP 2.1 response + Response authResponse = AuthResponseBuilder.buildResponse( + MOAMetadataProvider.getInstance(), issuerEntityID, attrQuery, date, + assertion, authConfig.isPVP2AssertionEncryptionActive()); + SoapBinding decoder = new SoapBinding(); decoder.encodeRespone(httpReq, httpResp, authResponse, null, null, pvpCredentials.getIDPAssertionSigningCredential()); @@ -139,6 +155,11 @@ public class AttributQueryAction implements IAction { Logger.error("Security exception", e); throw new MOAIDException("pvp2.01", null, e); + } catch (MOADatabaseException e) { + Logger.error("MOASession with SessionID=" + pendingReq.getMOASessionIdentifier() + + " is not found in Database", e); + throw new MOAIDException("init.04", new Object[] { pendingReq.getMOASessionIdentifier() }); + } } else { @@ -164,32 +185,143 @@ public class AttributQueryAction implements IAction { public String getDefaultActionName() { return PVP2XProtocol.ATTRIBUTEQUERY; } + + private Trible<List<Attribute>, Date, String> buildResponseInformationForAttributQuery(IRequest pendingReq, + AuthenticationSession session, List<Attribute> reqAttributes, InterfederationSessionStore nextIDPInformation) throws MOAIDException { + try { + //mark AttributeQuery as used if it exists + OASessionStore activeOA = authenticationSessionStorage.searchActiveOASSOSession(session, pendingReq.getOAURL(), pendingReq.requestedModule()); + if (activeOA != null) { + //mark + if ( pendingReq instanceof PVPTargetConfiguration && + ((PVPTargetConfiguration) pendingReq).getRequest() instanceof MOARequest && + ((PVPTargetConfiguration) pendingReq).getRequest().getInboundMessage() instanceof AttributeQuery) { + try { + activeOA.setAttributeQueryUsed(true); + MOASessionDBUtils.saveOrUpdate(activeOA); + + } catch (MOADatabaseException e) { + Logger.error("MOASession interfederation information can not stored to database.", e); + + } + } + } + + //build OnlineApplication dynamic from requested attributes (AttributeQuerry Request) and configuration + IOAAuthParameters spConfig = DynamicOAAuthParameterBuilder.buildFromAttributeQuery(reqAttributes); + + //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 + OAAuthParameter idp = authConfig.getOnlineApplicationParameter(nextIDPInformation.getIdpurlprefix()); + if (idp == null) { + Logger.warn("Configuration for federated IDP:" + nextIDPInformation.getIdpurlprefix() + + "is not loadable."); + throw new MOAIDException("auth.32", new Object[]{nextIDPInformation.getIdpurlprefix()}); + + } + + //check if next IDP config allows inbound messages + if (!idp.isInboundSSOInterfederationAllowed()) { + Logger.warn("Configuration for federated IDP:" + nextIDPInformation.getIdpurlprefix() + + "disallow inbound authentication messages."); + throw new MOAIDException("auth.33", new Object[]{nextIDPInformation.getIdpurlprefix()}); + + } + + //check next IDP service area policy. BusinessService IDPs can only request wbPKs + if (!spConfig.getBusinessService() && !idp.isIDPPublicService()) { + Logger.error("Interfederated IDP " + idp.getPublicURLPrefix() + + " has a BusinessService-IDP but requests PublicService attributes."); + throw new MOAIDException("auth.34", new Object[]{nextIDPInformation.getIdpurlprefix()}); + + } + + //validation complete --> start AttributeQuery Request + AssertionAttributeExtractor extractor = authDataBuilder.getAuthDataFromAttributeQuery(reqAttributes, + nextIDPInformation.getUserNameID(), idp); + + try { + //mark attribute request as used + if (nextIDPInformation.isStoreSSOInformation()) { + nextIDPInformation.setAttributesRequested(true); + MOASessionDBUtils.saveOrUpdate(nextIDPInformation); - private List<String> addDefaultAttributes(AttributeQuery query, IAuthData authData) { + //delete federated IDP from Session + } else { + MOASessionDBUtils.delete(nextIDPInformation); + + } + + } catch (MOADatabaseException e) { + Logger.error("MOASession interfederation information can not stored to database.", e); + + } + + return Trible.newInstance( + extractor.getAllResponseAttributesFromFirstAttributeStatement(), + extractor.getAssertionNotOnOrAfter(), + extractor.getQAALevel()); + + } else { + Logger.debug("Build authData for AttributQuery from local MOASession."); + IAuthData authData = authDataBuilder.buildAuthenticationData(pendingReq, session, spConfig); + + //add default attributes in case of mandates or STORK is in use + List<String> attrList = addDefaultAttributes(reqAttributes, authData); + + //build Set of response attributes + List<Attribute> respAttr = PVPAttributeBuilder.buildSetOfResponseAttributes(authData, attrList); + + return Trible.newInstance(respAttr, authData.getSsoSessionValidTo(), authData.getQAALevel()); + + } + + } catch (MOAIDException e) { + throw e; + } + } + + /** + * Add additional PVP Attribute-Names in respect to current MOASession. + *<br><br> + * <pre>As example: if current MOASession includes mandates but mandate attributes are not requested, + * this method a a minimum set of mandate attribute-names</pre> + * + * @param reqAttr From Service Provider requested attributes + * @param authData AuthenticationData + * @return List of PVP attribute-names + */ + private List<String> addDefaultAttributes(List<Attribute> reqAttr, IAuthData authData) { - List<String> reqAttributs = new ArrayList<String>(); + List<String> reqAttributeNames = new ArrayList<String>(); - for (Attribute attr : query.getAttributes()) { - reqAttributs.add(attr.getName()); + for (Attribute attr : reqAttr) { + reqAttributeNames.add(attr.getName()); } //add default STORK attributes if it is a STORK authentication - if (authData.isForeigner() && !reqAttributs.containsAll(DEFAULTSTORKATTRIBUTES)) { + if (authData.isForeigner() && !reqAttributeNames.containsAll(DEFAULTSTORKATTRIBUTES)) { for (String el : DEFAULTSTORKATTRIBUTES) { - if (!reqAttributs.contains(el)) - reqAttributs.add(el); + if (!reqAttributeNames.contains(el)) + reqAttributeNames.add(el); } } //add default mandate attributes if it is a authentication with mandates - if (authData.isUseMandate() && !reqAttributs.containsAll(DEFAULTMANDATEATTRIBUTES)) { + if (authData.isUseMandate() && !reqAttributeNames.containsAll(DEFAULTMANDATEATTRIBUTES)) { for (String el : DEFAULTMANDATEATTRIBUTES) { - if (!reqAttributs.contains(el)) - reqAttributs.add(el); + if (!reqAttributeNames.contains(el)) + reqAttributeNames.add(el); } } - return reqAttributs; + return reqAttributeNames; } + } |