From dd45e938564249a5e6897bd92dd29808d8990868 Mon Sep 17 00:00:00 2001 From: rudolf Date: Fri, 24 Oct 2003 08:34:56 +0000 Subject: MOA-ID version 1.1 (initial) git-svn-id: https://joinup.ec.europa.eu/svn/moa-idspss/trunk@19 d688527b-c9ab-4aba-bd8d-4036d912da1d --- .../moa/id/auth/AuthenticationServer.java | 648 +++++++++++++++++++++ 1 file changed, 648 insertions(+) create mode 100644 id.server/src/at/gv/egovernment/moa/id/auth/AuthenticationServer.java (limited to 'id.server/src/at/gv/egovernment/moa/id/auth/AuthenticationServer.java') diff --git a/id.server/src/at/gv/egovernment/moa/id/auth/AuthenticationServer.java b/id.server/src/at/gv/egovernment/moa/id/auth/AuthenticationServer.java new file mode 100644 index 000000000..e9d9c7175 --- /dev/null +++ b/id.server/src/at/gv/egovernment/moa/id/auth/AuthenticationServer.java @@ -0,0 +1,648 @@ +package at.gv.egovernment.moa.id.auth; + +import iaik.pki.PKIException; + +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.w3c.dom.Element; + +import at.gv.egovernment.moa.id.AuthenticationException; +import at.gv.egovernment.moa.id.BuildException; +import at.gv.egovernment.moa.id.ParseException; +import at.gv.egovernment.moa.id.ServiceException; +import at.gv.egovernment.moa.id.auth.builder.AuthenticationBlockAssertionBuilder; +import at.gv.egovernment.moa.id.auth.builder.AuthenticationDataAssertionBuilder; +import at.gv.egovernment.moa.id.auth.builder.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.PersonDataBuilder; +import at.gv.egovernment.moa.id.auth.builder.SAMLArtifactBuilder; +import at.gv.egovernment.moa.id.auth.builder.SelectBKUFormBuilder; +import at.gv.egovernment.moa.id.auth.builder.VPKBuilder; +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.IdentityLink; +import at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse; +import at.gv.egovernment.moa.id.auth.invoke.SignatureVerificationInvoker; +import at.gv.egovernment.moa.id.auth.parser.CreateXMLSignatureResponseParser; +import at.gv.egovernment.moa.id.auth.parser.InfoboxReadResponseParser; +import at.gv.egovernment.moa.id.auth.parser.SAMLArtifactParser; +import at.gv.egovernment.moa.id.auth.parser.VerifyXMLSignatureResponseParser; +import at.gv.egovernment.moa.id.auth.servlet.AuthServlet; +import at.gv.egovernment.moa.id.auth.validator.CreateXMLSignatureResponseValidator; +import at.gv.egovernment.moa.id.auth.validator.IdentityLinkValidator; +import at.gv.egovernment.moa.id.auth.validator.ValidateException; +import at.gv.egovernment.moa.id.auth.validator.VerifyXMLSignatureResponseValidator; +import at.gv.egovernment.moa.id.config.ConfigurationException; +import at.gv.egovernment.moa.id.config.ConfigurationProvider; +import at.gv.egovernment.moa.id.config.ConnectionParameter; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; +import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; +import at.gv.egovernment.moa.id.data.AuthenticationData; +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.logging.Logger; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.util.DateTimeUtils; +import at.gv.egovernment.moa.util.FileUtils; + +/** + * 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$ + */ +public class AuthenticationServer implements MOAIDAuthConstants { + + /** single instance */ + private static AuthenticationServer instance; + /** session data store (session ID -> AuthenticationSession) */ + private static Map sessionStore = new HashMap(); + /** authentication data store (assertion handle -> AuthenticationData) */ + private static Map authenticationDataStore = new HashMap(); + /** + * time out in milliseconds used by {@link cleanup} for session store + */ + private long sessionTimeOut = 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 request to select a BKU. + *
Processing depends on value of {@link AuthConfigurationProvider#getBKUSelectionType}. + *
For bkuSelectionType==HTMLComplete, a returnURI for the + * "BKU Auswahl" service is returned. + *
For bkuSelectionType==HTMLSelect, an HTML form for BKU selection is returned. + * @param authURL base URL of MOA-ID Auth component + * @param target "Geschäftsbereich" + * @param oaURL online application URL requested + * @param bkuSelectionTemplateURL template for BKU selection form to be used + * in case of HTMLSelect; may be null + * @param templateURL URL providing an HTML template for the HTML form to be used + * for call startAuthentication + * @return for bkuSelectionType==HTMLComplete, the returnURI for the + * "BKU Auswahl" service; + * for bkuSelectionType==HTMLSelect, an HTML form for BKU selection + * @throws WrongParametersException upon missing parameters + * @throws AuthenticationException when the configured BKU selection service cannot be reached, + * and when the given bkuSelectionTemplateURL cannot be reached + * @throws ConfigurationException on missing configuration data + * @throws BuildException while building the HTML form + */ + public String selectBKU( + String authURL, String target, String oaURL, String bkuSelectionTemplateURL, String templateURL) + throws WrongParametersException, AuthenticationException, ConfigurationException, BuildException { + + if (isEmpty(authURL)) + throw new WrongParametersException("StartAuthentication", "AuthURL"); + if (isEmpty(target)) + throw new WrongParametersException("StartAuthentication", PARAM_TARGET); + if (isEmpty(oaURL)) + throw new WrongParametersException("StartAuthentication", PARAM_OA); + if (! authURL.startsWith("https:")) + throw new AuthenticationException("auth.07", null); + ConnectionParameter bkuConnParam = AuthConfigurationProvider.getInstance().getBKUConnectionParameter(); + if (bkuConnParam == null) + throw new ConfigurationException("config.08", new Object[] {"BKUSelection/ConnectionParameter"}); + OAAuthParameter oaParam = + AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(oaURL); + if (oaParam == null) + throw new AuthenticationException("auth.00", new Object[] {oaURL}); + AuthenticationSession session = newSession(); + Logger.info("MOASession " + session.getSessionID() + " angelegt"); + session.setTarget(target); + session.setOAURLRequested(oaURL); + session.setPublicOAURLPrefix(oaParam.getPublicURLPrefix()); + session.setAuthURL(authURL); + session.setTemplateURL(templateURL); + String returnURL = new DataURLBuilder().buildDataURL(authURL, REQ_START_AUTHENTICATION, session.getSessionID()); + String bkuSelectionType = AuthConfigurationProvider.getInstance().getBKUSelectionType(); + if (bkuSelectionType.equals(AuthConfigurationProvider.BKU_SELECTION_TYPE_HTMLCOMPLETE)) { + // bkuSelectionType==HTMLComplete + String redirectURL = bkuConnParam.getUrl() + "?" + AuthServlet.PARAM_RETURN + "=" + returnURL; + return redirectURL; + } + else { + // bkuSelectionType==HTMLSelect + String bkuSelectTag; + try { + bkuSelectTag = readBKUSelectTag(AuthConfigurationProvider.getInstance(), bkuConnParam); + } + catch (Throwable ex) { + throw new AuthenticationException("auth.03", new Object[] {bkuConnParam.getUrl(), ex.toString()}, ex); + } + String bkuSelectionTemplate = null; + if (bkuSelectionTemplateURL != null) { + try { + bkuSelectionTemplate = new String(FileUtils.readURL(bkuSelectionTemplateURL)); + } + catch (IOException ex) { + throw new AuthenticationException("auth.03", new Object[] {bkuSelectionTemplateURL, ex.toString()}, ex); + } + } + String htmlForm = new SelectBKUFormBuilder().build(bkuSelectionTemplate, returnURL, bkuSelectTag); + return htmlForm; + } + } + /** + * Method readBKUSelectTag. + * @param conf the ConfigurationProvider + * @param connParam the ConnectionParameter for that connection + * @return String + * @throws ConfigurationException on config-errors + * @throws PKIException on PKI errors + * @throws IOException on any data error + * @throws GeneralSecurityException on security errors + */ + private String readBKUSelectTag(ConfigurationProvider conf, ConnectionParameter connParam) + throws ConfigurationException, PKIException, IOException, GeneralSecurityException { + + if (connParam.isHTTPSURL()) + return new String(SSLUtils.readHttpsURL(conf, connParam)); + else + return new String(FileUtils.readURL(connParam.getUrl())); + } + /** + * Processes the beginning of an authentication session. + * + * @param authURL URL of the servlet to be used as data URL + * @param target "Geschäftsbereich" of the online application requested + * @param oaURL online application URL requested + * @param bkuURL URL of the "Bürgerkartenumgebung" to be used; + * may be null; in this case, the default location will be used + * @param templateURL URL providing an HTML template for the HTML form generated + * @return HTML form + * @throws AuthenticationException + * @see GetIdentityLinkFormBuilder + * @see InfoboxReadRequestBuilder + */ + public String startAuthentication( + String authURL, String target, String oaURL, String templateURL, String bkuURL, String sessionID) + throws WrongParametersException, AuthenticationException, ConfigurationException, BuildException { + + if (isEmpty(sessionID)) { + if (isEmpty(authURL)) + throw new WrongParametersException("StartAuthentication", "AuthURL"); + if (! authURL.startsWith("https:")) + throw new AuthenticationException("auth.07", null); + if (isEmpty(target)) + throw new WrongParametersException("StartAuthentication", PARAM_TARGET); + if (isEmpty(oaURL)) + throw new WrongParametersException("StartAuthentication", PARAM_OA); + } + AuthenticationSession session; + if (sessionID != null) + session = getSession(sessionID); + else { + OAAuthParameter oaParam = + AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(oaURL); + if (oaParam == null) + throw new AuthenticationException("auth.00", new Object[] {oaURL}); + session = newSession(); + Logger.info("MOASession " + session.getSessionID() + " angelegt"); + session.setTarget(target); + session.setOAURLRequested(oaURL); + session.setPublicOAURLPrefix(oaParam.getPublicURLPrefix()); + session.setAuthURL(authURL); + session.setTemplateURL(templateURL); + } + String infoboxReadRequest = new InfoboxReadRequestBuilder().build(); + String dataURL = new DataURLBuilder().buildDataURL( + session.getAuthURL(), REQ_VERIFY_IDENTITY_LINK, session.getSessionID()); + 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 certInfoRequest = new CertInfoVerifyXMLSignatureRequestBuilder().build(); + String certInfoDataURL = new DataURLBuilder().buildDataURL( + session.getAuthURL(), REQ_START_AUTHENTICATION, session.getSessionID()); + String htmlForm = new GetIdentityLinkFormBuilder().build( + template, bkuURL, infoboxReadRequest, dataURL, certInfoRequest, certInfoDataURL); + return htmlForm; + } + /** + * Processes an <InfoboxReadResponse> sent by the + * security layer implementation.
+ * + * + * @param sessionID ID of associated authentication session data + * @param xmlInfoboxReadResponse String representation of the + * <InfoboxReadResponse> + * @return String representation of the <CreateXMLSignatureRequest> + */ + public String verifyIdentityLink (String sessionID, String xmlInfoboxReadResponse) + throws AuthenticationException, ParseException, ConfigurationException, ValidateException, ServiceException, WrongParametersException { + + if (isEmpty(sessionID)) + throw new WrongParametersException("VerifyAuthenticationBlock", PARAM_SESSIONID); + if (isEmpty(xmlInfoboxReadResponse)) + throw new WrongParametersException("VerifyAuthenticationBlock", PARAM_XMLRESPONSE); + AuthenticationSession session = getSession(sessionID); + if (session.getTimestampIdentityLink() != null) + throw new AuthenticationException("auth.01", new Object[] {sessionID}); + session.setTimestampIdentityLink(); + AuthConfigurationProvider authConf = AuthConfigurationProvider.getInstance(); + // parses the + IdentityLink identityLink = new InfoboxReadResponseParser(xmlInfoboxReadResponse). + parseIdentityLink(); + // validates the identity link + IdentityLinkValidator.getInstance().validate(identityLink); + // builds a for a call of MOA-SP + Element domVerifyXMLSignatureRequest = new VerifyXMLSignatureRequestBuilder().build( + identityLink, authConf.getMoaSpIdentityLinkTrustProfileID()); + // debug output + debugOutputXMLFile("VerifyIdentityLinkRequest.xml", domVerifyXMLSignatureRequest); + // invokes the call + Element domVerifyXMLSignatureResponse = new SignatureVerificationInvoker(). + verifyXMLSignature(domVerifyXMLSignatureRequest); + // parses the + VerifyXMLSignatureResponse verifyXMLSignatureResponse = + new VerifyXMLSignatureResponseParser(domVerifyXMLSignatureResponse).parseData(); + // debug output + debugOutputXMLFile("VerifyIdentityLinkResponse.xml", domVerifyXMLSignatureResponse); + // validates the + VerifyXMLSignatureResponseValidator.getInstance().validate( + verifyXMLSignatureResponse, + authConf.getIdentityLinkX509SubjectNames(), + VerifyXMLSignatureResponseValidator.CHECK_IDENTITY_LINK); + + session.setIdentityLink(identityLink); + // builds the AUTH-block + String authBlock = buildAuthenticationBlock(session); + session.setAuthBlock(authBlock); + // builds the + String[] transformInfos = authConf.getTransformsInfos(); + String createXMLSignatureRequest = new CreateXMLSignatureRequestBuilder(). + build(authBlock, transformInfos); + return createXMLSignatureRequest; + } + /** + * Builds an authentication block <saml:Assertion> from given session data. + * @param session authentication session + * @return <saml:Assertion> as a String + */ + private String buildAuthenticationBlock(AuthenticationSession session) { + IdentityLink identityLink = session.getIdentityLink(); + String issuer = identityLink.getGivenName() + " " + identityLink.getFamilyName(); + String issueInstant = DateTimeUtils.buildDateTime(Calendar.getInstance()); + String authURL = session.getAuthURL(); + String target = session.getTarget(); + String oaURL = session.getPublicOAURLPrefix(); + String authBlock = new AuthenticationBlockAssertionBuilder(). + build(issuer, issueInstant, authURL, target, oaURL); + return authBlock; + } + /** + * Processes a <CreateXMLSignatureResponse> sent by the + * security layer implementation.
+ *
    + *
  • Validates given <CreateXMLSignatureResponse>
  • + *
  • Parses <CreateXMLSignatureResponse> for error codes
  • + *
  • Parses authentication block enclosed in + * <CreateXMLSignatureResponse>
  • + *
  • Verifies authentication block by calling the MOA SP component
  • + *
  • Creates authentication data
  • + *
  • Creates a corresponding SAML artifact
  • + *
  • Stores authentication data in the authentication data store + * indexed by the SAML artifact
  • + *
  • Deletes authentication session
  • + *
  • Returns the SAML artifact, encoded BASE64
  • + *
+ * + * @param sessionID session ID of the running authentication session + * @param xmlCreateXMLSignatureReadResponse String representation of the + * <CreateXMLSignatureResponse> + * @return SAML artifact needed for retrieving authentication data, encoded BASE64 + */ + public String verifyAuthenticationBlock( + String sessionID, String xmlCreateXMLSignatureReadResponse) + throws AuthenticationException, BuildException, ParseException, ConfigurationException, ServiceException, ValidateException, WrongParametersException { + + if (isEmpty(sessionID)) + throw new WrongParametersException("VerifyAuthenticationBlock", PARAM_SESSIONID); + if (isEmpty(xmlCreateXMLSignatureReadResponse)) + throw new WrongParametersException("VerifyAuthenticationBlock", PARAM_XMLRESPONSE); + AuthenticationSession session = getSession(sessionID); + AuthConfigurationProvider authConf = AuthConfigurationProvider.getInstance(); + // parses + CreateXMLSignatureResponse csresp = + new CreateXMLSignatureResponseParser(xmlCreateXMLSignatureReadResponse).parseResponse(); + // validates + new CreateXMLSignatureResponseValidator().validate(csresp, session.getTarget(), session.getPublicOAURLPrefix()); + // builds a for a MOA-SPSS call + String[] vtids = authConf.getMoaSpAuthBlockVerifyTransformsInfoIDs(); + String tpid = authConf.getMoaSpAuthBlockTrustProfileID(); + Element domVsreq = new VerifyXMLSignatureRequestBuilder().build(csresp, vtids, tpid); + // debug output + AuthenticationServer.debugOutputXMLFile("VerifyAuthenticationBlockRequest.xml", domVsreq); + // invokes the call + Element domVsresp = new SignatureVerificationInvoker().verifyXMLSignature(domVsreq); + // parses the + VerifyXMLSignatureResponse vsresp = new VerifyXMLSignatureResponseParser(domVsresp).parseData(); + // debug output + AuthenticationServer.debugOutputXMLFile("VerifyAuthenticationBlockResponse.xml", domVsresp); + // validates the + VerifyXMLSignatureResponseValidator.getInstance().validate( + vsresp, null,VerifyXMLSignatureResponseValidator.CHECK_AUTH_BLOCK); + // compares the public keys from the identityLink with the AuthBlock + VerifyXMLSignatureResponseValidator.getInstance().validateCertificate(vsresp, session.getIdentityLink()); + + // builds authentication data and stores it together with a SAML artifact + AuthenticationData authData = buildAuthenticationData(session, vsresp); + String samlArtifact = new SAMLArtifactBuilder().build(session.getAuthURL(), session.getSessionID()); + storeAuthenticationData(samlArtifact, authData); + // invalidates the authentication session + sessionStore.remove(sessionID); + Logger.info("Anmeldedaten zu MOASession " + sessionID + " angelegt, SAML Artifakt " + samlArtifact); + return samlArtifact; + } + /** + * Builds the AuthenticationData object together with the + * corresponding <saml:Assertion> + * @param session authentication session + * @param verifyXMLSigResp VerifyXMLSignatureResponse from MOA-SP + * @return AuthenticationData object + * @throws ConfigurationException while accessing configuration data + * @throws BuildException while building the <saml:Assertion> + */ + private AuthenticationData buildAuthenticationData( + AuthenticationSession session, + VerifyXMLSignatureResponse verifyXMLSigResp) + throws ConfigurationException, BuildException { + + IdentityLink identityLink = session.getIdentityLink(); + AuthenticationData authData = new AuthenticationData(); + authData.setMajorVersion(1); + authData.setMinorVersion(0); + authData.setAssertionID(Random.nextRandom()); + authData.setIssuer(session.getAuthURL()); + authData.setIssueInstant(DateTimeUtils.buildDateTime(Calendar.getInstance())); + String vpkBase64 = new VPKBuilder().buildVPK( + identityLink.getIdentificationValue(), identityLink.getDateOfBirth(), session.getTarget()); + authData.setVPK(vpkBase64); + authData.setGivenName(identityLink.getGivenName()); + authData.setFamilyName(identityLink.getFamilyName()); + authData.setDateOfBirth(identityLink.getDateOfBirth()); + authData.setQualifiedCertificate(verifyXMLSigResp.isQualifiedCertificate()); + authData.setPublicAuthority(verifyXMLSigResp.isPublicAuthority()); + authData.setPublicAuthorityCode(verifyXMLSigResp.getPublicAuthorityCode()); + OAAuthParameter oaParam = + AuthConfigurationProvider.getInstance().getOnlineApplicationParameter( + session.getPublicOAURLPrefix()); + String prPerson = new PersonDataBuilder().build( + identityLink, oaParam.getProvideZMRZahl()); + + try { + String ilAssertion = + oaParam.getProvideIdentityLink() ? DOMUtils.serializeNode(identityLink.getSamlAssertion()) : ""; + String authBlock = oaParam.getProvideAuthBlock() ? session.getAuthBlock() : ""; + String samlAssertion = new AuthenticationDataAssertionBuilder().build( + authData, prPerson, authBlock, ilAssertion); + authData.setSamlAssertion(samlAssertion); + return authData; + } + catch (Throwable ex) { + throw new BuildException( + "builder.00", + new Object[] { "AuthenticationData", ex.toString() }, + ex); + } + } + /** + * Retrieves AuthenticationData indexed by the SAML artifact. + * The AuthenticationData is deleted from the store upon end of this call. + * + * @return AuthenticationData + */ + public AuthenticationData getAuthenticationData(String samlArtifact) throws AuthenticationException { + String assertionHandle; + try { + assertionHandle = new SAMLArtifactParser(samlArtifact).parseAssertionHandle(); + } + catch (ParseException ex) { + throw new AuthenticationException("1205", new Object[] {samlArtifact, ex.toString()}); + } + AuthenticationData authData = null; + synchronized (authenticationDataStore) { + authData = (AuthenticationData)authenticationDataStore.get(assertionHandle); + if (authData == null) { + Logger.error("Assertion not found for SAML Artifact: " + samlArtifact); + throw new AuthenticationException("1206", new Object[] {samlArtifact}); + } + authenticationDataStore.remove(assertionHandle); + } + long now = new Date().getTime(); + if (now - authData.getTimestamp().getTime() > authDataTimeOut) + throw new AuthenticationException("1207", new Object[] {samlArtifact}); + Logger.debug("Assertion delivered for SAML Artifact: " + samlArtifact); + return authData; + } + /** + * Stores authentication data indexed by the assertion handle contained in the + * given saml artifact. + * @param samlArtifact SAML artifact + * @param authData authentication data + * @throws AuthenticationException when SAML artifact is invalid + */ + private void storeAuthenticationData(String samlArtifact, AuthenticationData authData) + throws AuthenticationException { + + try { + SAMLArtifactParser parser = new SAMLArtifactParser(samlArtifact); + // check type code 0x0001 + byte[] typeCode = parser.parseTypeCode(); + if (typeCode[0] != 0 || typeCode[1] != 1) + throw new AuthenticationException("auth.06", new Object[] {samlArtifact}); + String assertionHandle = parser.parseAssertionHandle(); + synchronized(authenticationDataStore) { + Logger.debug("Assertion stored for SAML Artifact: " + samlArtifact); + authenticationDataStore.put(assertionHandle, authData); + } + } + catch (AuthenticationException ex) { + throw ex; + } + catch (Throwable ex) { + throw new AuthenticationException("auth.06", new Object[] {samlArtifact}); + } + } + /** + * Creates a new session and puts it into the session store. + * + * @param id Session ID + * @return AuthenticationSession created + * @exception AuthenticationException + * thrown when an AuthenticationSession is running + * already for the given session ID + */ + private static AuthenticationSession newSession() throws AuthenticationException { + String sessionID = Random.nextRandom(); + AuthenticationSession newSession = new AuthenticationSession(sessionID); + synchronized (sessionStore) { + AuthenticationSession session = (AuthenticationSession)sessionStore.get(sessionID); + if (session != null) + throw new AuthenticationException("auth.01", new Object[] { sessionID }); + sessionStore.put(sessionID, newSession); + } + return newSession; + } + /** + * 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 = (AuthenticationSession)sessionStore.get(id); + if (session == null) + throw new AuthenticationException("auth.02", new Object[] { id }); + return session; + } + /** + * Cleans up expired session and authentication data stores. + */ + public void cleanup() { + long now = new Date().getTime(); + synchronized(sessionStore) { + Set keys = new HashSet(sessionStore.keySet()); + for (Iterator iter = keys.iterator(); iter.hasNext(); ) { + String sessionID = (String) iter.next(); + AuthenticationSession session = (AuthenticationSession) sessionStore.get(sessionID); + if (now - session.getTimestampStart().getTime() > sessionTimeOut) { + Logger.info(MOAIDMessageProvider.getInstance().getMessage("cleaner.02", new Object[] {sessionID})); + sessionStore.remove(sessionID); + } + } + } + synchronized(authenticationDataStore) { + Set keys = new HashSet(authenticationDataStore.keySet()); + for (Iterator iter = keys.iterator(); iter.hasNext(); ) { + String samlArtifact = (String) iter.next(); + AuthenticationData authData = (AuthenticationData) authenticationDataStore.get(samlArtifact); + if (now - authData.getTimestamp().getTime() > authDataTimeOut) { + Logger.info(MOAIDMessageProvider.getInstance().getMessage("cleaner.03", new Object[] {samlArtifact})); + authenticationDataStore.remove(samlArtifact); + } + } + } + } + + /** + * Sets the sessionTimeOut. + * @param sessionTimeOut time out in seconds + */ + public void setSecondsSessionTimeOut(long seconds) { + sessionTimeOut = 1000 * seconds; + } + /** + * Sets the authDataTimeOut. + * @param authDataTimeOut time out in seconds + */ + public void setSecondsAuthDataTimeOut(long seconds) { + authDataTimeOut = 1000 * seconds; + } + + /** + * 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; + } + + /** + * Writes an XML structure to file for debugging purposes, encoding UTF-8. + * + * @param filename file name + * @param rootElem root element in DOM tree + */ + public static void debugOutputXMLFile(String filename, Element rootElem) { + if (Logger.isDebugEnabled(DEBUG_OUTPUT_HIERARCHY)) { + try { + String xmlString = new String(DOMUtils.serializeNode(rootElem)); + debugOutputXMLFile(filename, xmlString); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + } + /** + * Writes an XML structure to file for debugging purposes, encoding UTF-8. + * + * @param filename file name + * @param xmlString XML string + */ + public static void debugOutputXMLFile(String filename, String xmlString) { + if (Logger.isDebugEnabled(DEBUG_OUTPUT_HIERARCHY)) { + try { + java.io.OutputStream fout = new java.io.FileOutputStream(filename); + byte[] xmlData = xmlString.getBytes("UTF-8"); + fout.write(xmlData); + fout.close(); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + } +} -- cgit v1.2.3