Asp.net 为什么要在OAuthAuthorizationServerProvider.GrantRefreshToken中添加声明?
我正在使用承载令牌为OAuth 2配置AspNet.Identity,我已经看到了实现Asp.net 为什么要在OAuthAuthorizationServerProvider.GrantRefreshToken中添加声明?,asp.net,asp.net-web-api,oauth,oauth-2.0,asp.net-web-api2,Asp.net,Asp.net Web Api,Oauth,Oauth 2.0,Asp.net Web Api2,我正在使用承载令牌为OAuth 2配置AspNet.Identity,我已经看到了实现OAuthAuthorizationServerProvider.GrantRefreshToken方法的多个示例,作者在其中演示了向新ClaimsEntity添加声明的能力,如下所示 我试图在我的单一服务器(即我的Web API项目既是授权服务器又是资源服务器)的上下文中理解这一点,如有必要,我可以在以后将其拆分为单独的服务器 public override Task GrantRefreshToken(OA
OAuthAuthorizationServerProvider.GrantRefreshToken
方法的多个示例,作者在其中演示了向新ClaimsEntity
添加声明的能力,如下所示
我试图在我的单一服务器(即我的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);
}
公共覆盖任务GrantRefreshToken(OAuthGrantRefreshTokenContext)
{
var originalClient=context.Ticket.Properties.Dictionary[“as:client_id”];
var currentClient=context.ClientId;
if(originalClient!=当前客户端)
{
SetError(“无效的_clientId”,“刷新令牌被颁发给不同的clientId”);
返回Task.FromResult(空);
}
//更改刷新令牌请求的身份验证票证
var newIdentity=newclaimsidentity(context.Ticket.Identity);
//考虑一下:我不知道你为什么要在这里添加索赔,但这里有一个例子。
//var newClaim=newIdentity.Claims.Where(c=>c.Type==“newClaim”).FirstOrDefault();
//if(newClaim!=null)
//{
//newIdentity.RemoveClaim(newClaim);
//}
//newIdentity.AddClaim(新索赔(“新索赔”、“新价值”));
var newTicket=newauthenticationticket(newIdentity,context.Ticket.Properties);
上下文验证(newTicket);
返回Task.FromResult(空);
}
国家:
“应用程序必须调用context.Validated,以指示授权服务器中间件根据这些声明和属性发出访问令牌。”
我不明白。我以为我们在分发刷新令牌,而不是访问令牌
此外,“对context.Validated的调用可能会被赋予不同的AuthenticationTicket或ClaimsEntity,以控制哪些信息从刷新令牌流向访问令牌。”
我以为所有的声明都存储在我的签名和加密访问令牌中,该令牌作为授权:Bearer XXXXXX
传递。然而,我对ClaimsIdentity
和AuthenticationTicket
如何与OAuth 2.0流中的任何内容真正相关的问题掌握得很模糊
我最好的猜测是,
GrantRefreshToken
需要使用已经过身份验证和授权的标识(context.Ticket.identity
)并验证是否应通过调用context.Validated向其添加刷新令牌。OAuth2中的刷新令牌只是另一种授予类型:获取新的访问令牌的替代方法
因此,必须验证刷新令牌
,才能为用户发出新的访问令牌
将刷新令牌持久化到基础存储(例如数据库)时,整个用户标识必须与之一起存储(通常使用AuthenticationTokenCreateContext
对象的SerializeTicket()
方法)。这意味着,默认情况下,在第一次生成access\u令牌
期间获得的声明中的任何更改都不会使用refreshttoken
授权传播到其他access\u令牌
的排放中(如果需要在access\u令牌
中更新这些声明,则需要重新加载这些声明)
我相信这就是为什么许多示例显示如何在grantrefreshttoken
方法中添加/替换新标识中的声明的主要原因
我将尝试进一步澄清在支持RefreshTokenGrant
时通常发生的情况:
用户使用任何支持的授权(例如,ResourceOwnerCredentials
)对自己进行身份验证李>
我们创建一个绑定到此特定用户的身份(我们可以在此时添加声明),并使用它创建一个新的身份验证票证
(我们通过调用特定上下文
对象上的已验证(票证)
),该票证将用于创建访问令牌
李>
框架在提供的IAuthenticationTokenProvider
上生成一个新的刷新令牌调用CreateAsync
。在这个方法中,我们必须检索票据并将其存储到某种持久性存储器(例如数据库)中,以及一个唯一的Id
和一些有用的元数据。此Id
是用户视角的刷新\u标记
我们将access\u令牌
(包含用户的序列化声明)和refresh\u令牌
(仅作为参考)返回给用户
一段时间后,用户必须再次进行身份验证(例如,access\u令牌
过期),因此他将使用refresh\u令牌
向令牌端点发送请求
我们从持久存储中检索refresh\u令牌
记录,并反序列化将用于创建新标识的票证。此票证包含我们在第一次身份验证中添加的所有声明(这几乎是第一个访问\u令牌
的精确副本):如果在当前时刻和第一次身份验证之间的时间间隔内更改了任何声明(例如,向用户添加了新角色,更改了电子邮件等)我们现在有机会修改新标识并添加/替换这些声明,以便新的access\u令牌
将反映这些更改
流程通过验证票据(如前所述)并生成一对access\u token
和refresh\u token
发送给用户来继续
是的,您发送了一个刷新令牌,但服务器基于此刷新令牌发出访问令牌。因此,如果不调用Validated,最终将无法获得访问令牌<代码>对context.Validated的调用可能被赋予