为什么在OAuthAuthorizationServerProvider.GrantRefreshToken中添加声明?

Way*_*oss 2 asp.net oauth oauth-2.0 asp.net-web-api asp.net-web-api2

我正在使用承载令牌为OAuth 2配置AspNet.Identity,我已经看到了实现该OAuthAuthorizationServerProvider.GrantRefreshToken方法的多个示例,其中作者演示了new ClaimsIdentity如下所示添加声明的能力.

我试图在我的单服务器(即我的Web API项目是授权+资源服务器)的上下文中理解这一点,如果需要,我可以在以后将其拆分为单独的服务器.

public override Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
{
    var originalClient = context.Ticket.Properties.Dictionary["as:client_id"];
    var currentClient = context.ClientId;

    if (originalClient != currentClient)
    {
        context.SetError("invalid_clientId", "Refresh token is issued to a different clientId.");
        return Task.FromResult<object>(null);
    }

    // Change auth ticket for refresh token requests
    var newIdentity = new ClaimsIdentity(context.Ticket.Identity);

    // CONSIDER: I don't know why you would add a claim here, but here's an example.
    //var newClaim = newIdentity.Claims.Where(c => c.Type == "newClaim").FirstOrDefault();
    //if (newClaim != null)
    //{
    //    newIdentity.RemoveClaim(newClaim);
    //}
    //newIdentity.AddClaim(new Claim("newClaim", "newValue"));

    var newTicket = new AuthenticationTicket(newIdentity, context.Ticket.Properties);
    context.Validated(newTicket);

    return Task.FromResult<object>(null);
}
Run Code Online (Sandbox Code Playgroud)

文件说明:

"应用程序必须调用context.Validated指示Authorization Server中间件根据这些声明和属性发出访问令牌."

我不明白这一点.我以为我们正在分发刷新令牌,而不是访问令牌.

此外,"对context.Validated的调用可以被赋予不同的AuthenticationTicket或ClaimsIdentity,以便控制哪些信息从刷新令牌流向访问令牌."

我认为所有声明都存储在我的签名和加密访问令牌中,该令牌传递为Authorization: Bearer XXXXXX.但是,我对OAuth 2.0流程中的任何内容的处理方式ClaimsIdentityAuthenticationTicket实际关系都有一个细微的把握.

我最好的猜测是GrantRefreshToken需要获取已经过身份验证和授权的身份(context.Ticket.Identity)并通过调用context.Validated验证是否应该向其添加刷新令牌.

Fed*_*uma 5

OAuth2中的刷新标记只是另一种类型的授权:另一种获取新方法的方法access_token.

因此,RefreshToken必须验证必须access_token为用户发出新内容.

当将刷新令牌持久化到底层存储(例如数据库)时,必须将整个用户身份与其一起存储(通常使用对象的SerializeTicket()方法AuthenticationTokenCreateContext).这意味着在第一access_token代中获得的索​​赔中的任何更改都不会默认access_token使用RefreshToken授权传播到其他s排放(如果您需要更新这些声明,则需要重新加载这些声明access_token).

我相信这是为什么许多示例显示如何在GrantRefreshToken方法内的新标识中添加/替换声明的主要原因.

我将尝试进一步澄清支持以下情况时通常会发生的情况RefreshTokenGrant:

  1. 用户使用任何类型的支持授权来验证自己(例如ResourceOwnerCredentials);
  2. 我们创建一个与该特定用户绑定的标识(我们可以在此处添加声明)并使用它创建一个新的AuthenticationTicket(我们通过调用Validated(ticket)特定context对象进行验证)将用于创建access_token;
  3. 该框架生成一个新的刷新令牌,调用CreateAsync提供的IAuthenticationTokenProvider.在此方法中,我们必须检索票证并将其存储到某种持久性存储(例如数据库)以及唯一Id且有用的元数据中.这Idrefresh_token针对用户的观点.
  4. 我们返回给用户access_token(包含用户的序列化声明)和refresh_token(这只是一个参考).
  5. 一段时间后,用户必须再次进行身份验证(例如access_token已过期),因此他将使用该请求向令牌端点发送请求refresh_token.
  6. 我们refresh_token从持久存储中检索记录并反序列化将用于创建新标识的票证.此票证包含我们在第一次身份验证时添加的所有声明(这几乎是第一次身份验证的精确副本access_token):如果在当前时刻和第一次身份验证之间的间隔期间任何声明发生了更改(例如,新角色已添加到用户,电子邮件已更改等.)我们现在有机会修改新标识并添加/替换这些声明,以便新的access_token将反映更改.
  7. 流继续通过验证票(如前)和生成对access_tokenrefresh_token发送给用户.