【问题标题】:Force ASP.Net claims validation after they have been changed更改后强制 ASP.Net 声明验证
【发布时间】:2018-01-16 22:03:04
【问题描述】:

我正在使用 OWIN 开发 ASP.Net 应用程序,目前我遇到了索赔问题。我有两个级别的应用程序:基本和高级。某些功能仅适用于高级用户。所以我检查了声明,如果用户没有声明 advanced 我返回 403。但是在这里我找到了破坏这个系统的解决方法:

  • 用户激活高级模式
  • 他执行任何操作并保存其访问令牌
  • 他禁用高级模式
  • 现在他可以使用此令牌执行操作,就像他处于高级模式一样,但他实际上没有权限这样做。

我正在尝试为这种情况找到一些好的解决方案,但除了 set 1 minute timeoutalways check AspNetUserClaims instead of cookie 等我没有其他想法,但它们在我的情况下不起作用,因为他可以在此激活终身功能间隔一分钟,然后永久使用。

但我想设置一些服务器端标志,例如 oops, this guy have just changed his cookies, check it from database 或其他东西,以降低常见 API 调用的数据库往返次数。

是否有任何标准的默认方式来做到这一点?或者我只是选择了错误的乐器?

【问题讨论】:

  • 在 Identity 中,您可以简单地注销用户并以编程方式重新登录。似乎那样会反弹他们的 cookie 和 IPrincipal
  • @Eonasdan 我不知道何时注销用户。对于每个请求?每5分钟一次?如果是前者,那就没用了。如果后者比用户有 5 分钟的时间做每件事。
  • “用户激活高级模式”-> 退回登录-> “他停用高级模式”-> 退回登录
  • 退回登录不会影响已经存在的 cookie。如果用户有val1,val2,val3 的值并将其发送到服务器,Claims 表示他实际上拥有它们。我无法在服务器端注销这些值。这只是一个请求。
  • 简化:服务器收到一些请求,比如说“主页上的pring消息”和cookie“HOME_PAGE_MANAGER”。这种情况下服务器应该做什么?

标签: c# asp.net asp.net-mvc cookies owin


【解决方案1】:

您需要根据您的声明值发送更新 cookie。

以下是更新您的声明值的代码。

在用户禁用/启用高级模式时在您的操作中,然后更新用户claims

var isAdvanced= "1";    

var identity = (ClaimsIdentity)User.Identity;

// check if claim exist or not.
var existingClaim = identity.FindFirst("IsAdvanced");
if (existingClaim != null)
    identity.RemoveClaim(existingClaim);

// add/update claim value.
identity.AddClaim(new Claim("IsAdvanced", isAdvanced));

IOwinContext context = Request.GetOwinContext();

var authenticationContext = await context.Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie);

if (authenticationContext != null)
{
    authenticationManager.AuthenticationResponseGrant = new AuthenticationResponseGrant(identity,authenticationContext.Properties);
}

一旦您进行重定向,您将获得更新后的声明值,因此您无需进行数据库往返。

Credit to this post.

【讨论】:

  • 但是保存的请求呢?例如他刚刚使用了chrome功能save as cUrl然后手动发送请求?它仍然有一个具有此值的 cookie。我为下一个请求将其删除,但这没关系,因为我在服务器端没有检查任何内容。还是我?
  • @AlexZhukovskiy :不,如果您使用旧 cookie 手动发送请求,它将不起作用。因为旧的 cookie 值仍然具有声明值“1”。
  • @AlexZhukovskiy : 什么是 cookie 令牌过期时间?
  • 目前是1天左右,不过没关系。正如我上面所说,即使是 1 分钟的 cookie 也已经很危险了。
  • @AlexZhukovskiy :我有类似的情况,但我的数据不是那么敏感。这只是我的意见。用户登录后,当用户更改模式然后在更新声明之前,您将旧的 cookie 值保留在 cache dictionary <key, datetime> key =cookievalue=current+1day 中。现在创建一个ActionFilter 并检查传入请求的cookie 值,如果它存在于cached 字典中,则阻止该请求。由于您的到期时间是一天,因此您可以从 dic 中删除其值小于当前日期时间的 val。
【解决方案2】:

不幸的是,我发现的唯一方法实际上是查询数据库本身并检查用户是否具有有效的凭据:

public bool HasRequiredClaims(string[] requiredClaims)
{
    using (var context = new ApplicationDbContext())
    {
        int actualNumberOfClaims = context.Users
            .SelectMany(x => x.Claims)
            .Count(c => requiredClaims.Contains(c.ClaimValue)); // claim values are unique per user (in my case) so I don't have to filter on user
        return actualNumberOfClaims == claimsValuesToSearch.Length;
    }
}

【讨论】:

    猜你喜欢
    • 2020-10-09
    • 1970-01-01
    • 2021-05-22
    • 2017-06-17
    • 2018-12-29
    • 2019-06-09
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多