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);
                    }
                }
            }
        }
예제 #2
0
        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();
            }
        }
예제 #3
0
        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;
            }
        }
예제 #4
0
 private static void RejectIdentity(CookieValidateIdentityContext context)
 {
     context.RejectIdentity();
     context.OwinContext.Authentication.SignOut(context.Options.AuthenticationType);
 }
 private static void RejectIdentity(CookieValidateIdentityContext context)
 {
     context.RejectIdentity();
     context.OwinContext.Authentication.SignOut(context.Options.AuthenticationType);
 }