/*
* 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;
}
}