/*
* 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;
import iaik.asn1.ObjectID;
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.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.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.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.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.SSLUtils;
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.srzgw.CreateIdentityLinkRequest;
import at.gv.util.xsd.srzgw.CreateIdentityLinkRequest.PEPSData;
import at.gv.util.xsd.srzgw.CreateIdentityLinkResponse;
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 = "";
if (session.isSsoRequested()) {
//load identityLink with SSO Target
boolean isbuisness = false;
String domainIdentifier = "";
IdentificationNumber ssobusiness = AuthConfigurationProvider.getInstance().getSSOBusinessService();
if (ssobusiness != null) {
isbuisness = true;
domainIdentifier = ssobusiness.getValue();
}
//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 signature XMLDSIG signature
* @return Identity link assertion
* @throws SZRGWClientException
*/
public CreateIdentityLinkResponse getIdentityLink(String PEPSIdentifier, String PEPSFirstname, String PEPSFamilyname, String PEPSDateOfBirth, String citizenSignature, String represented, String representative, String mandateContent, String organizationAddress, String organizationType) throws SZRGWClientException {
SZRGWClient client = null;
try {
AuthConfigurationProvider authConf = AuthConfigurationProvider.getInstance();
ConnectionParameter connectionParameters = authConf.getForeignIDConnectionParameter();
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);
// TODO add MIS data
// request.setMIS(value)
Logger.info("Starte Kommunikation mit dem Stammzahlenregister Gateway(" + connectionParameters.getUrl() + ")...");
CreateIdentityLinkResponse response = client.sentCreateIDLRequest(request , connectionParameters.getUrl());
return response;
// client.setAddress(connectionParameters.getUrl());
// if (connectionParameters.getUrl().toLowerCase().startsWith("https:")) {
// Logger.debug("Initialisiere SSL Verbindung");
// try {
// client.setSSLSocketFactory(SSLUtils.getSSLSocketFactory(AuthConfigurationProvider.getInstance(), connectionParameters));
// } catch (IOException e) {
// Logger.error("Could not initialize SSL Factory", e);
// throw new SZRGWClientException("Could not initialize SSL Factory");
// } catch (GeneralSecurityException e) {
// Logger.error("Could not initialize SSL Factory", e);
// throw new SZRGWClientException("Could not initialize SSL Factory");
// } catch (PKIException e) {
// Logger.error("Could not initialize SSL Factory", e);
// throw new SZRGWClientException("Could not initialize SSL Factory");
// }
// }
}
catch (ConfigurationException e) {
Logger.warn(e);
Logger.warn(MOAIDMessageProvider.getInstance().getMessage("config.12", null ));
}
// // create request
// CreateIdentityLinkResponse response = null;
// Element request = null;
// try {
// Document doc = client.buildGetIdentityLinkRequest(PEPSIdentifier, PEPSFirstname, PEPSFamilyname, PEPSDateOfBirth, signature);
// request = doc.getDocumentElement();
//
// // send request
// response = client.createIdentityLinkResponse(request, connectionParameters.getUrl());
//
//
//
// } catch (SZRGWClientException e) {
// // give him a second try - Nach dem Starten des Tomcat wird beim ersten Mal das Client-Zertifikat offenbar vom HTTPClient nicht mitgeschickt.
//// try {
//// response = client.createIdentityLinkResponse(request);
//// }
//// catch (SZRGWClientException e1) {
//// throw new SZRGWClientException(e1);
//// }
// }
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), null, null, null);
}
/**
* 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, signature, null, null, null);
}
/**
* 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 citizenSignature, String representative, String represented,
String mandate) throws SZRGWClientException {
return getIdentityLink(eIdentifier, givenName, lastName, dateOfBirth, citizenSignature, representative, represented, mandate, null, null);
}
/**
* 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 witt 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