package at.gv.egovernment.moa.id.auth;
import iaik.asn1.ObjectID;
import iaik.util.logging.Log;
import iaik.x509.X509Certificate;
import iaik.x509.X509ExtensionInitException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.math.BigInteger;
import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.security.cert.CertificateException;
import java.util.ArrayList;
//import java.security.cert.CertificateFactory;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.xpath.XPathAPI;
import org.opensaml.common.IdentifierGenerator;
import org.opensaml.common.impl.SecureRandomIdentifierGenerator;
import org.opensaml.xml.util.Base64;
import org.opensaml.xml.util.XMLHelper;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import at.gv.egovernment.moa.id.auth.builder.AuthenticationBlockAssertionBuilder;
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.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.ExtendedSAMLAttributeImpl;
import at.gv.egovernment.moa.id.auth.data.IdentityLink;
import at.gv.egovernment.moa.id.auth.data.InfoboxValidationResult;
import at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse;
import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
import at.gv.egovernment.moa.id.auth.exception.BKUException;
import at.gv.egovernment.moa.id.auth.exception.BuildException;
import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
import at.gv.egovernment.moa.id.auth.exception.ParseException;
import at.gv.egovernment.moa.id.auth.exception.ServiceException;
import at.gv.egovernment.moa.id.auth.exception.ValidateException;
import at.gv.egovernment.moa.id.auth.exception.WrongParametersException;
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.IdentityLinkAssertionParser;
import at.gv.egovernment.moa.id.auth.parser.InfoboxReadResponseParser;
import at.gv.egovernment.moa.id.auth.parser.VerifyXMLSignatureResponseParser;
import at.gv.egovernment.moa.id.auth.servlet.PEPSConnectorServlet;
import at.gv.egovernment.moa.id.auth.stork.VelocityProvider;
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.VerifyXMLSignatureResponseValidator;
import at.gv.egovernment.moa.id.auth.validator.parep.ParepUtils;
//import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.CreateIdentityLinkResponse;
//import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.SZRGWClient;
//import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.SZRGWClientException;
import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.SZRGWConstants;
import at.gv.egovernment.moa.id.client.SZRGWClient;
import at.gv.egovernment.moa.id.client.SZRGWClientException;
import at.gv.egovernment.moa.id.commons.db.dao.config.IdentificationNumber;
import at.gv.egovernment.moa.id.commons.db.dao.config.OAStorkAttribute;
import at.gv.egovernment.moa.id.commons.db.dao.config.StorkAttribute;
import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;
import at.gv.egovernment.moa.id.config.ConfigurationException;
import at.gv.egovernment.moa.id.config.ConnectionParameter;
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.stork.CPEPS;
import at.gv.egovernment.moa.id.config.stork.STORKConfig;
import at.gv.egovernment.moa.id.data.AuthenticationData;
import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;
import at.gv.egovernment.moa.id.storage.AssertionStorage;
import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage;
import at.gv.egovernment.moa.id.storage.DBExceptionStoreImpl;
import at.gv.egovernment.moa.id.util.HTTPUtils;
import at.gv.egovernment.moa.id.util.MOAIDMessageProvider;
import at.gv.egovernment.moa.id.util.Random;
import at.gv.egovernment.moa.id.util.XMLUtil;
import at.gv.egovernment.moa.id.util.client.mis.simple.MISMandate;
import at.gv.egovernment.moa.logging.LogMsg;
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.DateTimeUtils;
import at.gv.egovernment.moa.util.FileUtils;
import at.gv.egovernment.moa.util.MiscUtil;
import at.gv.egovernment.moa.util.StringUtils;
import at.gv.egovernment.moa.util.XPathUtils;
import at.gv.util.xsd.mis.MandateIdentifiers;
import at.gv.util.xsd.mis.Target;
import at.gv.util.xsd.srzgw.CreateIdentityLinkRequest;
import at.gv.util.xsd.srzgw.CreateIdentityLinkRequest.PEPSData;
import at.gv.util.xsd.srzgw.CreateIdentityLinkResponse;
import at.gv.util.xsd.srzgw.MISType;
import at.gv.util.xsd.srzgw.MISType.Filters;
import eu.stork.oasisdss.api.AdditionalProfiles;
import eu.stork.oasisdss.api.ApiUtils;
import eu.stork.oasisdss.api.ApiUtilsException;
import eu.stork.oasisdss.api.Profiles;
import eu.stork.oasisdss.api.QualityLevels;
import eu.stork.oasisdss.api.SignatureTypes;
import eu.stork.oasisdss.profile.AnyType;
import eu.stork.oasisdss.profile.DocumentType;
import eu.stork.oasisdss.profile.SignRequest;
import eu.stork.peps.auth.commons.PEPSUtil;
import eu.stork.peps.auth.commons.PersonalAttribute;
import eu.stork.peps.auth.commons.PersonalAttributeList;
import eu.stork.peps.auth.commons.STORKAuthnRequest;
import eu.stork.peps.auth.engine.STORKSAMLEngine;
import eu.stork.peps.exceptions.STORKSAMLEngineException;
/**
* API for MOA ID Authentication Service.
{@link AuthenticationSession} is
* stored in a session store and retrieved by giving the session ID.
*
* @author Paul Ivancsics
* @version $Id: AuthenticationServer.java 1273 2012-02-27 14:50:18Z kstranacher
* $
*/
public class AuthenticationServer implements MOAIDAuthConstants {
/** single instance */
private static AuthenticationServer instance;
/**
* time out in milliseconds used by {@link cleanup} for session store
*/
private long sessionTimeOutCreated = 15 * 60 * 1000; // default 10 minutes
private long sessionTimeOutUpdated = 10 * 60 * 1000; // default 10 minutes
/**
* time out in milliseconds used by {@link cleanup} for authentication data
* store
*/
private long authDataTimeOut = 2 * 60 * 1000; // default 2 minutes
/**
* Returns the single instance of AuthenticationServer
.
*
* @return the single instance of AuthenticationServer
*/
public static AuthenticationServer getInstance() {
if (instance == null)
instance = new AuthenticationServer();
return instance;
}
/**
* Constructor for AuthenticationServer.
*/
public AuthenticationServer() {
super();
}
/**
* Processes the beginning of an authentication session.
*
<InfoboxReadRequest>
<InfoboxReadRequest>
null
; in this case, the default location will be
* used
* @param useMandate
* Indicates if mandate is used or not
* @param templateURL
* URL providing an HTML template for the HTML form generated
* @param templateMandteURL
* URL providing an HTML template for the HTML form generated
* (for signing in mandates mode)
* @param req
* determines the protocol used
* @param sourceID
* @return HTML form
* @throws AuthenticationException
* @see GetIdentityLinkFormBuilder
* @see InfoboxReadRequestBuilder
*/
public String startAuthentication(AuthenticationSession session, HttpServletRequest req) throws WrongParametersException,
AuthenticationException, ConfigurationException, BuildException {
if (session == null) {
throw new AuthenticationException("auth.18", new Object[] { });
}
//load OnlineApplication configuration
OAAuthParameter oaParam =
AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(session.getPublicOAURLPrefix());
if (oaParam == null)
throw new AuthenticationException("auth.00", new Object[] { session.getPublicOAURLPrefix() });
//load Template
String template = null;
if (session.getTemplateURL() != null) {
try {
template = new String(FileUtils.readURL(session.getTemplateURL()));
} catch (IOException ex) {
throw new AuthenticationException("auth.03", new Object[] {
session.getTemplateURL(), ex.toString() }, ex);
}
}
String infoboxReadRequest = "";
String domainIdentifier = AuthConfigurationProvider.getInstance().getSSOTagetIdentifier().trim();
if (MiscUtil.isEmpty(domainIdentifier) && session.isSsoRequested()) {
//do not use SSO if no Target is set
Log.warn("NO SSO-Target found in configuration. Single Sign-On is deaktivated!");
session.setSsoRequested(false);
}
if (session.isSsoRequested()) {
//load identityLink with SSO Target
boolean isbuisness = false;
if (domainIdentifier.startsWith(PREFIX_WPBK)) {
isbuisness = false;
} else {
isbuisness = true;
}
//build ReadInfobox request
infoboxReadRequest = new InfoboxReadRequestBuilder().build(
isbuisness, domainIdentifier);
} else {
//build ReadInfobox request
infoboxReadRequest = new InfoboxReadRequestBuilder().build(
oaParam.getBusinessService(), oaParam
.getIdentityLinkDomainIdentifier());
}
String dataURL = new DataURLBuilder().buildDataURL(
session.getAuthURL(), REQ_VERIFY_IDENTITY_LINK, session
.getSessionID());
//removed in MOAID 2.0
String pushInfobox = "";
// VerifyInfoboxParameters verifyInfoboxParameters = oaParam
// .getVerifyInfoboxParameters();
// if (verifyInfoboxParameters != null) {
// pushInfobox = verifyInfoboxParameters.getPushInfobox();
// session.setPushInfobox(pushInfobox);
// }
//build CertInfo request
String certInfoRequest = new CertInfoVerifyXMLSignatureRequestBuilder()
.build();
String certInfoDataURL = new DataURLBuilder()
.buildDataURL(session.getAuthURL(), REQ_START_AUTHENTICATION,
session.getSessionID());
//get Applet Parameters
String appletwidth = req.getParameter(PARAM_APPLET_WIDTH);
String appletheigth = req.getParameter(PARAM_APPLET_HEIGTH);
appletheigth = StringEscapeUtils.escapeHtml(appletheigth);
appletwidth = StringEscapeUtils.escapeHtml(appletwidth);
String htmlForm = new GetIdentityLinkFormBuilder().build(template,
session.getBkuURL(), infoboxReadRequest, dataURL, certInfoRequest,
certInfoDataURL, pushInfobox, oaParam, appletheigth, appletwidth);
return htmlForm;
}
/**
* Processes an <InfoboxReadResponse>
sent by the
* security layer implementation.<InfoboxReadResponse>
<InfoboxReadResponse>
<CreateXMLSignatureRequest>
* containg the authentication block, meant to be returned to the security
* layer implementation<InfoboxReadResponse>
* @return String representation of the
* <CreateXMLSignatureRequest>
* @throws BKUException
*/
public String verifyIdentityLink(AuthenticationSession session,
Map<InfoboxReadResponse>
sent by the
* security layer implementation.<InfoboxReadResponse>
<InfoboxReadResponse>
<CreateXMLSignatureRequest>
* containg the authentication block, meant to be returned to the security
* layer implementation<InfoboxReadResponse>
* @return String representation of the
* <CreateXMLSignatureRequest>
*/
public String verifyCertificate(AuthenticationSession session,
X509Certificate certificate) throws AuthenticationException,
BuildException, ParseException, ConfigurationException,
ValidateException, ServiceException, MOAIDException{
if (session == null)
throw new AuthenticationException("auth.10", new Object[] {
REQ_VERIFY_CERTIFICATE, PARAM_SESSIONID });
// check if person is a Organwalter
// if true - don't show bPK in AUTH Block
try {
for (ObjectID OWid : MOAIDAuthConstants.OW_LIST) {
if (certificate.getExtension(OWid) != null) {
session.setOW(true);
}
}
} catch (X509ExtensionInitException e) {
Logger.warn("Certificate extension is not readable.");
session.setOW(false);
}
AuthConfigurationProvider authConf = AuthConfigurationProvider
.getInstance();
OAAuthParameter oaParam = AuthConfigurationProvider.getInstance()
.getOnlineApplicationParameter(session.getPublicOAURLPrefix());
String returnvalue = getCreateXMLSignatureRequestAuthBlockOrRedirect(session,
authConf, oaParam);
return returnvalue;
}
/**
* Processes an Mandate
sent by the MIS.Mandate
<CreateXMLSignatureRequest>
* containg the authentication block, meant to be returned to the security
* layer implementation<InfoboxReadResponse>
* @return String representation of the
* <CreateXMLSignatureRequest>
*/
public void verifyMandate(AuthenticationSession session, MISMandate mandate)
throws AuthenticationException, BuildException, ParseException,
ConfigurationException, ValidateException, ServiceException {
if (session == null)
throw new AuthenticationException("auth.10", new Object[] {
GET_MIS_SESSIONID, PARAM_SESSIONID });
OAAuthParameter oaParam = AuthConfigurationProvider.getInstance()
.getOnlineApplicationParameter(session.getPublicOAURLPrefix());
try {
// sets the extended SAML attributes for OID (Organwalter)
setExtendedSAMLAttributeForMandatesOID(session, mandate, oaParam
.getBusinessService());
validateExtendedSAMLAttributeForMandates(session, mandate, oaParam.getBusinessService());
} catch (SAXException e) {
throw new AuthenticationException("auth.16",
new Object[] { GET_MIS_SESSIONID }, e);
} catch (IOException e) {
throw new AuthenticationException("auth.16",
new Object[] { GET_MIS_SESSIONID }, e);
} catch (ParserConfigurationException e) {
throw new AuthenticationException("auth.16",
new Object[] { GET_MIS_SESSIONID }, e);
} catch (TransformerException e) {
throw new AuthenticationException("auth.16",
new Object[] { GET_MIS_SESSIONID }, e);
}
}
/**
*
* @param session
* @param authConf
* @param oaParam
* @return
* @throws ConfigurationException
* @throws BuildException
* @throws ValidateException
*/
public String getCreateXMLSignatureRequestAuthBlockOrRedirect(
AuthenticationSession session, AuthConfigurationProvider authConf,
OAAuthParameter oaParam) throws ConfigurationException,
BuildException, ValidateException {
// check for intermediate processing of the infoboxes
if (session.isValidatorInputPending())
return "Redirect to Input Processor";
if (authConf == null)
authConf = AuthConfigurationProvider.getInstance();
if (oaParam == null)
oaParam = AuthConfigurationProvider.getInstance()
.getOnlineApplicationParameter(
session.getPublicOAURLPrefix());
// builds the AUTH-block
String authBlock = buildAuthenticationBlock(session, oaParam);
// builds the <CreateXMLSignatureRequest>
*/
public String createXMLSignatureRequestForeignID(AuthenticationSession session,
X509Certificate cert) throws AuthenticationException,
BuildException, ParseException, ConfigurationException,
ValidateException, ServiceException {
if (session == null)
throw new AuthenticationException("auth.10", new Object[] {
REQ_VERIFY_CERTIFICATE, PARAM_SESSIONID });
AuthConfigurationProvider authConf = AuthConfigurationProvider
.getInstance();
OAAuthParameter oaParam = AuthConfigurationProvider.getInstance()
.getOnlineApplicationParameter(session.getPublicOAURLPrefix());
return getCreateXMLSignatureRequestForeigID(session, authConf, oaParam,
cert);
}
public String getCreateXMLSignatureRequestForeigID(
AuthenticationSession session, AuthConfigurationProvider authConf,
OAAuthParameter oaParam, X509Certificate cert)
throws ConfigurationException {
// check for intermediate processing of the infoboxes
if (session.isValidatorInputPending())
return "Redirect to Input Processor";
if (authConf == null)
authConf = AuthConfigurationProvider.getInstance();
if (oaParam == null)
oaParam = AuthConfigurationProvider.getInstance()
.getOnlineApplicationParameter(
session.getPublicOAURLPrefix());
Principal subject = cert.getSubjectDN();
String createXMLSignatureRequest = new CreateXMLSignatureRequestBuilder()
.buildForeignID(subject.toString(), oaParam, session);
return createXMLSignatureRequest;
}
/**
* Processes an <CreateXMLSignatureResponse>
sent by the
* security layer implementation.<CreateXMLSignatureResponse>
<CreateXMLSignatureResponse>
<CreateXMLSignatureResponse>
* @throws BKUException
*/
public X509Certificate verifyXMLSignature(String sessionID,
Map<CreateXMLSignatureResponse>
sent by the
* security layer implementation.<CreateXMLSignatureResponse>
<CreateXMLSignatureResponse>
<ReadInfoboxResponse>
* @throws BKUException
*/
public X509Certificate getCertificate(String sessionID,
Map<saml:Assertion>
from
* given session data.
*
* @param session
* authentication session
*
* @return <saml:Assertion>
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,
OAAuthParameter oaParam) throws BuildException {
IdentityLink identityLink = session.getIdentityLink();
String issuer = identityLink.getName();
String gebDat = identityLink.getDateOfBirth();
String identificationValue = null;
String identificationType = null;
//set empty AuthBlock BPK in case of OW or SSO or bpk is not requested
if (session.isOW() || session.isSsoRequested() || oaParam.isRemovePBKFromAuthBlock()) {
identificationType = "";
identificationValue = "";
} else if (identityLink.getIdentificationType().equals(Constants.URN_PREFIX_BASEID)) {
if (oaParam.getBusinessService()) {
String bpkBase64 = new BPKBuilder().buildWBPK(identityLink
.getIdentificationValue(), oaParam.getIdentityLinkDomainIdentifier());
identificationValue = bpkBase64;
if (oaParam.getIdentityLinkDomainIdentifier().startsWith(Constants.URN_PREFIX_WBPK + "+" ))
identificationType = oaParam.getIdentityLinkDomainIdentifier();
else
identificationType = Constants.URN_PREFIX_WBPK + "+" + oaParam.getIdentityLinkDomainIdentifier();
} else {
String bpkBase64 = new BPKBuilder().buildBPK(identityLink
.getIdentificationValue(), session.getTarget());
identificationValue = bpkBase64;
identificationType = Constants.URN_PREFIX_CDID + "+" + session.getTarget();
}
} else {
identificationValue = identityLink.getIdentificationValue();
identificationType = identityLink.getIdentificationType();
}
String issueInstant = DateTimeUtils.buildDateTimeUTC(Calendar
.getInstance());
session.setIssueInstant(issueInstant);
String authURL = session.getAuthURL();
String target = session.getTarget();
String targetFriendlyName = session.getTargetFriendlyName();
// Bug #485
// (https://egovlabs.gv.at/tracker/index.php?func=detail&aid=485&group_id=6&atid=105)
// String oaURL = session.getPublicOAURLPrefix();
List<CreateXMLSignatureResponse>
sent by the
* security layer implementation.<CreateXMLSignatureResponse>
<CreateXMLSignatureResponse>
for error
* codes<CreateXMLSignatureResponse>
<CreateXMLSignatureResponse>
* @return SAML artifact needed for retrieving authentication data, encoded
* BASE64
* @throws BKUException
*/
public String verifyAuthenticationBlock(AuthenticationSession session,
String xmlCreateXMLSignatureReadResponse)
throws AuthenticationException, BuildException, ParseException,
ConfigurationException, ServiceException, ValidateException, BKUException {
if (session == null)
throw new AuthenticationException("auth.10", new Object[] {
REQ_VERIFY_AUTH_BLOCK, PARAM_SESSIONID });
if (isEmpty(xmlCreateXMLSignatureReadResponse))
throw new AuthenticationException("auth.10", new Object[] {
REQ_VERIFY_AUTH_BLOCK, PARAM_XMLRESPONSE });
AuthConfigurationProvider authConf = AuthConfigurationProvider
.getInstance();
// parses <CreateXMLSignatureResponse>
sent by the
* security layer implementation.<CreateXMLSignatureResponse>
<CreateXMLSignatureResponse>
for error
* codes<CreateXMLSignatureResponse>
<CreateXMLSignatureResponse>
* @return SAML artifact needed for retrieving authentication data, encoded
* BASE64
*/
protected Element createIdentificationBPK(Element mandatePerson,
String baseid, String target) throws BuildException {
Element identificationBpK = mandatePerson.getOwnerDocument()
.createElementNS(Constants.PD_NS_URI, "Identification");
Element valueBpK = mandatePerson.getOwnerDocument().createElementNS(
Constants.PD_NS_URI, "Value");
String bpkBase64 = new BPKBuilder().buildBPK(baseid, target);
valueBpK.appendChild(mandatePerson.getOwnerDocument().createTextNode(
bpkBase64));
Element typeBpK = mandatePerson.getOwnerDocument().createElementNS(
Constants.PD_NS_URI, "Type");
typeBpK.appendChild(mandatePerson.getOwnerDocument().createTextNode(
"urn:publicid:gv.at:cdid+bpk"));
identificationBpK.appendChild(valueBpK);
identificationBpK.appendChild(typeBpK);
return identificationBpK;
}
protected String getBaseId(Element mandatePerson)
throws TransformerException, IOException {
NodeList list = mandatePerson.getElementsByTagNameNS(
Constants.PD_NS_URI, "Identification");
for (int i = 0; i < list.getLength(); i++) {
Element identification = (Element) list.item(i);
Element type = (Element) identification.getElementsByTagNameNS(
Constants.PD_NS_URI, "Type").item(0);
if (type.getTextContent().compareToIgnoreCase(
"urn:publicid:gv.at:baseid") == 0) {
Element value = (Element) identification
.getElementsByTagNameNS(Constants.PD_NS_URI, "Value")
.item(0);
return value.getTextContent();
}
}
return null;
}
/**
* Gets the foreign authentication data.<saml:Assertion>
*
* @param session
* authentication session
* @param verifyXMLSigResp
* VerifyXMLSignatureResponse from MOA-SP
* @param useUTC uses correct UTC time format
* @param useUTC indicates that authenticated citizen is a foreigner
* @param isForeigner indicates whether Austrian (false) or foreigner (true) authenticates
* @return AuthenticationData object
* @throws ConfigurationException
* while accessing configuration data
* @throws BuildException
* while building the <saml:Assertion>
*/
public static AuthenticationData buildAuthenticationData(
AuthenticationSession session, OAAuthParameter oaParam, String target)
throws ConfigurationException, BuildException {
IdentityLink identityLink = session.getIdentityLink();
AuthenticationData authData = new AuthenticationData();
VerifyXMLSignatureResponse verifyXMLSigResp = session.getXMLVerifySignatureResponse();
boolean businessService = oaParam.getBusinessService();
authData.setMajorVersion(1);
authData.setMinorVersion(0);
authData.setAssertionID(Random.nextRandom());
authData.setIssuer(session.getAuthURL());
authData.setIssueInstant(DateTimeUtils.buildDateTimeUTC(Calendar
.getInstance()));
//baseID or wbpk in case of BusinessService without SSO or BusinessService SSO
authData.setIdentificationValue(identityLink.getIdentificationValue());
authData.setIdentificationType(identityLink.getIdentificationType());
authData.setGivenName(identityLink.getGivenName());
authData.setFamilyName(identityLink.getFamilyName());
authData.setDateOfBirth(identityLink.getDateOfBirth());
authData.setQualifiedCertificate(verifyXMLSigResp
.isQualifiedCertificate());
authData.setPublicAuthority(verifyXMLSigResp.isPublicAuthority());
authData.setPublicAuthorityCode(verifyXMLSigResp
.getPublicAuthorityCode());
authData.setBkuURL(session.getBkuURL());
try {
if (session.getUseMandate() && session.isOW()) {
MISMandate mandate = session.getMISMandate();
authData.setBPK(mandate.getOWbPK());
authData.setBPKType(Constants.URN_PREFIX_CDID + "+" + "OW");
authData.setIdentityLink(identityLink);
Logger.trace("Authenticated User is OW: " + mandate.getOWbPK());
} else {
if (businessService) {
//since we have foreigner, wbPK is not calculated in BKU
if(identityLink.getIdentificationType().equals(Constants.URN_PREFIX_BASEID)) {
String registerAndOrdNr = oaParam.getIdentityLinkDomainIdentifier();
if (registerAndOrdNr.startsWith(AuthenticationSession.REGISTERANDORDNR_PREFIX_)) {
// If domainIdentifier starts with prefix
// "urn:publicid:gv.at:wbpk+"; remove this prefix
registerAndOrdNr = registerAndOrdNr
.substring(AuthenticationSession.REGISTERANDORDNR_PREFIX_.length());
Logger.debug("Register and ordernumber prefix stripped off; resulting register string: "
+ registerAndOrdNr);
}
String wbpkBase64 = new BPKBuilder().buildWBPK(identityLink.getIdentificationValue(), registerAndOrdNr);
authData.setBPK(wbpkBase64);
authData.setBPKType( Constants.URN_PREFIX_WBPK + "+" + registerAndOrdNr);
} else {
authData.setBPK(identityLink.getIdentificationValue());
authData.setBPKType(identityLink.getIdentificationType());
}
Logger.trace("Authenticate user with wbPK " + authData.getBPK());
Element idlassertion = session.getIdentityLink().getSamlAssertion();
//set bpk/wpbk;
Node prIdentification = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_IDENT_VALUE_XPATH);
prIdentification.getFirstChild().setNodeValue(authData.getBPK());
//set bkp/wpbk type
Node prIdentificationType = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_IDENT_TYPE_XPATH);
prIdentificationType.getFirstChild().setNodeValue(authData.getBPKType());
IdentityLinkAssertionParser idlparser = new IdentityLinkAssertionParser(idlassertion);
IdentityLink idl = idlparser.parseIdentityLink();
authData.setIdentityLink(idl);
} else {
if(identityLink.getIdentificationType().equals(Constants.URN_PREFIX_BASEID)) {
// only compute bPK if online application is a public service and we have the Stammzahl
String bpkBase64 = new BPKBuilder().buildBPK(identityLink.getIdentificationValue(), target);
authData.setBPK(bpkBase64);
authData.setBPKType(Constants.URN_PREFIX_CDID + "+" + oaParam.getTarget());
}
Logger.trace("Authenticate user with bPK " + authData.getBPK());
authData.setIdentityLink(identityLink);
}
}
return authData;
} catch (Throwable ex) {
throw new BuildException("builder.00", new Object[] {
"AuthenticationData", ex.toString() }, ex);
}
}
/**
* Retrieves a session from the session store.
*
* @param id
* session ID
* @return AuthenticationSession
stored with given session ID,
* null
if session ID unknown
*/
public static AuthenticationSession getSession(String id)
throws AuthenticationException {
AuthenticationSession session;
try {
session = AuthenticationSessionStoreage.getSession(id);
if (session == null)
throw new AuthenticationException("auth.02", new Object[] { id });
return session;
} catch (MOADatabaseException e) {
throw new AuthenticationException("parser.04", new Object[] { id });
}
}
/**
* Cleans up expired session and authentication data stores.
*/
public void cleanup() {
long now = new Date().getTime();
//clean AuthenticationSessionStore
AuthenticationSessionStoreage.clean(now, sessionTimeOutCreated, sessionTimeOutUpdated);
//clean AssertionStore
AssertionStorage assertionstore = AssertionStorage.getInstance();
assertionstore.clean(now, authDataTimeOut);
//clean ExeptionStore
DBExceptionStoreImpl exstore = DBExceptionStoreImpl.getStore();
exstore.clean(now, authDataTimeOut);
}
/**
* Sets the sessionTimeOut.
*
* @param seconds
* Time out of the session in seconds
*/
public void setSecondsSessionTimeOutCreated(long seconds) {
sessionTimeOutCreated = seconds * 1000;
}
public void setSecondsSessionTimeOutUpdated(long seconds) {
sessionTimeOutUpdated = seconds * 1000;
}
/**
* Sets the authDataTimeOut.
*
* @param seconds
* Time out for signing AuthData in seconds
*/
public void setSecondsAuthDataTimeOut(long seconds) {
authDataTimeOut = seconds * 1000;
}
/**
* Checks a parameter.
*
* @param param
* parameter
* @return true if the parameter is null or empty
*/
private boolean isEmpty(String param) {
return param == null || param.length() == 0;
}
/**
* Checks the correctness of SAML attributes and returns its value.
*
* @param param
* samlAttribute
* @param i
* the number of the verified attribute for messages
* @param identifier
* the infobox identifier for messages
* @param friendlyname
* the friendly name of the infobox for messages
* @return the SAML attribute value (Element or String)
*/
protected static Object verifySAMLAttribute(
ExtendedSAMLAttribute samlAttribute, int i, String identifier,
String friendlyName) throws ValidateException {
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" });
}
return value;
}
/**
* Does the request to the SZR-GW
* @param oaFriendlyName
* @param signature XMLDSIG signature
* @return Identity link assertion
* @throws SZRGWClientException
*/
public CreateIdentityLinkResponse getIdentityLink(String PEPSIdentifier, String PEPSFirstname, String PEPSFamilyname, String PEPSDateOfBirth, String gender, String citizenSignature, String represented, String representative, String mandateContent, String organizationAddress, String organizationType, String targetType, String targetValue, String oaFriendlyName, String filters) throws SZRGWClientException {
try {
AuthConfigurationProvider authConf = AuthConfigurationProvider.getInstance();
ConnectionParameter connectionParameters = authConf.getForeignIDConnectionParameter();
SZRGWClient client = new SZRGWClient(connectionParameters);
CreateIdentityLinkRequest request = new CreateIdentityLinkRequest();
request.setSignature(citizenSignature.getBytes());
PEPSData data = new PEPSData();
data.setDateOfBirth(PEPSDateOfBirth);
data.setFamilyname(PEPSFamilyname);
data.setFirstname(PEPSFirstname);
data.setIdentifier(PEPSIdentifier);
data.setRepresentative(representative);
data.setRepresented(represented);
data.setMandateContent(mandateContent);
data.setLegalPersonCanonicalRegisteredAddress(organizationAddress);
data.setLegalPersonTranslatableType(organizationType);
if(null != mandateContent) {
MISType mis = new MISType();
Target targetObject = new Target();
targetObject.setType(targetType);
targetObject.setValue(targetValue);
mis.setTarget(targetObject);
mis.setOAFriendlyName(oaFriendlyName);
Filters filterObject = new Filters();
MandateIdentifiers mandateIds = new MandateIdentifiers();
for(String current : filters.split(","))
mandateIds.getMandateIdentifier().add(current.trim());
filterObject.setMandateIdentifiers(mandateIds);
mis.setFilters(filterObject);
request.setMIS(mis);
}
Logger.info("Starte Kommunikation mit dem Stammzahlenregister Gateway(" + connectionParameters.getUrl() + ")...");
CreateIdentityLinkResponse response = client.sentCreateIDLRequest(request , connectionParameters.getUrl());
return response;
}
catch (ConfigurationException e) {
Logger.warn(e);
Logger.warn(MOAIDMessageProvider.getInstance().getMessage("config.12", null ));
}
return null;
}
/**
* Does the request to the SZR-GW.
*
* @param signature the signature
* @return the identity link
* @throws SZRGWClientException the sZRGW client exception
* @throws ConfigurationException the configuration exception
*/
public CreateIdentityLinkResponse getIdentityLink(Element signature) throws SZRGWClientException, ConfigurationException {
return getIdentityLink(null, null, null, null, XMLHelper.nodeToString(signature));
}
/**
* Does the request to the SZR-GW.
*
* @param PEPSIdentifier the pEPS identifier
* @param PEPSFirstname the pEPS firstname
* @param PEPSFamilyname the pEPS familyname
* @param PEPSDateOfBirth the pEPS date of birth
* @param signature XMLDSIG signature
* @return Identity link assertion
* @throws SZRGWClientException the sZRGW client exception
* @throws ConfigurationException the configuration exception
*/
public CreateIdentityLinkResponse getIdentityLink(String PEPSIdentifier, String PEPSFirstname, String PEPSFamilyname, String PEPSDateOfBirth, String signature) throws SZRGWClientException {
return getIdentityLink(PEPSIdentifier, PEPSFirstname, PEPSFamilyname, PEPSDateOfBirth, null, signature, null, null, null, null, null, null, null);
}
/**
* Gets the identity link.
*
* @param citizenSignature the citizen signature
* @param representative the representative
* @param represented the represented
* @param mandate the mandate
* @param organizationAddress the organization address
* @param organizationType the organization type
* @return the identity link
* @throws SZRGWClientException
*/
public CreateIdentityLinkResponse getIdentityLink(String citizenSignature,
String representative, String represented, String mandateContent,
String organizationAddress, String organizationType, String targetType, String targetValue, String oaFriendlyName, String filters) throws SZRGWClientException {
return getIdentityLink(null, null, null, null, null,
citizenSignature, represented, representative, mandateContent, organizationAddress,
organizationType, targetType, targetValue, oaFriendlyName, filters);
}
/**
* SZR-GW Client interface.
*
* @param eIdentifier the e identifier
* @param givenName the given name
* @param lastName the last name
* @param dateOfBirth the date of birth
* @param citizenSignature the citizen signature
* @param representative the representative
* @param represented the represented
* @param mandate the mandate
* @return the identity link
* @throws SZRGWClientException the sZRGW client exception
*/
public CreateIdentityLinkResponse getIdentityLink(String eIdentifier,
String givenName, String lastName, String dateOfBirth, String gender,
String citizenSignature, String representative, String represented,
String mandate, String targetType, String targetValue, String oaFriendlyName, String filters) throws SZRGWClientException {
return getIdentityLink(eIdentifier, givenName, lastName, dateOfBirth, gender,
citizenSignature, representative, represented, mandate, null,
null, targetType, targetValue, oaFriendlyName, filters);
}
/**
* Starts a MOA-ID authentication process using STORK
* @param req HttpServletRequest
* @param resp HttpServletResponse
* @param ccc Citizen country code
* @param oaURL URL of the online application
* @param target Target parameter
* @param targetFriendlyName Friendly Name of Target
* @param authURL Authentication URL
* @param sourceID SourceID parameter
* @throws MOAIDException
* @throws AuthenticationException
* @throws WrongParametersException
* @throws ConfigurationException
*/
public static void startSTORKAuthentication(
HttpServletRequest req,
HttpServletResponse resp,
AuthenticationSession moasession) throws MOAIDException, AuthenticationException, WrongParametersException, ConfigurationException {
if (moasession == null) {
throw new AuthenticationException("auth.18", new Object[] { });
}
//read configuration paramters of OA
OAAuthParameter oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(moasession.getPublicOAURLPrefix());
if (oaParam == null)
throw new AuthenticationException("auth.00", new Object[] { moasession.getPublicOAURLPrefix() });
//Start of STORK Processing
STORKConfig storkConfig = AuthConfigurationProvider.getInstance().getStorkConfig();
CPEPS cpeps = storkConfig.getCPEPS(moasession.getCcc());
Logger.debug("Preparing to assemble STORK AuthnRequest with the following values:");
String destination = cpeps.getPepsURL().toExternalForm();
Logger.debug("C-PEPS URL: " + destination);
String acsURL = HTTPUtils.getBaseURL(req) + PEPSConnectorServlet.PEPSCONNECTOR_SERVLET_URL_PATTERN;
Logger.debug("MOA Assertion Consumer URL (PEPSConnctor): " + acsURL);
String providerName= oaParam.getFriendlyName();
String issuerValue = HTTPUtils.getBaseURL(req);
Logger.debug("Issuer value: " + issuerValue);
// prepare collection of required attributes
// - attributes for online application
List