public async Task OnValidateIdentity(CookieValidateIdentityContext cookieValidateIdentityContext) { DateTimeOffset currentDateUtc = DateTimeOffset.UtcNow; if (cookieValidateIdentityContext.Options?.SystemClock != null) { currentDateUtc = cookieValidateIdentityContext.Options.SystemClock.UtcNow; } DateTimeOffset? authenticationTickedIssuedDataUtc = cookieValidateIdentityContext.Properties.IssuedUtc; bool authenticationTickedIsValid = !authenticationTickedIssuedDataUtc.HasValue; if (authenticationTickedIssuedDataUtc.HasValue) { authenticationTickedIsValid = currentDateUtc.Subtract(authenticationTickedIssuedDataUtc.Value) > this.ValidationInterval; } if (authenticationTickedIsValid) { var userId = cookieValidateIdentityContext.Identity.GetUserId(); if (userId != null) { bool userIdentityIsValid = false; User user = await this.userRepository.FindByIdAsync(userId); if (user != null) { string securityStamp = cookieValidateIdentityContext.Identity.FindFirst("AspNet.Identity.SecurityStamp")?.Value; if (securityStamp == user.SecurityStamp) { var userRoles = await this.userRepository.GetRolesAsync(user); var userClaims = await this.userRepository.GetClaimsAsync(user); var claimsIdentity = await this.claimsIdentityFactory.CreateAsync(user, AuthenticationType.ApplicationCookie, userRoles, userClaims); // Add custom user claims here. cookieValidateIdentityContext.Properties.IssuedUtc = new DateTimeOffset?(); cookieValidateIdentityContext.Properties.ExpiresUtc = new DateTimeOffset?(); cookieValidateIdentityContext.OwinContext.Authentication.SignIn(cookieValidateIdentityContext.Properties, claimsIdentity); userIdentityIsValid = true; } } if (!userIdentityIsValid) { cookieValidateIdentityContext.RejectIdentity(); cookieValidateIdentityContext.OwinContext.Authentication.SignOut(cookieValidateIdentityContext.Options.AuthenticationType); } } } }
private static async Task ValidateAccessToken(CookieValidateIdentityContext ctx, string tokenEndpoint, string clientId, string clientSecret) { var claimsIdentity = ctx?.Identity; if (claimsIdentity == null) { return; } DateTimeOffset expiresAt; DateTimeOffset.TryParse(claimsIdentity.FindFirst("expires_at")?.Value, out expiresAt); try { //Check for expired token if (DateTimeOffset.UtcNow.AddMinutes(5) >= expiresAt) { Trace.WriteLine($"Token expiring, expiresAt: {expiresAt}, now: {DateTimeOffset.UtcNow}"); string refreshToken = claimsIdentity.FindFirst("refresh_token")?.Value; if (refreshToken == null) { Trace.WriteLine("No refresh token, rejecting identity"); ctx.RejectIdentity(); return; } var tokenResponse = await StsTokenHelper.RefreshToken(_client, tokenEndpoint, clientId, clientSecret, refreshToken); if (tokenResponse.IsError) { Trace.WriteLine("RefreshToken resulted in error, rejecting identity"); ctx.RejectIdentity(); return; } claimsIdentity.AddOrUpdateClaim("access_token", tokenResponse.AccessToken); claimsIdentity.AddOrUpdateClaim("expires_at", tokenResponse.ExpiresUtc().ToString()); claimsIdentity.AddOrUpdateClaim("refresh_token", tokenResponse.RefreshToken); //ctx.ReplaceIdentity(claimsIdentity); // kill old cookie ctx.OwinContext.Authentication.SignOut(ctx.Options.AuthenticationType); // sign in again var authenticationProperties = new AuthenticationProperties { IsPersistent = ctx.Properties.IsPersistent }; ctx.OwinContext.Authentication.SignIn(authenticationProperties, claimsIdentity); } } catch (Exception ex) { Trace.WriteLine($"Exception occurred, rejecting identity\r\n{ex.Message}\r\n{ex.StackTrace}"); ctx.RejectIdentity(); } }
private static async Task ProcessIdentity(TimeSpan validateInterval, CookieValidateIdentityContext context) { if (context.Request.Path.HasValue && (context.Request.Path.Value.EndsWith(".css") || context.Request.Path.Value.EndsWith(".js") || context.Request.Path.Value.EndsWith(".map") || context.Request.Path.Value.EndsWith(".woff") || context.Request.Path.Value.EndsWith(".woff2") || context.Request.Path.Value.EndsWith(".png") || context.Request.Path.Value.EndsWith(".gif") || context.Request.Path.Value.EndsWith(".jpg") || context.Request.Path.Value.EndsWith(".jpeg") ) ) { return; } try { var currentUtc = DateTimeOffset.UtcNow; if (context.Options?.SystemClock != null) { currentUtc = context.Options.SystemClock.UtcNow; } var issuedUtc = context.Properties.IssuedUtc; // Only validate if enough time has elapsed var validate = (issuedUtc == null); if (issuedUtc != null) { var timeElapsed = currentUtc.Subtract(issuedUtc.Value); validate = timeElapsed > validateInterval; } if (validate) { var manager = context.OwinContext.GetUserManager <UserManager>(); var userId = context.Identity.GetUserId(); if (manager != null && !string.IsNullOrWhiteSpace(userId)) { var user = await manager.FindByIdAsync(userId); var reject = true; // Refresh the identity if the stamp matches, otherwise reject if (user != null && await VerifySecurityStampAsync(manager, user, context) //&& await VerifyClientIdAsync(user, context) ) { reject = false; // Regenerate fresh claims if possible and resign in var identity = await user.GenerateUserIdentityAsync(manager, context.Identity.GetIsPersistent()); if (identity != null) { context.OwinContext.Authentication.SignIn(identity); var newResponseGrant = context.OwinContext.Authentication.AuthenticationResponseGrant; if (newResponseGrant != null) { newResponseGrant.Properties.IsPersistent = context.Identity.GetIsPersistent(); } } } if (reject) { if (user != null) { int clientId; if (int.TryParse(context.Identity.FindFirstValue("AspNet.Identity.ClientId"), out clientId)) { manager.SignOutClientById(user, clientId); } } context.RejectIdentity(); context.OwinContext.Authentication.SignOut(context.Options.AuthenticationType); } } } } catch (Exception e) { LogManager.GetLogger(typeof(ApplicationCookieIdentityValidator)).Error("Error in validate cookie.", e); throw; } }
private static void RejectIdentity(CookieValidateIdentityContext context) { context.RejectIdentity(); context.OwinContext.Authentication.SignOut(context.Options.AuthenticationType); }