我正在使用承载令牌为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);
}
“应用程序必须调用context.Validated指示Authorization Server中间件根据这些声明和属性发出访问令牌。”
我不明白这一点。我以为我们正在分发刷新令牌,而不是访问令牌。
此外,“对context.Validated的调用可能会被赋予不同的AuthenticationTicket或ClaimsIdentity,以便控制哪些信息从刷新令牌流向访问令牌。”
我认为所有声明都存储在我的签名和加密访问令牌中,该令牌传递为Authorization: Bearer XXXXXX
。但是,我对ClaimsIdentity
和AuthenticationTicket
与OAuth 2.0流程中的任何内容实际相关的方式都有一个微妙的把握。
我最好的猜测是GrantRefreshToken
需要获取已经过身份验证和授权的身份(context.Ticket.Identity
),并通过调用context.Validated验证是否应该向其添加刷新令牌。
答案 0 :(得分:5)
OAuth2中的刷新标记只是另一种类型的授权:获取新access_token
的另一种方法。
因此,必须验证RefreshToken
才能为用户发出新的access_token
。
当将刷新令牌持久化到底层存储(例如数据库)时,必须将整个用户身份与其一起存储(通常使用SerializeTicket()
对象的AuthenticationTokenCreateContext
方法)。这意味着在第一代access_token
生成期间获得的声明中的任何更改都不会在默认情况下使用access_token
授权传播到其他RefreshToken
排放(您需要再次重新加载这些声明如果您需要在access_token
)中更新它们。
我认为这是许多示例显示如何在GrantRefreshToken
方法中的新标识中添加/替换声明的主要原因。
我将尝试进一步澄清支持RefreshTokenGrant
时通常会发生的事情:
ResourceOwnerCredentials
); AuthenticationTicket
(我们通过在特定{{1上调用Validated(ticket)
来验证对象)将用于创建context
; access_token
上生成一个名为CreateAsync
的新刷新令牌。在此方法中,我们必须检索故障单并将其存储到某种持久性存储(例如数据库)以及唯一的IAuthenticationTokenProvider
和一些有用的元数据中。这个Id
是用户观点的Id
。refresh_token
(其中包含用户的序列化声明)和access_token
(仅作为参考)。refresh_token
已过期),因此他将使用access_token
向令牌端点发送请求。refresh_token
记录,并反序列化将用于创建新标识的故障单。此票证包含我们在第一次身份验证时添加的所有声明(这几乎是第一次refresh_token
的精确副本):如果在当前时刻和第一次身份验证之间的间隔期间任何声明发生了更改(例如,新的角色已添加到用户,电子邮件已更改等。)我们现在有机会修改新身份并添加/替换这些声明,以便新access_token
将反映更改。access_token
和access_token
以发送给用户。