Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net 为什么要在OAuthAuthorizationServerProvider.GrantRefreshToken中添加声明?_Asp.net_Asp.net Web Api_Oauth_Oauth 2.0_Asp.net Web Api2 - Fatal编程技术网

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

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

我正在使用承载令牌为OAuth 2配置AspNet.Identity,我已经看到了实现
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的调用可能被赋予