// Get the current JWT token and transport type public string GetBearerToken(HttpContext context, out BearerTokenTransport tokenTransport) { string token; // If context is null, might be a worker thread (Task), so check for the token in the per-thread IUserIdentity if (context == null) { tokenTransport = BearerTokenTransport.ThreadUserIdentity; token = ApplicationSettings.Container.Resolve <IThreadContext>().UserToken; return(token); } // try get from Authentication headers token = context.Request.Headers["Authorization"]; if (token != null && token.StartsWith("Bearer ")) { tokenTransport = BearerTokenTransport.AuthorizationHeader; return(token.Substring("Bearer ".Length, token.Length - "Bearer ".Length)); } // fall back to API parameter token = context.Request["_user_token"]; if (token != null) { tokenTransport = BearerTokenTransport.APIParameter; return(token); } // fall back to cookies var cookies = HttpContext.Current.Request.Cookies; token = cookies["BearerToken"] == null ? null : cookies["BearerToken"].Value; tokenTransport = BearerTokenTransport.Cookie; return(token); }
// Validate a token with autorenew if required public ClaimsPrincipal ValidateTokenAndAutoRenewTokenIfRequired(string bearerToken, BearerTokenTransport tokenTransport) { try { var principal = ValidateToken(bearerToken); var expirationDate = GetTokenExpirationDate(bearerToken); var sessionTokenTimeout = Convert.ToInt32(ConfigurationManager.AppSettings["SessionTokenTimeout"]); var sessionTokenRenewalTimeout = Convert.ToInt32(ConfigurationManager.AppSettings["SessionTokenRenewalTimeout"]); if (tokenTransport != BearerTokenTransport.APIParameter && DateTime.Compare(DateTime.UtcNow, expirationDate.AddMinutes(sessionTokenRenewalTimeout - sessionTokenTimeout)) > 0) { var token = CreateToken(principal.Claims.Where(c => c.Type != "aud" && c.Type != "iss" && c.Type != "nbf" && c.Type != "exp")); switch (tokenTransport) { case BearerTokenTransport.AuthorizationHeader: AddTokenToAuthorizationHeaders(token); break; case BearerTokenTransport.Cookie: AddTokenToCookies(token); break; case BearerTokenTransport.APIParameter: // nothing we can do in this case break; case BearerTokenTransport.ThreadUserIdentity: ApplicationSettings.Container.Resolve <IThreadContext>().UserToken = token; break; default: // so that we don't miss this if any other means of token transport arrive on the scene in the future throw new GOServerException("notImplemented", $"{tokenTransport} - AutoRenewToken has not been implemented for this kind of token transport"); } } return(principal); } catch (Exception) { // We used to age-out the cookie here. // Removed because we want expired tokens to continue to stick around so that the rest of the app knows the context for auth failure throw; } }