【发布时间】: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