帐户数据更改后注销用户

时间:2018-07-23 09:28:04

标签: angular authentication .net-core asp.net-identity

我一直在使用.net核心webapi作为后端创建角度应用程序。在我的应用程序中是一个用户管理面板,具有足够特权的用户可以在其中更改数据(电子邮件,密码,应用程序中的角色等)。我想在每次更改特定用户的数据时强制应用程序刷新身份验证令牌(但仅强制该用户刷新令牌)或将其重定向到登录页面。我希望该功能可以确保当我更改用户角色时,用户不会(或确实拥有)立即访问应用程序的某些部分。

我当前的解决方案是添加并发戳(或其中的哈希)作为声明值,然后在每个api调用期间通过实现自定义AuthorizationHandler对其进行验证。这是实现此目的的代码示例:

var claims = principal.Claims.ToList();
            claims.Add(new Claim(
                CustomClaimTypes.Version, userIdentity.ConcurrencyStamp));
            return Ok(await _tokenGenerator.GenerateToken(userIdentity, claims));


public class ConcurrencyAuthorizationRequirement : IAuthorizationRequirement
    {

    }
    public class ConcurrencyAuthorizationHandler : AuthorizationHandler<ConcurrencyAuthorizationRequirement>
    {
        private readonly UserManager<CustomIdentityUser> _userManager;

        public ConcurrencyAuthorizationHandler(UserManager<CustomIdentityUser> userManager)
        {
            _userManager = userManager;
        }
        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ConcurrencyAuthorizationRequirement requirement)
        {
            var versionClaim = context.User.Claims.FirstOrDefault(x => x.Type == CustomClaimTypes.Version);
            if (versionClaim != null)
            {
                var concurrencyStamp = _userManager.FindByNameAsync(context.User.Identity.Name).Result.ConcurrencyStamp;
                if (string.Equals(concurrencyStamp, versionClaim.Value))
                {
                    context.Succeed(requirement);
                    return Task.CompletedTask;
                }
            }

            var filterContext = context.Resource as AuthorizationFilterContext;
            var response = filterContext?.HttpContext.Response;
            var message = Encoding.UTF8.GetBytes("some message");
            response?.OnStarting(async () =>
            {
                filterContext.HttpContext.Response.StatusCode = 401;
                await response.Body.WriteAsync(message, 0, message.Length);
            });
            return Task.CompletedTask;
        }
    }

Angular应用程序将使用http拦截器来处理刷新令牌(与到期令牌功能相似)

它工作得很好,但是我对每个api调用中的每个数据库查询都不满意...

我的问题是: 1.我相信有更好的方法可以达到相同的结果。应该怎么做才能获得相似的结果? 2.我在使用UserManager缓存ConcurrecyStamp时遇到问题。将UserManager添加为作用域依赖项不会刷新图章。仅在将管理器声明为临时依赖项之后,它才开始工作。是什么原因呢?

0 个答案:

没有答案