身份认证服务器未返回刷新令牌。

16

我正在尝试设置Thinktecture的Identity Server 3,但我似乎无法在交换授权代码时(或使用ResourceOwner流程时)返回刷新令牌,但我现在要集中精力讨论授权代码,因为这对我更重要。我收到了访问令牌,并且可以正常使用它们进行身份验证,但似乎没有生成我期望获得的刷新令牌。是否需要特别处理才能使Identity Server返回刷新令牌?

我已经查看了文档,但没有发现任何我设置错误的内容,在他们关于刷新令牌 的页面上,我没有做的唯一一件事就是在将用户发送到那里进行身份验证时显式请求“offline_access”范围,因为每当我尝试时,我都会收到“无效的范围”错误。因此,我认为Thinktecture的措辞“通过代码或资源所有者流程请求offline_access范围”意味着offline_access范围是基于您使用的流程自动请求的。

我一直在尽力遵循他们的示例应用程序(以及现有Owin中间件的源代码来自Katana项目),我的设置如下:

  • 我使用他们的client class创建了一个客户端,手动指定以下内容:
    var client = new Client()
    {
        ClientId = "SomeId",
        ClientName = "Client with Authentication Code Flow",
        RequireConsent = false, //将其设置为true没有帮助
        Flow = Flows.AuthorizationCode,
        ClientSecrets = new List() {
            new ClientSecret("secret")
        },
        RedirectUris = new List()
        {
            "localhost:/specific-redirect-path"
        }
    };
  • 我正在调用Authorization endpoint,如下所示:
    var authorizationEndpoint =
        AuthorizationEndpointBase +
        "?client_id=" + Uri.EscapeDataString(Options.ClientId) +
        "&scope=Default" +
        "&response_type=code" +在此代码中,首先构建了授权终结点的URL,包括客户端ID、重定向URI和状态参数等信息,并通过Uri.EscapeDataString()方法进行编码。然后,在回调URL中,将使用授权代码(code)请求令牌终结点,传递客户端ID、客户端秘钥、重定向URI、授权代码和授权类型等参数,并通过PostAsync()方法发送HTTP POST请求。最后,接收来自服务器的响应并读取其中包含的访问令牌。
    在该调用中,Identity Server 的日志记录显示了授权代码验证成功以及创建令牌响应等过程。调试: [Thinktecture.IdentityServer.Core.Services.Default.DefaultTokenService]: 2015年7月13日下午1:44:07 +00:00 -- 创建引用访问令牌 iisexpress.exe 信息: 0 : [Thinktecture.IdentityServer.Core.Endpoints.TokenEndpointController]: 2015年7月13日下午1:44:07 +00:00 -- 结束令牌请求 iisexpress.exe 信息: 0 : [Thinktecture.IdentityServer.Core.Results.TokenResult]: 2015年7月13日下午1:44:07 +00:00 -- 返回令牌响应。

    我不确定是否还有其他相关的内容,如有需要,我将提供更多信息。


抱歉,打擾一下,不過我能否獲取您使用身份驗證服務構建的生成刷新令牌等模板? - Behrooz
遗憾的是,我正在作为员工增补的一部分构建它,但我现在已经不在那里了,因此我无法访问代码库,也没有发布它的权限。 - AJ Karnitis
2个回答

48

您需要在请求中显式地请求“offline_access”权限。用空格分隔其他所需的范围。(在下面的示例中,我将“Default”替换为“MyApi”,以明确我们正在谈论应用程序定义的范围。)

&scope=MyApi offline_access 

然而,你也必须授予该客户端获得刷新令牌的权利,这并不仅仅是基于你选择的流程自动发生的:

var client = new Client()
{
    ... //All the stuff you were doing before

    ScopeRestrictions = new List<string>
    { 
        "MyApi",
        StandardScopes.OfflineAccess.Name, //"offline_access" -for refresh tokens
        //Other commonly requested scopes:
        //StandardScopes.OpenId.Name, //"openid"
        //StandardScopes.Email.Name,  //"email"

    },
}

您可能需要在范围存储中添加“offline_access”。范围存储是Identity Server知道的范围列表。由于您的问题没有提及项目中如何设置范围存储,因此您可能已经拥有它。但是,如果上述方法不起作用,您可能需要在示例代码中查找类似于此的代码,并添加OfflineAccess。

var scopeStore = new InMemoryScopeStore(new Scope[]{
    StandardScopes.OpenId,
    StandardScopes.Profile,
    StandardScopes.Email,
    StandardScopes.OfflineAccess,  //<--- ensure this is here to allow refresh tokens
    new Scope{
        Enabled = true,
        Name = "MyApi"
    },
}

1
谢谢,解决了!我不知道我是怎么做到的,但在将StandardScopes添加到数据库时,作用域没有被包含进去,而且之前手动查看它们时也错过了,这就是为什么我认为它可能是自动确定的原因。现在这更有意义了。 - AJ Karnitis
2
我忘记在我的作用域存储中包含 StandardScopes.OfflineAccess,感谢您提到了这一点。 - Joshua
2
注意:StandardScopes.All 不包括离线访问范围。(在我看来非常奇怪)。 - jinavar1
正是我所需要的! - Sarah Lissachell

2
在发送令牌请求时,请在范围中添加offline_access值。
new Client
            {
                ClientId = "ro.angular",
                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,

                ClientSecrets =
                {
                    new Secret("secret".Sha256())
                },
                AllowedScopes = {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    IdentityServerConstants.StandardScopes.Email,
                    IdentityServerConstants.StandardScopes.Address,
                    "api1",
                    IdentityServerConstants.StandardScopes.OfflineAccess
                },
                AllowOfflineAccess = true,
                RefreshTokenUsage = TokenUsage.ReUse,
                RefreshTokenExpiration = TokenExpiration.Sliding

            }

Get Refresh token

Get new access token with refresh token


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接