【问题标题】:Updated value of Claim is not reflecting in the subsequent requests更新后的声明值未反映在后续请求中
【发布时间】:2019-04-02 15:33:14
【问题描述】:

在我的项目中,我使用基于令牌的身份验证,成功登录后,我将一些特定于用户的值存储在用户的令牌中,为此我使用了声明。

以下是我用于在登录后存储声明的代码:

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 });

您能否建议我如何在自定义属性中获取新值,以便如果用户的帐户被锁定,然后从下一个请求开始,则不应处理任何 API 请求?

【问题讨论】:

    标签: c# asp.net-web-api


    【解决方案1】:

    那是因为您仍在使用旧的/现有的令牌,它仍然没有 IsLocked 的更新值,因此是场景。为了解决这个问题,用户要么必须通过生成具有更新值的新令牌来重新开始。基本上必须生成一个新的访问令牌。

    更多了解请查看此问题链接https://github.com/IdentityServer/IdentityServer3/issues/2783

    【讨论】:

    • 嗨拉胡尔。我知道创建一个新的访问令牌可以解决这个问题,但我不确定我该怎么做。你能分享一个相同的代码示例吗?
    • @MohitThakur 我的意思是被锁定的用户必须再次登录或者如果是 Api 请求则需要通过点击/token 端点来生成新的访问令牌
    • 我尝试使用 /token 端点重新生成令牌,但即便如此,我也可以使用旧的访问令牌来使用 API 端点。有什么解决办法吗?
    猜你喜欢
    • 2016-02-19
    • 1970-01-01
    • 2020-12-26
    • 1970-01-01
    • 1970-01-01
    • 2020-02-17
    • 1970-01-01
    • 2021-07-22
    • 1970-01-01
    相关资源
    最近更新 更多