/** * Updates the user's Shibboleth session with authentication information. If no session exists a * new one will be created. * * @param loginContext current login context * @param authenticationSubject subject created from the authentication method * @param authenticationMethod the method used to authenticate the subject * @param authenticationInstant the time of authentication * @param httpRequest current HTTP request * @param httpResponse current HTTP response */ protected void updateUserSession( LoginContext loginContext, Subject authenticationSubject, String authenticationMethod, DateTime authenticationInstant, HttpServletRequest httpRequest, HttpServletResponse httpResponse) { Principal authenticationPrincipal = authenticationSubject.getPrincipals().iterator().next(); LOG.debug("Updating session information for principal {}", authenticationPrincipal.getName()); Session idpSession = (Session) httpRequest.getAttribute(Session.HTTP_SESSION_BINDING_ATTRIBUTE); if (idpSession == null) { LOG.debug("Creating shibboleth session for principal {}", authenticationPrincipal.getName()); idpSession = (Session) sessionManager.createSession(); loginContext.setSessionID(idpSession.getSessionID()); addSessionCookie(httpRequest, httpResponse, idpSession); } // Merge the information in the current session subject with the information from the // login handler subject idpSession.setSubject(mergeSubjects(idpSession.getSubject(), authenticationSubject)); // Check if an existing authentication method with no updated timestamp was used (i.e. SSO // occurred); // if not record the new information AuthenticationMethodInformation authnMethodInfo = idpSession.getAuthenticationMethods().get(authenticationMethod); if (authnMethodInfo == null || authenticationInstant != null) { LOG.debug( "Recording authentication and service information in Shibboleth session for principal: {}", authenticationPrincipal.getName()); LoginHandler loginHandler = handlerManager.getLoginHandlers().get(loginContext.getAttemptedAuthnMethod()); DateTime authnInstant = authenticationInstant; if (authnInstant == null) { authnInstant = new DateTime(); } authnMethodInfo = new AuthenticationMethodInformationImpl( idpSession.getSubject(), authenticationPrincipal, authenticationMethod, authnInstant, loginHandler.getAuthenticationDuration()); } loginContext.setAuthenticationMethodInformation(authnMethodInfo); idpSession .getAuthenticationMethods() .put(authnMethodInfo.getAuthenticationMethod(), authnMethodInfo); sessionManager.indexSession(idpSession, idpSession.getPrincipalName()); ServiceInformation serviceInfo = new ServiceInformationImpl( loginContext.getRelyingPartyId(), new DateTime(), authnMethodInfo); idpSession.getServicesInformation().put(serviceInfo.getEntityID(), serviceInfo); }
/** * Adds an IdP session cookie to the outbound response. * * @param httpRequest current request * @param httpResponse current response * @param userSession user's session */ protected void addSessionCookie( HttpServletRequest httpRequest, HttpServletResponse httpResponse, Session userSession) { httpRequest.setAttribute(Session.HTTP_SESSION_BINDING_ATTRIBUTE, userSession); byte[] remoteAddress = httpRequest.getRemoteAddr().getBytes(); byte[] sessionId = userSession.getSessionID().getBytes(); String signature = null; try { MessageDigest digester = MessageDigest.getInstance("SHA"); digester.update(userSession.getSessionSecret()); digester.update(remoteAddress); digester.update(sessionId); signature = Base64.encodeBytes(digester.digest()); } catch (GeneralSecurityException e) { LOG.error("Unable to compute signature over session cookie material", e); } LOG.debug("Adding IdP session cookie to HTTP response"); StringBuilder cookieValue = new StringBuilder(); cookieValue.append(Base64.encodeBytes(remoteAddress, Base64.DONT_BREAK_LINES)).append("|"); cookieValue.append(Base64.encodeBytes(sessionId, Base64.DONT_BREAK_LINES)).append("|"); cookieValue.append(signature); String cookieDomain = HttpServletHelper.getCookieDomain(context); Cookie sessionCookie = new Cookie(IDP_SESSION_COOKIE_NAME, HTTPTransportUtils.urlEncode(cookieValue.toString())); sessionCookie.setVersion(1); if (cookieDomain != null) { sessionCookie.setDomain(cookieDomain); } sessionCookie.setPath( "".equals(httpRequest.getContextPath()) ? "/" : httpRequest.getContextPath()); sessionCookie.setSecure(httpRequest.isSecure()); httpResponse.addCookie(sessionCookie); }