From 18aa548b45c1a3eb1ca91cc06d53c6c8e4d1feee Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Fri, 13 Jun 2014 11:31:23 +0200 Subject: change PEPS communication session binding - primary SAML2 relayState parameter should be used for statefull connections but no PEPS instance support this feature from SAML2 specification - as bugfix the PEPS AuthnRequest ID attribute is used as sessiontokken because most PEPS instances return the requestID in PEPS AuthnResponse->inResponseTO attribute --- .../moa/id/auth/AuthenticationServer.java | 22 +++-- .../moa/id/auth/servlet/PEPSConnectorServlet.java | 110 ++++++++++++--------- .../id/storage/AuthenticationSessionStoreage.java | 26 +++-- 3 files changed, 92 insertions(+), 66 deletions(-) diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java index 44453afe3..a8cf5014f 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java @@ -1466,7 +1466,6 @@ public class AuthenticationServer implements MOAIDAuthConstants { */ public static AuthenticationSession getSession(String id) throws AuthenticationException { - AuthenticationSession session; try { session = AuthenticationSessionStoreage.getSession(id); @@ -1476,7 +1475,10 @@ public class AuthenticationServer implements MOAIDAuthConstants { return session; } catch (MOADatabaseException e) { - throw new AuthenticationException("parser.04", new Object[]{id}); + throw new AuthenticationException("auth.02", new Object[]{id}); + + } catch (Exception e) { + throw new AuthenticationException("parser.04", new Object[]{id}); } } @@ -1755,8 +1757,12 @@ public class AuthenticationServer implements MOAIDAuthConstants { String issuerValue = AuthConfigurationProvider.getInstance().getPublicURLPrefix(); - String acsURL = new DataURLBuilder().buildDataURL(issuerValue, - PEPSConnectorServlet.PEPSCONNECTOR_SERVLET_URL_PATTERN, moasession.getSessionID()); +// String acsURL = new DataURLBuilder().buildDataURL(issuerValue, +// PEPSConnectorServlet.PEPSCONNECTOR_SERVLET_URL_PATTERN, moasession.getSessionID()); + + //solve Problem with sessionIDs + String acsURL = issuerValue + PEPSConnectorServlet.PEPSCONNECTOR_SERVLET_URL_PATTERN; + Logger.debug("MOA Assertion Consumer URL (PEPSConnctor): " + acsURL); String providerName = oaParam.getFriendlyName(); @@ -1860,10 +1866,10 @@ public class AuthenticationServer implements MOAIDAuthConstants { //send moasession.setStorkAuthnRequest(authnRequest); - HttpSession httpSession = req.getSession(); - httpSession.setAttribute("MOA-Session-ID", moasession.getSessionID()); - + AuthenticationSessionStoreage.changeSessionID(moasession, authnRequest.getSamlId()); + + Logger.info("Preparing to send STORK AuthnRequest."); Logger.info("prepared STORKAuthnRequest: "); Logger.info(new String(authnRequest.getTokenSaml())); @@ -1886,8 +1892,8 @@ public class AuthenticationServer implements MOAIDAuthConstants { } catch (Exception e) { Logger.error("Error sending STORK SAML AuthnRequest.", e); - httpSession.invalidate(); throw new MOAIDException("stork.02", new Object[]{destination}); + } Logger.info("STORK AuthnRequest successfully successfully prepared for client with target location: " + authnRequest.getDestination()); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java index 25749c8bc..93ac84381 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java @@ -113,16 +113,50 @@ public class PEPSConnectorServlet extends AuthServlet { //check if https or only http super.checkIfHTTPisAllowed(request.getRequestURL().toString()); + + Logger.debug("Beginning to extract SAMLResponse out of HTTP Request"); + + //extract STORK Response from HTTP Request + //Decodes SAML Response + byte[] decSamlToken; + try { + decSamlToken = PEPSUtil.decodeSAMLToken(request.getParameter("SAMLResponse")); + } catch(NullPointerException e) { + Logger.error("Unable to retrieve STORK Response", e); + throw new MOAIDException("stork.04", null); + } + + //Get SAMLEngine instance + STORKSAMLEngine engine = STORKSAMLEngine.getInstance("outgoing"); + + STORKAuthnResponse authnResponse = null; + try { + //validate SAML Token + Logger.debug("Starting validation of SAML response"); + authnResponse = engine.validateSTORKAuthnResponse(decSamlToken, (String) request.getRemoteHost()); + Logger.info("SAML response succesfully verified!"); + }catch(STORKSAMLEngineException e){ + Logger.error("Failed to verify STORK SAML Response", e); + throw new MOAIDException("stork.05", null); + } + + Logger.info("STORK SAML Response message succesfully extracted"); + Logger.debug("STORK response: "); + Logger.debug(authnResponse.toString()); Logger.debug("Trying to find MOA Session-ID ..."); - String moaSessionID = request.getParameter(PARAM_SESSIONID); - + //String moaSessionID = request.getParameter(PARAM_SESSIONID); + //first use SAML2 relayState + String moaSessionID = request.getParameter("RelayState"); + // escape parameter strings moaSessionID= StringEscapeUtils.escapeHtml(moaSessionID); + //check if SAML2 relaystate includes a MOA sessionID if (StringUtils.isEmpty(moaSessionID)) { - //check if SAML2 relaystate includes a MOA sessionID - moaSessionID = request.getParameter("RelayState"); + //if relaystate is emtpty, use SAML response -> inResponseTo element as session identifier + + moaSessionID = authnResponse.getInResponseTo(); moaSessionID= StringEscapeUtils.escapeHtml(moaSessionID); if (StringUtils.isEmpty(moaSessionID)) { @@ -132,13 +166,19 @@ public class PEPSConnectorServlet extends AuthServlet { throw new AuthenticationException("auth.02", new Object[] { moaSessionID }); } else - Logger.trace("MOA SessionID " + moaSessionID + " is found in SAML2 relayState."); + Logger.trace("Use MOA SessionID " + moaSessionID + " from AuthnResponse->inResponseTo attribute."); } else - Logger.trace("MOA SessionID " + moaSessionID + " is found in http GET parameter."); + //Logger.trace("MOA SessionID " + moaSessionID + " is found in http GET parameter."); + Logger.trace("MOA SessionID " + moaSessionID + " is found in SAML2 relayState."); - if (!ParamValidatorUtils.isValidSessionID(moaSessionID)) - throw new WrongParametersException("VerifyAuthenticationBlock", PARAM_SESSIONID, "auth.12"); + /*INFO!!!! + * SAML message IDs has an different format then MOASessionIDs + * This is only a workaround because many PEPS does not support SAML2 relayState or + * MOASessionID as AttributConsumerServiceURL GET parameter + */ +// if (!ParamValidatorUtils.isValidSessionID(moaSessionID)) +// throw new WrongParametersException("VerifyAuthenticationBlock", PARAM_SESSIONID, "auth.12"); pendingRequestID = AuthenticationSessionStoreage.getPendingRequestID(moaSessionID); @@ -150,35 +190,7 @@ public class PEPSConnectorServlet extends AuthServlet { Logger.info("Found MOA sessionID: " + moaSessionID); - Logger.debug("Beginning to extract SAMLResponse out of HTTP Request"); - //extract STORK Response from HTTP Request - //Decodes SAML Response - byte[] decSamlToken; - try { - decSamlToken = PEPSUtil.decodeSAMLToken(request.getParameter("SAMLResponse")); - } catch(NullPointerException e) { - Logger.error("Unable to retrieve STORK Response", e); - throw new MOAIDException("stork.04", null); - } - - //Get SAMLEngine instance - STORKSAMLEngine engine = STORKSAMLEngine.getInstance("outgoing"); - - STORKAuthnResponse authnResponse = null; - try { - //validate SAML Token - Logger.debug("Starting validation of SAML response"); - authnResponse = engine.validateSTORKAuthnResponse(decSamlToken, (String) request.getRemoteHost()); - Logger.info("SAML response succesfully verified!"); - }catch(STORKSAMLEngineException e){ - Logger.error("Failed to verify STORK SAML Response", e); - throw new MOAIDException("stork.05", null); - } - - Logger.info("STORK SAML Response message succesfully extracted"); - Logger.debug("STORK response: "); - Logger.debug(authnResponse.toString()); String statusCodeValue = authnResponse.getStatusCode(); @@ -272,17 +284,17 @@ public class PEPSConnectorServlet extends AuthServlet { Logger.debug("fetching OAParameters from database"); - //read configuration paramters of OA - AuthenticationSession moasession; - try { - moasession = AuthenticationSessionStoreage.getSession(moaSessionID); - } catch (MOADatabaseException e2) { - Logger.error("could not retrieve moa session"); - throw new AuthenticationException("auth.01", null); - } - OAAuthParameter oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(moasession.getPublicOAURLPrefix()); +// //read configuration paramters of OA +// AuthenticationSession moasession; +// try { +// moasession = AuthenticationSessionStoreage.getSession(moaSessionID); +// } catch (MOADatabaseException e2) { +// Logger.error("could not retrieve moa session"); +// throw new AuthenticationException("auth.01", null); +// } + OAAuthParameter oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(moaSession.getPublicOAURLPrefix()); if (oaParam == null) - throw new AuthenticationException("auth.00", new Object[] { moasession.getPublicOAURLPrefix() }); + throw new AuthenticationException("auth.00", new Object[] { moaSession.getPublicOAURLPrefix() }); // retrieve target //TODO: check in case of SSO!!! @@ -293,7 +305,7 @@ public class PEPSConnectorServlet extends AuthServlet { if (id.startsWith(AuthenticationSession.REGISTERANDORDNR_PREFIX_)) targetValue = id.substring(AuthenticationSession.REGISTERANDORDNR_PREFIX_.length()); else - targetValue = moasession.getDomainIdentifier(); + targetValue = moaSession.getDomainIdentifier(); targetType = AuthenticationSession.REGISTERANDORDNR_PREFIX_; } else { targetType = AuthenticationSession.TARGET_PREFIX_; @@ -365,13 +377,13 @@ public class PEPSConnectorServlet extends AuthServlet { //TODO: found better solution, but QAA Level in response could be not supported yet try { - moasession.setQAALevel(authnResponse.getAssertions().get(0). + moaSession.setQAALevel(authnResponse.getAssertions().get(0). getAuthnStatements().get(0).getAuthnContext(). getAuthnContextClassRef().getAuthnContextClassRef()); } catch (Throwable e) { Logger.warn("STORK QAA-Level is not found in AuthnResponse. Set QAA Level to requested level"); - moasession.setQAALevel(PVPConstants.STORK_QAA_PREFIX + oaParam.getQaaLevel()); + moaSession.setQAALevel(PVPConstants.STORK_QAA_PREFIX + oaParam.getQaaLevel()); } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/AuthenticationSessionStoreage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/AuthenticationSessionStoreage.java index 27f53feed..350c4e9da 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/AuthenticationSessionStoreage.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/AuthenticationSessionStoreage.java @@ -174,21 +174,19 @@ public class AuthenticationSessionStoreage { } - public static String changeSessionID(AuthenticationSession session) - throws AuthenticationException, BuildException { - - try { + public static String changeSessionID(AuthenticationSession session, String newSessionID) throws BuildException, AuthenticationException { + try { AuthenticatedSessionStore dbsession = searchInDatabase(session.getSessionID(), true); - String id = Random.nextRandom(); + Logger.debug("Change SessionID from " + session.getSessionID() - + "to " + id); + + "to " + newSessionID); - session.setSessionID(id); + session.setSessionID(newSessionID); encryptSession(session, dbsession); - dbsession.setSessionid(id); + dbsession.setSessionid(newSessionID); dbsession.setAuthenticated(session.isAuthenticated()); //set Timestamp in this state, because automated timestamp generation is buggy in Hibernate 4.2.1 @@ -198,11 +196,21 @@ public class AuthenticationSessionStoreage { Logger.trace("Change SessionID complete."); - return id; + return newSessionID; } catch (MOADatabaseException e) { throw new AuthenticationException("TODO!", null); } + + + + } + + public static String changeSessionID(AuthenticationSession session) + throws AuthenticationException, BuildException { + String id = Random.nextRandom(); + return changeSessionID(session, id); + } public static void setAuthenticated(String moaSessionID, boolean value) { -- cgit v1.2.3