如何过期/更新存储在Web API SessionToken中的ClaimsIdentity声明

本文关键字:API Web SessionToken 中的 声明 ClaimsIdentity 存储 更新 何过期 过期 | 更新日期: 2023-09-27 18:07:05

我正在使用优秀的Thinktecture。用于在ASP中执行身份验证/授权的IdentityModel库。NET Web API项目,该项目将从移动设备和可能的Web客户端使用。我使用基本身份验证来验证移动客户端访问web api,并利用Thinktecture内置的SessionToken生成。IdentityModel礼物。然而,我有一些问题,如何撤销索赔添加到ClaimsIdentity索赔集合,然后(我认为)编码到提供给客户端的SessionToken…

到目前为止我写的是:

按照IdentityModel样例项目中的示例,我创建了以下类
public static class  SecurityConfig
{
  public static void ConfigureGlobal(HttpConfiguration globalConfig)
  {
      globalConfig.MessageHandlers.Add(new AuthenticationHandler(CreateConfiguration()));
  }
  public static AuthenticationConfiguration CreateConfiguration()
  {
      var authentication = new AuthenticationConfiguration()
          {
              ClaimsAuthenticationManager = new MyClaimsTransformer(),
              RequireSsl = false, //TODO:TESTING only
              EnableSessionToken = true,
              SessionToken = new SessionTokenConfiguration()
              {
                  EndpointAddress = "/Authenticate"
              }
          };
       authentication.AddBasicAuthentication(Membership.ValidateUser);
      return authentication;
   }
}

从全局调用。像这样的一个类

SecurityConfig.ConfigureGlobal(GlobalConfiguration.Configuration);

移动设备从个人收集用户名和密码,并正确设置身份验证头,并将凭据提供给必要的web端点http://myhost/api/Authenticate

在服务器上,我的会员。使用用户名/密码调用ValidatUser,如果验证成功,则调用MyClaimsTransformer的Authenticate方法。

public class ClaimsTransformer : ClaimsAuthenticationManager
{
   public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
   {
     if (!incomingPrincipal.Identity.IsAuthenticated)
     {
        return base.Authenticate(resourceName, incomingPrincipal);
     }
     return incomingPrincipal;
   }
}

移动客户端然后收到一个令牌,它可以在任何后续请求的身份验证头中传递该令牌。

这一切都很好。

现在我想做的是,在ClaimsTransformer中,添加一些代码,这些代码将执行以下伪代码:

var nameClaim = incomingPrincipal.Claims.First(c => c.Type == ClaimTypes.Name);
//Using value in nameClaim lookup roles or permissions for this user.
var someListofRoles = SomeMethodToGetRoles(nameClaim.Value);
//Add user roles to the Claims collection of the ClaimsPrincipal.
foreach(var role in someListOfRoles)
{
   incomingPrincipal.Identities.First().AddClaim(new Claim("Role", role.Name));
}

我的希望是限制我需要从数据库请求给定用户的角色或权限列表的次数,以及在自定义AuthorizeAttribute中方便地检查这些角色/权限。

然而,当我开始添加这一点时,我开始考虑这样的场景:用户已经登录并将收到此令牌,但通过系统的其他用户的某些操作,他们的角色将被更改或撤销。初始用户将仍然拥有这个令牌,其中包含现已过期的角色/权限列表,并且在令牌过期之前可以访问任何内容,或者将被赋予对某些内容的新访问权限,但实际上不会收到该访问权限,直到他们以某种方式注销。

是否有一种机制使以这种方式创建的SessionToken无效?或者,如果我通过某种方式知道对用户角色/权限进行了更改,我将如何修改声明并以无缝的方式重新发布SessionToken ?

另外,如何完全撤销一个SessionToken,即如果我想'注销'一个用户,那将如何工作?

如何过期/更新存储在Web API SessionToken中的ClaimsIdentity声明

会话令牌功能没有该功能。我们希望保持简单,以解决"每次应用程序启动时输入密码"的问题。如果没有一个完整的数据存储后端(这将在web农场等中工作),撤销是很难实现的。

不应该在会话令牌中存储可能随会话时间变化的数据。

数据库更改通知设计完全由您决定。我的建议是像使用时间戳/rowversion来检查数据(用户/角色)是否过期。您可以将这些数据timestamp/rowversion存储在服务器上,如user-session,或在客户端存储cookie/header。我推荐前一种方法。

如果过时,我建议您可以重新执行您的CreateConfiguration()方法,该方法应重新创建反映与令牌相关的最新数据更改的所有必要信息。