diff options
Diffstat (limited to 'id.server/src/at/gv/egovernment/moa/id/auth/AuthenticationServer.java')
-rw-r--r-- | id.server/src/at/gv/egovernment/moa/id/auth/AuthenticationServer.java | 261 |
1 files changed, 238 insertions, 23 deletions
diff --git a/id.server/src/at/gv/egovernment/moa/id/auth/AuthenticationServer.java b/id.server/src/at/gv/egovernment/moa/id/auth/AuthenticationServer.java index 8359623b1..cd4b26df3 100644 --- a/id.server/src/at/gv/egovernment/moa/id/auth/AuthenticationServer.java +++ b/id.server/src/at/gv/egovernment/moa/id/auth/AuthenticationServer.java @@ -10,8 +10,10 @@ import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Set; +import java.util.Vector; import javax.xml.transform.TransformerException; @@ -23,36 +25,42 @@ import at.gv.egovernment.moa.id.ParseException; import at.gv.egovernment.moa.id.ServiceException; import at.gv.egovernment.moa.id.auth.builder.AuthenticationBlockAssertionBuilder; import at.gv.egovernment.moa.id.auth.builder.AuthenticationDataAssertionBuilder; +import at.gv.egovernment.moa.id.auth.builder.BPKBuilder; import at.gv.egovernment.moa.id.auth.builder.CertInfoVerifyXMLSignatureRequestBuilder; import at.gv.egovernment.moa.id.auth.builder.CreateXMLSignatureRequestBuilder; import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder; import at.gv.egovernment.moa.id.auth.builder.GetIdentityLinkFormBuilder; import at.gv.egovernment.moa.id.auth.builder.InfoboxReadRequestBuilder; +import at.gv.egovernment.moa.id.auth.builder.InfoboxValidatorParamsBuilder; import at.gv.egovernment.moa.id.auth.builder.PersonDataBuilder; import at.gv.egovernment.moa.id.auth.builder.SAMLArtifactBuilder; import at.gv.egovernment.moa.id.auth.builder.SelectBKUFormBuilder; -import at.gv.egovernment.moa.id.auth.builder.BPKBuilder; import at.gv.egovernment.moa.id.auth.builder.VerifyXMLSignatureRequestBuilder; import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; import at.gv.egovernment.moa.id.auth.data.CreateXMLSignatureResponse; +import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute; import at.gv.egovernment.moa.id.auth.data.IdentityLink; +import at.gv.egovernment.moa.id.auth.data.InfoboxValidatorParams; import at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse; import at.gv.egovernment.moa.id.auth.invoke.SignatureVerificationInvoker; import at.gv.egovernment.moa.id.auth.parser.CreateXMLSignatureResponseParser; +import at.gv.egovernment.moa.id.auth.parser.ExtendedInfoboxReadResponseParser; import at.gv.egovernment.moa.id.auth.parser.InfoboxReadResponseParser; import at.gv.egovernment.moa.id.auth.parser.SAMLArtifactParser; import at.gv.egovernment.moa.id.auth.parser.VerifyXMLSignatureResponseParser; import at.gv.egovernment.moa.id.auth.servlet.AuthServlet; import at.gv.egovernment.moa.id.auth.validator.CreateXMLSignatureResponseValidator; import at.gv.egovernment.moa.id.auth.validator.IdentityLinkValidator; +import at.gv.egovernment.moa.id.auth.validator.InfoboxValidator; import at.gv.egovernment.moa.id.auth.validator.ValidateException; import at.gv.egovernment.moa.id.auth.validator.VerifyXMLSignatureResponseValidator; import at.gv.egovernment.moa.id.config.ConfigurationException; import at.gv.egovernment.moa.id.config.ConfigurationProvider; import at.gv.egovernment.moa.id.config.ConnectionParameter; -import at.gv.egovernment.moa.id.config.OAParameter; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; +import at.gv.egovernment.moa.id.config.auth.VerifyInfoboxParameter; +import at.gv.egovernment.moa.id.config.auth.VerifyInfoboxParameters; import at.gv.egovernment.moa.id.data.AuthenticationData; import at.gv.egovernment.moa.id.util.HTTPUtils; import at.gv.egovernment.moa.id.util.MOAIDMessageProvider; @@ -65,7 +73,6 @@ import at.gv.egovernment.moa.util.Constants; import at.gv.egovernment.moa.util.DOMUtils; import at.gv.egovernment.moa.util.DateTimeUtils; import at.gv.egovernment.moa.util.FileUtils; -import at.gv.egovernment.moa.util.OutputXML2File; import at.gv.egovernment.moa.util.StringUtils; /** @@ -338,6 +345,11 @@ public class AuthenticationServer implements MOAIDAuthConstants { ex); } } + String pushInfobox = ""; + VerifyInfoboxParameters verifyInfoboxParameters = oaParam.getVerifyInfoboxParameters(); + if (verifyInfoboxParameters != null) { + pushInfobox = verifyInfoboxParameters.getPushInfobox(); + } String certInfoRequest = new CertInfoVerifyXMLSignatureRequestBuilder().build(oaParam.getSlVersion12()); String certInfoDataURL = new DataURLBuilder().buildDataURL( @@ -351,7 +363,8 @@ public class AuthenticationServer implements MOAIDAuthConstants { infoboxReadRequest, dataURL, certInfoRequest, - certInfoDataURL); + certInfoDataURL, + pushInfobox); return htmlForm; } /** @@ -363,6 +376,7 @@ public class AuthenticationServer implements MOAIDAuthConstants { * <li>Verifies identity link by calling the MOA SP component</li> * <li>Checks certificate authority of identity link</li> * <li>Stores identity link in the session</li> + * <li>Verifies all additional infoboxes returned from the BKU</li> * <li>Creates an authentication block to be signed by the user</li> * <li>Creates and returns a <code><CreateXMLSignatureRequest></code> * containg the authentication block, meant to be returned to the @@ -370,13 +384,14 @@ public class AuthenticationServer implements MOAIDAuthConstants { * </ul> * * @param sessionID ID of associated authentication session data - * @param xmlInfoboxReadResponse String representation of the - * <code><InfoboxReadResponse></code> + * @param infoboxReadResponseParameters The parameters from the response returned from + * the BKU including the <code><InfoboxReadResponse></code> * @return String representation of the <code><CreateXMLSignatureRequest></code> */ - public String verifyIdentityLink(String sessionID, String xmlInfoboxReadResponse) + public String verifyIdentityLink(String sessionID, Map infoboxReadResponseParameters) throws AuthenticationException, + BuildException, ParseException, ConfigurationException, ValidateException, @@ -384,8 +399,11 @@ public class AuthenticationServer implements MOAIDAuthConstants { if (isEmpty(sessionID)) throw new AuthenticationException("auth.10", new Object[] { REQ_VERIFY_IDENTITY_LINK, PARAM_SESSIONID}); + + String xmlInfoboxReadResponse = (String)infoboxReadResponseParameters.get(PARAM_XMLRESPONSE); if (isEmpty(xmlInfoboxReadResponse)) throw new AuthenticationException("auth.10", new Object[] { REQ_VERIFY_IDENTITY_LINK, PARAM_XMLRESPONSE}); + AuthenticationSession session = getSession(sessionID); if (session.getTimestampIdentityLink() != null) throw new AuthenticationException("auth.01", new Object[] { sessionID }); @@ -427,6 +445,8 @@ public class AuthenticationServer implements MOAIDAuthConstants { ignoreManifestValidationResult); session.setIdentityLink(identityLink); + // now validate the extended infoboxes + verifyInfoboxes(session, infoboxReadResponseParameters); // builds the AUTH-block String authBlock = buildAuthenticationBlock(session); // session.setAuthBlock(authBlock); @@ -446,29 +466,222 @@ public class AuthenticationServer implements MOAIDAuthConstants { /** * Builds an authentication block <code><saml:Assertion></code> from given session data. * @param session authentication session + * * @return <code><saml:Assertion></code> as a String + * + * @throws BuildException If an error occurs on serializing an extended SAML attribute + * to be appended to the AUTH-Block. */ - private String buildAuthenticationBlock(AuthenticationSession session) { + private String buildAuthenticationBlock(AuthenticationSession session) throws BuildException { IdentityLink identityLink = session.getIdentityLink(); String issuer = identityLink.getName(); String gebDat = identityLink.getDateOfBirth(); String identificationValue = identityLink.getIdentificationValue(); String identificationType = identityLink.getIdentificationType(); String issueInstant = DateTimeUtils.buildDateTime(Calendar.getInstance()); + session.setIssueInstant(issueInstant); String authURL = session.getAuthURL(); String target = session.getTarget(); String oaURL = session.getPublicOAURLPrefix(); - String authBlock = new AuthenticationBlockAssertionBuilder().buildAuthBlock(issuer, - issueInstant, - authURL, - target, - identificationValue, - identificationType, - oaURL, - gebDat); + List extendedSAMLAttributes = session.getExtendedSAMLAttributesAUTH(); + String authBlock = new AuthenticationBlockAssertionBuilder().buildAuthBlock( + issuer, + issueInstant, + authURL, + target, + identificationValue, + identificationType, + oaURL, + gebDat, + extendedSAMLAttributes); return authBlock; } + + /** + * Verifies the infoboxes (except of the identity link infobox) returned by the BKU by + * calling appropriate validator classes. + * + * @param session The actual authentication session. + * @param infoboxReadResponseParams The parameters returned from the BKU as response + * to an infobox read request (including the infobox + * tokens to be verified). + * + * @throws AuthenticationException If the verification of at least one infobox fails. + * @throws ConfigurationException If the OAuthParameter cannot be extracted. + */ + private void verifyInfoboxes( + AuthenticationSession session, Map infoboxReadResponseParams) + throws ValidateException, ConfigurationException + { + + AuthConfigurationProvider authConfigurationProvider = AuthConfigurationProvider.getInstance(); + // get the default VerifyInfobox parameters + Map defaultInfoboxParameters = null; + VerifyInfoboxParameters defaultVerifyInfoboxParameters = + authConfigurationProvider.getDefaultVerifyInfoboxParameters(); + if (defaultVerifyInfoboxParameters != null) { + defaultInfoboxParameters = defaultVerifyInfoboxParameters.getInfoboxParameters(); + } + // get the OA specific VerifyInfobox parameters + Map infoboxParameters = null; + OAAuthParameter oaParam = + authConfigurationProvider.getOnlineApplicationParameter(session.getPublicOAURLPrefix()); + VerifyInfoboxParameters verifyInfoboxParameters = oaParam.getVerifyInfoboxParameters(); + if (verifyInfoboxParameters != null) { + Vector authAttributes = new Vector(); + Vector oaAttributes = new Vector(); + infoboxParameters = verifyInfoboxParameters.getInfoboxParameters(); + // get the list of infobox identifiers + List identifiers = verifyInfoboxParameters.getIdentifiers(); + if (identifiers != null) { + // step through the identifiers and verify the infoboxes + Iterator it = identifiers.iterator(); + while (it.hasNext()) { + String identifier = (String)it.next(); + // get the infobox read response from the map of parameters + String infoboxReadResponse = (String)infoboxReadResponseParams.get(identifier); + // get the configuration parameters + VerifyInfoboxParameter verifyInfoboxParameter = null; + Object object = infoboxParameters.get(identifier); + // if not present, use default + if ((object == null) && (defaultInfoboxParameters != null)) { + object = defaultInfoboxParameters.get(identifier); + } + if (object != null) { + verifyInfoboxParameter = (VerifyInfoboxParameter)object; + } + if (infoboxReadResponse != null) { + if (verifyInfoboxParameter == null) { + // should not happen because of the pushinfobox mechanism; check it anyway + Logger.error("No validator for verifying \"" + identifier + "\"-infobox configured."); + throw new ValidateException("validator.41", new Object[] {identifier}); + } else { + String friendlyName = verifyInfoboxParameter.getFriendlyName(); + // get the class for validating the infobox + InfoboxValidator infoboxValidator = null; + try { + Class validatorClass = Class.forName(verifyInfoboxParameter.getValidatorClassName()); + infoboxValidator = (InfoboxValidator) validatorClass.newInstance(); + } catch (Exception e) { + Logger.error("Could not load validator class \"" + verifyInfoboxParameter.getValidatorClassName() + + "\" for \"" + identifier + "\"-infobox: " + e.getMessage()); + throw new ValidateException("validator.42", new Object[] {friendlyName}); + } + Logger.debug("Successfully loaded validator class \"" + verifyInfoboxParameter.getValidatorClassName() + + "\" for \"" + identifier + "\"-infobox."); + // parse the infobox read reponse + List infoboxTokenList = null; + try { + infoboxTokenList = + ExtendedInfoboxReadResponseParser.parseInfoboxReadResponse(infoboxReadResponse, friendlyName); + } catch (ParseException e) { + Logger.error("InfoboxReadResponse for \"" + identifier + + "\"-infobox could not be parsed successfully: " + e.getMessage()); + throw new ValidateException("validator.43", new Object[] {friendlyName}); + } + // build the parameters for validating the infobox + InfoboxValidatorParams infoboxValidatorParams = + InfoboxValidatorParamsBuilder.buildInfoboxValidatorParams( + session, verifyInfoboxParameter, infoboxTokenList); + // now validate the infobox + boolean infoboxValid = false; + try { + infoboxValid = infoboxValidator.validate(infoboxValidatorParams); + } catch (ValidateException e) { + Logger.error("Error validating " + identifier + " infobox:" + e.getMessage()); + throw new ValidateException( + "validator.44", new Object[] {friendlyName}); + } + if (!infoboxValid) { + Logger.info("Validation of " + identifier + " infobox failed."); + throw new ValidateException( + "validator.40", new Object[] {friendlyName, infoboxValidator.getErrorMessage()}); + } + + Logger.info(identifier + " infobox successfully validated."); + + // get the SAML attributes to be appended to the AUTHBlock or to the final + // SAML Assertion + ExtendedSAMLAttribute[] extendedSAMLAttributes = infoboxValidator.getExtendedSamlAttributes(); + if (extendedSAMLAttributes != null) { + int length = extendedSAMLAttributes.length; + for (int i=0; i<length; i++) { + ExtendedSAMLAttribute samlAttribute = extendedSAMLAttributes[i]; + String name = samlAttribute.getName(); + if (name == null) { + Logger.info("The name of SAML-Attribute number " + (i+1) + " returned from " + + identifier + "-infobox validator is null."); + throw new ValidateException( + "validator.45", new Object[] {friendlyName, "Name", String.valueOf((i+1)), "null"}); + } + if (name == "") { + Logger.info("The name of SAML-Attribute number " + (i+1) + " returned from " + + identifier + "-infobox validator is empty."); + throw new ValidateException( + "validator.45", new Object[] {friendlyName, "Name", String.valueOf((i+1)), "leer"}); + } + if (samlAttribute.getNameSpace() == null) { + Logger.info("The namespace of SAML-Attribute number " + (i+1) + " returned from " + + identifier + "-infobox validator is null."); + throw new ValidateException( + "validator.45", new Object[] {friendlyName, "Namespace", String.valueOf((i+1)), "null"}); + } + Object value = samlAttribute.getValue(); + if (value == null) { + Logger.info("The value of SAML-Attribute number " + (i+1) + " returned from " + + identifier + "-infobox validator is null."); + throw new ValidateException( + "validator.45", new Object[] {friendlyName ,"Wert", String.valueOf((i+1)), "null"}); + } + if ((value instanceof String) || (value instanceof Element)) { + + switch (samlAttribute.getAddToAUTHBlock()) { + case ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK: + authAttributes.add(samlAttribute); + oaAttributes.add(samlAttribute); + break; + case ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY: + authAttributes.add(samlAttribute); + break; + case ExtendedSAMLAttribute.NOT_ADD_TO_AUTHBLOCK: + oaAttributes.add(samlAttribute); + break; + default: + Logger.info("Invalid return value from method \"getAddToAUTHBlock()\" (" + + samlAttribute.getAddToAUTHBlock() + ") in SAML attribute number " + + (i+1) + " for infobox " + identifier); + throw new ValidateException( + "validator.47", new Object[] {friendlyName, String.valueOf((i+1))}); + } + } else { + Logger.info("The type of SAML-Attribute number " + (i+1) + " returned from " + + identifier + "-infobox validator is not valid. Must be either \"java.Lang.String\"" + + " or \"org.w3c.dom.Element\""); + throw new ValidateException( + "validator.46", new Object[] {identifier, String.valueOf((i+1))}); + + } + } + + } + } + } else { + if ((verifyInfoboxParameter !=null) && (verifyInfoboxParameter.isRequired())) { + Logger.info("Infobox \"" + identifier + "\" is required, but not returned from the BKU"); + throw new ValidateException( + "validator.48", new Object[] {verifyInfoboxParameter.getFriendlyName()}); + + } + Logger.debug("Infobox \"" + identifier + "\" not returned from BKU."); + } + } + session.setExtendedSAMLAttributesAUTH(authAttributes); + session.setExtendedSAMLAttributesOA(oaAttributes); + } + } + } + /** * Processes a <code><CreateXMLSignatureResponse></code> sent by the * security layer implementation.<br> @@ -630,13 +843,15 @@ public class AuthenticationServer implements MOAIDAuthConstants { } String authBlock = oaParam.getProvideAuthBlock() ? session.getAuthBlock() : ""; String samlAssertion = - new AuthenticationDataAssertionBuilder().build(authData, - prPerson, - authBlock, - ilAssertion, - session.getBkuURL(), - signerCertificateBase64, - businessService); + new AuthenticationDataAssertionBuilder().build( + authData, + prPerson, + authBlock, + ilAssertion, + session.getBkuURL(), + signerCertificateBase64, + businessService, + session.getExtendedSAMLAttributesOA()); authData.setSamlAssertion(samlAssertion); return authData; } catch (Throwable ex) { |