在我的项目中,我使用的是基于令牌的身份验证,成功登录后,我将一些特定于用户的值存储在用户的令牌中,并为此使用了Claims。
下面是我用于在登录后存储声明的代码:
User user = new UserManager().GetUser(UserName, Password);
var claims = new List<Claim>()
{
new Claim(ClaimTypes.Name, user.FullName),
new Claim(ClaimTypes.Email, user.Email),
new Claim("IsLocked", Convert.ToString(user.IsLocked))
};
AuthenticationProperties properties = CreateProperties(context.UserName);
ClaimsIdentity oAuthIdentity = new ClaimsIdentity(claims, Startup.OAuthOptions.AuthenticationType);
var ticket = new AuthenticationTicket(oAuthIdentity, properties);
context.Validated(ticket);
如您在上面的代码中看到的那样,我声称可以存储用户的 IsLocked 值。根据要求,我需要阻止帐户被锁定的用户访问每个API操作。为此,我创建了一个自定义操作过滤器,并在其中使用了 IsLocked 声明的值,因此,如果用户的声明值表明该用户帐户已锁定,则阻止执行操作。
以下是我的自定义操作过滤器的代码:
public class AllowActiveUsersAttribute : ActionFilterAttribute
{
public AllowActiveUsersAttribute()
{
}
public override void OnActionExecuting(HttpActionContext actionContext)
{
var identity = (ClaimsPrincipal)Thread.CurrentPrincipal;
if (Convert.ToBoolean(identity.Claims.Where(c => c.Type == "IsLocked").Select(c => c.Value).SingleOrDefault()))
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
}
}
}
然后在所有Web API操作上使用此自定义属性,例如:
[AllowActiveUsers]
public async Task<IHttpActionResult> GetAccountDetails()
此代码可以正常工作,并且当我使用锁定的帐户登录并尝试使用任何API端点时,出现“未授权”错误。
在我们的系统中,我们有一些规则,违反这些规则可以锁定用户的帐户。帐户锁定后,用户将无法访问任何API端点。因此,成功登录后(使用未锁定的帐户),如果用户违反任何规则,则他/她的帐户应立即被锁定,此后,他/她一定不能使用任何API端点。
为此,我添加了代码以更新 IsLocked 声明的值,并成功更新了声明值。但是,当我尝试在自定义操作中获取 IsLocked 声明的值时,我得到的是相同的旧值,而不是新的返回值。下面是我用来更新声明值的代码。
// check for the existing claim and remove it
var user = User as ClaimsPrincipal;
var identity = user.Identity as ClaimsIdentity;
var claim = (from c in user.Claims where c.Type == "IsLocked" select c).FirstOrDefault();
if (claim != null)
identity.RemoveClaim(claim);
// add new claim
identity.AddClaim(new Claim("IsLocked", Convert.ToString(true)));
var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
authenticationManager.AuthenticationResponseGrant = new AuthenticationResponseGrant(new ClaimsPrincipal(identity), new AuthenticationProperties() { IsPersistent = true });
您能否建议我如何在custom属性中获取新值,以便如果用户的帐户被锁定,然后从下一个请求开始,则不应该受理任何API请求?
答案 0 :(得分:0)
这是因为您仍在使用旧的/现有的令牌,而这些令牌仍然没有更新的值IsLocked
,因此没有方案。为了解决这个问题,用户要么必须通过生成具有更新值的新令牌来重新开始。本质上,必须生成一个新的访问令牌。
请参阅此问题链接以进一步了解https://github.com/IdentityServer/IdentityServer3/issues/2783