/* * Copyright 2003 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.auth.builder; import java.io.StringWriter; import java.text.MessageFormat; import java.util.List; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Element; import org.w3c.dom.Node; import at.gv.egovernment.moa.id.BuildException; import at.gv.egovernment.moa.id.ParseException; import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute; import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttributeImpl; import at.gv.egovernment.moa.id.config.ConfigurationException; import at.gv.egovernment.moa.id.config.TargetToSectorNameMapper; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.util.Random; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.Constants; import at.gv.egovernment.moa.util.DOMUtils; import at.gv.egovernment.moa.util.StringUtils; /** * Builder for the authentication block <saml:Assertion> * to be included in a <CreateXMLSignatureResponse>. * * @author Paul Ivancsics * @version $Id$ */ public class AuthenticationBlockAssertionBuilder extends AuthenticationAssertionBuilder implements Constants { /** template for the Auth-Block */ private static String AUTH_BLOCK = "" + NL + " " + NL + " " + NL + " {3}" + NL + " " + NL + "{4}" + " " + NL + " {5}" + NL + " " + NL + " " + NL + " {6}" + NL + " " + NL + "{7}" + " " + NL + ""; private static String GESCHAEFTS_BEREICH_ATTRIBUTE = " " + NL + " {0}" + NL + " " + NL; private static String WBPK_ATTRIBUTE = " " + NL + " " + NL + " " + NL + " {0}" + NL + " {1}" + NL + " " + NL + " " + NL + " " + NL; private static String PR_IDENTIFICATION_ATTRIBUTE = " " + NL + " {0}" + NL + " {1}" + NL + " " + NL; /** * The number of SAML attributes included in this AUTH-Block (without the extended SAML attributes). */ public static final int NUM_OF_SAML_ATTRIBUTES = 3; /** * Constructor for AuthenticationBlockAssertionBuilder. */ public AuthenticationBlockAssertionBuilder() { super(); } /** * Builds the authentication block <saml:Assertion> * * @param issuer authentication block issuer; "GivenName FamilyName" * @param issueInstant current timestamp * @param authURL URL of MOA-ID authentication component * @param target "Geschäftsbereich"; maybe null if the application * is a business application * @param identityLinkValue the content of the <pr:Value> * child element of the <pr:Identification> * element derived from the Identitylink; this is the * value of the wbPK; * maybe null if the application is a public service * @param identityLinkType the content of the <pr:Type> * child element of the <pr:Identification> * element derived from the Identitylink; this includes the * URN prefix and the identification number of the business * application used as input for wbPK computation; * maybe null if the application is a public service * @param oaURL public URL of online application requested * @param gebDat The date of birth from the identity link. * @param extendedSAMLAttributes The SAML attributes to be appended to the AUTHBlock. * * @return String representation of authentication block * <saml:Assertion> built * * @throws BuildException If an error occurs on serializing an extended SAML attribute * to be appended to the AUTH-Block. */ public String buildAuthBlock( String issuer, String issueInstant, String authURL, String target, String targetFriendlyName, String identityLinkValue, String identityLinkType, String oaURL, String gebDat, List extendedSAMLAttributes, AuthenticationSession session) throws BuildException { session.setSAMLAttributeGebeORwbpk(true); String gebeORwbpk = ""; String wbpkNSDeclaration = ""; //reading OA parameters OAAuthParameter oaParam; try { oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter( session.getPublicOAURLPrefix()); } catch (ConfigurationException e) { Logger.error("Error on building AUTH-Block: " + e.getMessage()); throw new BuildException("builder.00", new Object[] { "AUTH-Block", e.toString()}); } if (target == null) { // OA is a business application if (!Constants.URN_PREFIX_HPI.equals(identityLinkType)) { // Only add wbPKs to AUTH-Block. HPIs can be added to the AUTH-Block by the corresponding Validator gebeORwbpk = MessageFormat.format(WBPK_ATTRIBUTE, new Object[] { identityLinkValue, identityLinkType }); wbpkNSDeclaration = " xmlns:pr=\"" + PD_NS_URI + "\""; //adding type of wbPK domain identifier ExtendedSAMLAttribute idLinkDomainIdentifierTypeAttribute = new ExtendedSAMLAttributeImpl("IdentityLinkDomainIdentifierType", oaParam.getIdentityLinkDomainIdentifierType(), Constants.MOA_NS_URI, ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY); extendedSAMLAttributes.add(idLinkDomainIdentifierTypeAttribute); } else { // We do not have a wbPK, therefore no SAML-Attribute is provided session.setSAMLAttributeGebeORwbpk(false); } } else { // OA is a govermental application String sectorName = TargetToSectorNameMapper.getSectorNameViaTarget(target); if (StringUtils.isEmpty(sectorName)) { if (targetFriendlyName != null) sectorName = targetFriendlyName; } System.out.println("targetFriendlyName: " + targetFriendlyName); System.out.println("sectorName: " + sectorName); //gebeORwbpk = MessageFormat.format(GESCHAEFTS_BEREICH_ATTRIBUTE, new Object[] { target }); gebeORwbpk = MessageFormat.format(GESCHAEFTS_BEREICH_ATTRIBUTE, new Object[] { target + " (" + sectorName + ")" }); //no business service, adding bPK Element bpkSamlValueElement; try { bpkSamlValueElement = DOMUtils.parseDocument(MessageFormat.format(PR_IDENTIFICATION_ATTRIBUTE, new Object[] { identityLinkValue, Constants.URN_PREFIX_BPK }), false, null, null).getDocumentElement(); } catch (Exception e) { Logger.error("Error on building AUTH-Block: " + e.getMessage()); throw new BuildException("builder.00", new Object[] { "AUTH-Block", e.toString()}); } // String s = xmlToString(bpkSamlValueElement); // System.out.println("bpkSamlValueElement: " + s); ExtendedSAMLAttribute bpkAttribute = new ExtendedSAMLAttributeImpl("bPK", bpkSamlValueElement, Constants.MOA_NS_URI, ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY); extendedSAMLAttributes.add(bpkAttribute); boolean useMandate = session.getUseMandate(); if (useMandate) { String mandateReferenceValue = Random.nextRandom(); // remove leading "-" if (mandateReferenceValue.startsWith("-")) mandateReferenceValue = mandateReferenceValue.substring(1); session.setMandateReferenceValue(mandateReferenceValue); ExtendedSAMLAttribute mandateReferenceValueAttribute = new ExtendedSAMLAttributeImpl("mandateReferenceValue", mandateReferenceValue, Constants.MOA_NS_URI, ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK); extendedSAMLAttributes.add(mandateReferenceValueAttribute); } //gebeORwbpk = gebeORwbpk + MessageFormat.format(BPK_ATTRIBUTE, new Object[] { identityLinkValue, identityLinkType }); wbpkNSDeclaration = " xmlns:pr=\"" + PD_NS_URI + "\""; } //adding friendly name of OA String oaFriendlyName = StringUtils.isEmpty(oaParam.getFriendlyName()) ? "" : oaParam.getFriendlyName(); ExtendedSAMLAttribute oaFriendlyNameAttribute = new ExtendedSAMLAttributeImpl("oaFriendlyName", oaFriendlyName, Constants.MOA_NS_URI, ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY); extendedSAMLAttributes.add(oaFriendlyNameAttribute); String assertion; try { assertion = MessageFormat.format( AUTH_BLOCK, new Object[] { wbpkNSDeclaration, issuer, issueInstant, authURL, gebeORwbpk, oaURL, gebDat, buildExtendedSAMLAttributes(extendedSAMLAttributes)}); } catch (ParseException e) { Logger.error("Error on building AUTH-Block: " + e.getMessage()); throw new BuildException("builder.00", new Object[] { "AUTH-Block", e.toString()}); } return assertion; } /** * Builds the authentication block <saml:Assertion> * * @param issuer authentication block issuer; "GivenName FamilyName" * @param issueInstant current timestamp * @param authURL URL of MOA-ID authentication component * @param target "Geschäftsbereich"; maybe null if the application * is a business application * @param identityLinkValue the content of the <pr:Value> * child element of the <pr:Identification> * element derived from the Identitylink; this is the * value of the wbPK; * maybe null if the application is a public service * @param identityLinkType the content of the <pr:Type> * child element of the <pr:Identification> * element derived from the Identitylink; this includes the * URN prefix and the identification number of the business * application used as input for wbPK computation; * maybe null if the application is a public service * @param oaURL public URL of online application requested * @param gebDat The date of birth from the identity link. * @param extendedSAMLAttributes The SAML attributes to be appended to the AUTHBlock. * * @return String representation of authentication block * <saml:Assertion> built * * @throws BuildException If an error occurs on serializing an extended SAML attribute * to be appended to the AUTH-Block. */ public String buildAuthBlockForeignID( String issuer, String issueInstant, String authURL, String target, String identityLinkValue, String identityLinkType, String oaURL, String gebDat, List extendedSAMLAttributes, AuthenticationSession session) throws BuildException { session.setSAMLAttributeGebeORwbpk(true); String gebeORwbpk = ""; String wbpkNSDeclaration = ""; //BZ.., reading OA parameters OAAuthParameter oaParam; try { oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter( session.getPublicOAURLPrefix()); } catch (ConfigurationException e) { Logger.error("Error on building AUTH-Block: " + e.getMessage()); throw new BuildException("builder.00", new Object[] { "AUTH-Block", e.toString()}); } //..BZ if (target == null) { // OA is a business application if (!Constants.URN_PREFIX_HPI.equals(identityLinkType)) { // Only add wbPKs to AUTH-Block. HPIs can be added to the AUTH-Block by the corresponding Validator gebeORwbpk = MessageFormat.format(WBPK_ATTRIBUTE, new Object[] { identityLinkValue, identityLinkType }); wbpkNSDeclaration = " xmlns:pr=\"" + PD_NS_URI + "\""; //BZ.., adding type of wbPK domain identifier ExtendedSAMLAttribute idLinkDomainIdentifierTypeAttribute = new ExtendedSAMLAttributeImpl("IdentityLinkDomainIdentifierType", oaParam.getIdentityLinkDomainIdentifierType(), Constants.MOA_NS_URI, ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY); extendedSAMLAttributes.add(idLinkDomainIdentifierTypeAttribute); //..BZ } else { // We do not have a wbPK, therefore no SAML-Attribute is provided session.setSAMLAttributeGebeORwbpk(false); } } else { // OA is a govermental application //BZ.. String sectorName = TargetToSectorNameMapper.getSectorNameViaTarget(target); //gebeORwbpk = MessageFormat.format(GESCHAEFTS_BEREICH_ATTRIBUTE, new Object[] { target }); gebeORwbpk = MessageFormat.format(GESCHAEFTS_BEREICH_ATTRIBUTE, new Object[] { target + " (" + sectorName + ")" }); //..BZ //BZ.., no business service, adding bPK Element bpkSamlValueElement; try { bpkSamlValueElement = DOMUtils.parseDocument(MessageFormat.format(PR_IDENTIFICATION_ATTRIBUTE, new Object[] { identityLinkValue, Constants.URN_PREFIX_BPK }), false, null, null).getDocumentElement(); } catch (Exception e) { Logger.error("Error on building AUTH-Block: " + e.getMessage()); throw new BuildException("builder.00", new Object[] { "AUTH-Block", e.toString()}); } ExtendedSAMLAttribute bpkAttribute = new ExtendedSAMLAttributeImpl("bPK", bpkSamlValueElement, Constants.MOA_NS_URI, ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY); extendedSAMLAttributes.add(bpkAttribute); //gebeORwbpk = gebeORwbpk + MessageFormat.format(BPK_ATTRIBUTE, new Object[] { identityLinkValue, identityLinkType }); wbpkNSDeclaration = " xmlns:pr=\"" + PD_NS_URI + "\""; //..BZ } //BZ.., adding friendly name of OA String oaFriendlyName = StringUtils.isEmpty(oaParam.getFriendlyName()) ? "" : oaParam.getFriendlyName(); ExtendedSAMLAttribute oaFriendlyNameAttribute = new ExtendedSAMLAttributeImpl("oaFriendlyName", oaFriendlyName, Constants.MOA_NS_URI, ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY); extendedSAMLAttributes.add(oaFriendlyNameAttribute); //..BZ String assertion; try { assertion = MessageFormat.format( AUTH_BLOCK, new Object[] { wbpkNSDeclaration, issuer, issueInstant, authURL, gebeORwbpk, oaURL, gebDat, buildExtendedSAMLAttributes(extendedSAMLAttributes)}); } catch (ParseException e) { Logger.error("Error on building AUTH-Block: " + e.getMessage()); throw new BuildException("builder.00", new Object[] { "AUTH-Block", e.toString()}); } return assertion; } public static String xmlToString(Node node) { try { Source source = new DOMSource(node); StringWriter stringWriter = new StringWriter(); Result result = new StreamResult(stringWriter); TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); transformer.transform(source, result); return stringWriter.getBuffer().toString(); } catch (TransformerConfigurationException e) { e.printStackTrace(); } catch (TransformerException e) { e.printStackTrace(); } return null; } }