/** * This method handles the logout requests from the IdP Any request for the defined logout URL is * handled here * * @param request * @throws javax.servlet.ServletException * @throws IOException */ public void doSLO(HttpServletRequest request) throws SSOAgentException { XMLObject saml2Object = null; if (request.getParameter(SSOAgentConstants.SAML2SSO.HTTP_POST_PARAM_SAML2_AUTH_REQ) != null) { saml2Object = SSOAgentUtils.unmarshall( new String( Base64.decode( request.getParameter( SSOAgentConstants.SAML2SSO.HTTP_POST_PARAM_SAML2_AUTH_REQ)), Charset.forName("UTF-8"))); } if (saml2Object == null) { saml2Object = SSOAgentUtils.unmarshall( new String( Base64.decode( request.getParameter(SSOAgentConstants.SAML2SSO.HTTP_POST_PARAM_SAML2_RESP)), Charset.forName("UTF-8"))); } if (saml2Object instanceof LogoutRequest) { LogoutRequest logoutRequest = (LogoutRequest) saml2Object; String sessionIndex = logoutRequest.getSessionIndexes().get(0).getSessionIndex(); Set<HttpSession> sessions = SSOAgentSessionManager.invalidateAllSessions(sessionIndex); for (HttpSession session : sessions) { session.invalidate(); } } else if (saml2Object instanceof LogoutResponse) { if (request.getSession(false) != null) { /** * Not invalidating session explicitly since there may be other listeners still waiting to * get triggered and at the end of the chain session needs to be invalidated by the system */ Set<HttpSession> sessions = SSOAgentSessionManager.invalidateAllSessions(request.getSession(false)); for (HttpSession session : sessions) { try { session.invalidate(); } catch (IllegalStateException ignore) { if (log.isDebugEnabled()) { log.debug("Ignoring exception : ", ignore); } // ignore // session is already invalidated } } } } else { throw new SSOAgentException("Invalid SAML2 Single Logout Request/Response"); } }
protected void processSSOResponse(HttpServletRequest request) throws SSOAgentException { LoggedInSessionBean sessionBean = new LoggedInSessionBean(); sessionBean.setSAML2SSO(sessionBean.new SAML2SSO()); String saml2ResponseString = new String( Base64.decode( request.getParameter(SSOAgentConstants.SAML2SSO.HTTP_POST_PARAM_SAML2_RESP)), Charset.forName("UTF-8")); Response saml2Response = (Response) SSOAgentUtils.unmarshall(saml2ResponseString); sessionBean.getSAML2SSO().setResponseString(saml2ResponseString); sessionBean.getSAML2SSO().setSAMLResponse(saml2Response); Assertion assertion = null; if (ssoAgentConfig.getSAML2().isAssertionEncrypted()) { List<EncryptedAssertion> encryptedAssertions = saml2Response.getEncryptedAssertions(); EncryptedAssertion encryptedAssertion = null; if (!org.apache.commons.collections.CollectionUtils.isEmpty(encryptedAssertions)) { encryptedAssertion = encryptedAssertions.get(0); try { assertion = getDecryptedAssertion(encryptedAssertion); } catch (Exception e) { if (log.isDebugEnabled()) { log.debug("Assertion decryption failure : ", e); } throw new SSOAgentException("Unable to decrypt the SAML2 Assertion"); } } } else { List<Assertion> assertions = saml2Response.getAssertions(); if (assertions != null && !assertions.isEmpty()) { assertion = assertions.get(0); } } if (assertion == null) { if (isNoPassive(saml2Response)) { LOGGER.log(Level.FINE, "Cannot authenticate in passive mode"); return; } throw new SSOAgentException("SAML2 Assertion not found in the Response"); } String idPEntityIdValue = assertion.getIssuer().getValue(); if (idPEntityIdValue == null || idPEntityIdValue.isEmpty()) { throw new SSOAgentException("SAML2 Response does not contain an Issuer value"); } else if (!idPEntityIdValue.equals(ssoAgentConfig.getSAML2().getIdPEntityId())) { throw new SSOAgentException("SAML2 Response Issuer verification failed"); } sessionBean.getSAML2SSO().setAssertion(assertion); // Cannot marshall SAML assertion here, before signature validation due to a weird issue in // OpenSAML // Get the subject name from the Response Object and forward it to login_action.jsp String subject = null; if (assertion.getSubject() != null && assertion.getSubject().getNameID() != null) { subject = assertion.getSubject().getNameID().getValue(); } if (subject == null) { throw new SSOAgentException("SAML2 Response does not contain the name of the subject"); } sessionBean.getSAML2SSO().setSubjectId(subject); // set the subject request.getSession().setAttribute(SSOAgentConstants.SESSION_BEAN_NAME, sessionBean); // validate audience restriction validateAudienceRestriction(assertion); // validate signature validateSignature(saml2Response, assertion); // Marshalling SAML2 assertion after signature validation due to a weird issue in OpenSAML sessionBean.getSAML2SSO().setAssertionString(marshall(assertion)); ((LoggedInSessionBean) request.getSession().getAttribute(SSOAgentConstants.SESSION_BEAN_NAME)) .getSAML2SSO() .setSubjectAttributes(getAssertionStatements(assertion)); // For removing the session when the single sign out request made by the SP itself if (ssoAgentConfig.getSAML2().isSLOEnabled()) { String sessionId = assertion.getAuthnStatements().get(0).getSessionIndex(); if (sessionId == null) { throw new SSOAgentException( "Single Logout is enabled but IdP Session ID not found in SAML2 Assertion"); } ((LoggedInSessionBean) request.getSession().getAttribute(SSOAgentConstants.SESSION_BEAN_NAME)) .getSAML2SSO() .setSessionIndex(sessionId); SSOAgentSessionManager.addAuthenticatedSession(request.getSession(false)); } request.getSession().setAttribute(SSOAgentConstants.SESSION_BEAN_NAME, sessionBean); }