static void AuthorizeRequest(object sender, EventArgs e) { SessionInfo session=null; try { if (HttpContext.Current.User.Identity.IsAuthenticated && HttpContext.Current.User.Identity is FormsIdentity) { // Note: If user signed out in another window, the ticket would have been // removed from the browser and this code shoudn't be executed. // resemble the SessionInfo from the ticket. FormsIdentity loginId = (FormsIdentity) HttpContext.Current.User.Identity ; FormsAuthenticationTicket ticket = loginId.Ticket; String[] fields = ticket.UserData.Split('|'); String tokenId = fields[0]; String userDisplayName = fields[1]; SessionToken token = new SessionToken(tokenId, ticket.Expiration); session = new SessionInfo(loginId.Name, userDisplayName, token); // Initialize the session. This will throw exception if the session is no longer // valid. For eg, time-out. SessionManager.InitializeSession(session); } if (String.IsNullOrEmpty(Thread.CurrentThread.Name)) { String user = SessionManager.Current != null ? SessionManager.Current.User.Identity.Name : "Unknown"; Thread.CurrentThread.Name = String.Format(SR.WebGUILogHeader, HttpContext.Current.Request.UserHostAddress, HttpContext.Current.Request.Browser.Browser, HttpContext.Current.Request.Browser.Version, user); } } catch (SessionValidationException) { // SessionValidationException is thrown when the session id is invalid or the session already expired. // If session already expired, if (session != null && session.Credentials.SessionToken.ExpiryTime < Platform.Time) { SessionManager.SignOut(session); } else { // redirect to login screen SessionManager.TerminateSession("The current session is no longer valid.", SR.MessageCurrentSessionNoLongerValid); } } catch(Exception ex) { // log the exception ExceptionHandler.ThrowException(ex); } }
/// <summary> /// Sets up the principal for the thread and save the authentiction ticket. /// </summary> /// <param name="session"></param> public static void InitializeSession(SessionInfo session) { // this should throw exception if the session is no longer valid. It also loads the authority tokens} if (!session.Valid) { throw new Exception("This session is no longer valid"); } Current = session; string loginId = session.User.Identity.Name; var identity = session.User.Identity as CustomIdentity; if (identity == null) { Platform.CheckForNullReference(identity, "identity"); // throw exception } else { string displayName = identity.DisplayName; SessionToken token = session.Credentials.SessionToken; string[] authorities = session.Credentials.Authorities; String data = String.Format("{0}|{1}|{2}|{3}", token.Id, displayName, StringUtilities.Combine(session.User.WarningMessages,"@"), session.User.WarningsDisplayed); // the expiry time is determined by the authentication service DateTime expiryTime = token.ExpiryTime; var authTicket = new FormsAuthenticationTicket(2, // version loginId, // user name Platform.Time, // creation expiryTime, // Expiration false, // Persistent data); // User data // Now encrypt the ticket. string encryptedTicket = FormsAuthentication.Encrypt(authTicket); // Create a cookie with the encrypted data var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket); //Create an unencrypted cookie that contains the userid and the expiry time so the browser //can check for session timeout. //TODO: store the expiry time as epoch instead so we don't need to deal with format or regional settings madness var expiryCookie = new HttpCookie(GetExpiryTimeCookieName(session), DateTimeFormatter.Format(expiryTime.ToUniversalTime(), ImageServerConstants.CookieDateTimeFormat)); HttpContext.Current.Response.Cookies.Add(authCookie); HttpContext.Current.Response.Cookies.Add(expiryCookie); SessionTimeout = expiryTime.ToUniversalTime() - Platform.Time.ToUniversalTime(); } }
/// <summary> /// Gets the redirect url for the current session /// </summary> /// <param name="session"></param> /// <returns></returns> public static String GetRedirectUrl(SessionInfo session) { Platform.CheckForNullReference(session, "session"); var redirectUrl = FormsAuthentication.GetRedirectUrl(session.User.Identity.Name, false); if (VirtualPathUtility.IsAbsolute(redirectUrl) || VirtualPathUtility.IsAppRelative(redirectUrl)) { return redirectUrl; } var tokenParam = "userId=" + session.User.Identity.Name + "&sessionId=" + session.Credentials.SessionToken.Id; var uri = new UriBuilder(redirectUrl); uri.Query = string.IsNullOrEmpty(uri.Query) ? tokenParam : uri.Query.Substring(1)+"&" + tokenParam; return uri.ToString(); }
private static void ForceOtherPagesToLogout(SessionInfo session) { //NOTE: SessionTimeout.ascx must be updated if this method is modified. // Ideally we want to remove the expiry time cookie on the client. // However, this is not possible. We can only update the cookie. // By removing the expiry time value in the cookie, we are implicity // other pages to redirect to the login page instead. (see SessionTimeout.ascx) HttpCookie expiryCookie = new HttpCookie(GetExpiryTimeCookieName(session)) { Expires = Platform.Time.AddMinutes(5), Value = string.Empty }; HttpContext.Current.Response.Cookies.Set(expiryCookie); }
public static string GetExpiryTimeCookieName(SessionInfo session) { if (session == null) return null; string loginId = session.User.Identity.Name; return "ImageServer." + loginId; }
public static void SignOut(SessionInfo session) { FormsAuthentication.SignOut(); if (session != null) { try { ForceOtherPagesToLogout(session); using (LoginService service = new LoginService()) { service.Logout(session.Credentials.SessionToken.Id); } } catch (NotSupportedException) { //ignore this. } catch (Exception e) { Platform.Log(LogLevel.Warn, e, "Failed to log user out."); } UserAuthenticationAuditHelper audit = new UserAuthenticationAuditHelper( ServerPlatform.AuditSource, EventIdentificationContentsEventOutcomeIndicator.Success, UserAuthenticationEventType.Logout); audit.AddUserParticipant(new AuditPersonActiveParticipant( session.Credentials.UserName, null, session.Credentials.DisplayName)); ServerPlatform.LogAuditMessage(audit); } }
public static void SignOut(SessionInfo session) { FormsAuthentication.SignOut(); if (session != null) { try { ForceOtherPagesToLogout(session); using (LoginService service = new LoginService()) { service.Logout(session.Credentials.SessionToken.Id); } } catch (NotSupportedException) { //ignore this. } catch (Exception e) { Platform.Log(LogLevel.Warn, e, "Failed to log user out."); } } }
public SessionInfo Login(string userName, string password, string appName) { if (string.IsNullOrEmpty(userName)) throw new ArgumentException(SR.UserIDIsEmpty); if (string.IsNullOrEmpty(password)) throw new ArgumentException(SR.PasswordIsEmpty); Platform.CheckForEmptyString(password, "password"); Platform.CheckForEmptyString(appName, "appName"); SessionInfo session = null; Platform.GetService( delegate(IAuthenticationService service) { try { var request = new InitiateSessionRequest(userName, appName, Dns.GetHostName(), password) { GetAuthorizations = true }; InitiateSessionResponse response = service.InitiateSession(request); if (response != null) { var credentials = new LoginCredentials { UserName = userName, DisplayName = response.DisplayName, SessionToken = response.SessionToken, Authorities = response.AuthorityTokens, DataAccessAuthorityGroups = response.DataGroupOids, EmailAddress = response.EmailAddress }; var user = new CustomPrincipal(new CustomIdentity(userName, response.DisplayName),credentials); Thread.CurrentPrincipal = user; session = new SessionInfo(user); session.User.WarningMessages = response.WarningMessages; // Note: need to insert into the cache before calling SessionInfo.Validate() SessionCache.Instance.AddSession(response.SessionToken.Id, session); session.Validate(); Platform.Log(LogLevel.Info, "{0} has successfully logged in.", userName); } } catch (FaultException<PasswordExpiredException> ex) { throw ex.Detail; } catch(FaultException<UserAccessDeniedException> ex) { throw ex.Detail; } catch (FaultException<RequestValidationException> ex) { throw ex.Detail; } } ); return session; }
private void CleanupSession(SessionInfo session) { lock (_sync) { using (var service = new LoginService()) { try { try { service.Logout(session.Credentials.SessionToken.Id); } catch(Exception ex) { Platform.Log(LogLevel.Warn, ex, "Unable to terminate session {0} gracefully", session.Credentials.SessionToken.Id); } } finally { RemoveSession(session.Credentials.SessionToken.Id); } } } }
private void OnSessionRemoved(SessionInfo session) { }
public void AddSession(string id, SessionInfo session) { lock (_sync) { _cacheSessionInfo.Add(id, session); } }
static void AuthorizeRequest(object sender, EventArgs e) { SessionInfo session=null; try { if (HttpContext.Current.User.Identity.IsAuthenticated && HttpContext.Current.User.Identity is FormsIdentity) { // Note: If user signed out in another window, the ticket would have been // removed from the browser and this code shoudn't be executed. // resemble the SessionInfo from the ticket. var loginId = (FormsIdentity) HttpContext.Current.User.Identity ; FormsAuthenticationTicket ticket = loginId.Ticket; String[] fields = ticket.UserData.Split('|'); String tokenId = fields[0]; String userDisplayName = fields[1]; SessionToken token = new SessionToken(tokenId, ticket.Expiration); session = new SessionInfo(loginId.Name, userDisplayName, token); if (ticket.Version > 1) { if (!string.IsNullOrEmpty(fields[2])) { var warningMessages = fields[2].Split('@'); session.User.WarningMessages = warningMessages.Length > 0 ? new List<string>(warningMessages) : new List<string>(); } if (!string.IsNullOrEmpty(fields[3])) { session.User.WarningsDisplayed = bool.Parse(fields[3]); } } // Initialize the session. This will throw exception if the session is no longer // valid. For eg, time-out. SessionManager.InitializeSession(session); } // TODO (CR Jan 2014): This is a worker thread, and thread names can only be // set once. This will forever give false information after the first use. if (String.IsNullOrEmpty(Thread.CurrentThread.Name)) { String user = SessionManager.Current != null ? SessionManager.Current.User.Identity.Name : "Unknown"; Thread.CurrentThread.Name = String.Format(SR.WebGUILogHeader, HttpContext.Current.Request.UserHostAddress, HttpContext.Current.Request.Browser.Browser, HttpContext.Current.Request.Browser.Version, user); } } catch (SessionValidationException) { // SessionValidationException is thrown when the session id is invalid or the session already expired. // If session already expired, if (session != null && session.Credentials.SessionToken.ExpiryTime < Platform.Time) { SessionManager.SignOut(session); } else { // redirect to login screen SessionManager.TerminateSession("The current session is no longer valid.", SR.MessageCurrentSessionNoLongerValid); } } catch(Exception ex) { // log the exception ExceptionHandler.ThrowException(ex); } }
public SessionInfo VerifySession(string userId, string sessionTokenId) { SessionInfo sessionInfo = SessionCache.Instance.Find(sessionTokenId); if (sessionInfo != null) return sessionInfo; // Session does not exist in the cache. // Go to the server to see if the session exists // It may var request = new ValidateSessionRequest(userId, new SessionToken(sessionTokenId)) { GetAuthorizations = true, ValidateOnly = false // load the tokens too since we don't know anything about session yet }; try { using (new ResponseCacheBypassScope()) //bypass the response cache { Platform.GetService( delegate(IAuthenticationService service) { ValidateSessionResponse response = service.ValidateSession(request); sessionInfo = new SessionInfo(userId, userId, response.SessionToken); SessionCache.Instance.AddSession(sessionTokenId, sessionInfo); sessionInfo.Validate(); }); } return sessionInfo; } catch (FaultException<InvalidUserSessionException> ex) { SessionCache.Instance.RemoveSession(sessionTokenId); throw new SessionValidationException(ex.Detail); } catch (FaultException<UserAccessDeniedException> ex) { SessionCache.Instance.RemoveSession(sessionTokenId); throw new SessionValidationException(ex.Detail); } catch (Exception ex) { //TODO: for now we can't distinguish communicate errors and credential validation errors. // All exceptions are treated the same: we can't verify the session. var e = new SessionValidationException(ex); throw e; } }