身份服务器不返回刷新令牌

Identity Server not returning refresh token

我正在尝试设置 Thinktecture 的 Identity Server 3,但在交换授权代码时(或在使用 ResourceOwner 流程​​时,我似乎无法将其设置为 return 刷新令牌,但我我将专注于授权代码,因为它现在对我来说更重要)。我取回了访问令牌并可以使用它们进行身份验证,但它似乎甚至没有生成我期望取回的刷新令牌。我需要做些什么才能让 Identity Server return 刷新令牌?

我查看了文档,但没有发现任何我设置错误的地方,refresh tokens 他们页面上唯一我没有做的事情就是明确要求"offline_access" 将用户发送到那里进行身份验证时的范围,因为每当我尝试时都会收到 "invalid scope" 错误。因此,我采用 Thinktecture 的 "Request the offline_access scope (via code or resource owner flow)" 措辞来表示 offline_access 范围是根据您使用的流程自动请求的。

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

当我调用令牌端点时,我在 Identity Server 上的登录显示如下(在验证授权码之后):

    iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Validation.TokenRequestValidator]: 7/13/2015 1:44:07 PM +00:00 -- Token request validation success
     {
      "ClientId": "SomeId",
      "ClientName": "Client with Authentication Code Flow",
      "GrantType": "authorization_code",
      "AuthorizationCode": "f8f795e649044067ebd96a341c5af8c3"
    }
    iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.ResponseHandling.TokenResponseGenerator]: 7/13/2015 1:44:07 PM +00:00 -- Creating token response
    iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.ResponseHandling.TokenResponseGenerator]: 7/13/2015 1:44:07 PM +00:00 -- Processing authorization code request
    Debug: [Thinktecture.IdentityServer.Core.Services.Default.DefaultTokenService]: 7/13/2015 1:44:07 PM +00:00 -- Creating access token
    Debug: [Thinktecture.IdentityServer.Core.Services.Default.DefaultTokenService]: 7/13/2015 1:44:07 PM +00:00 -- Creating reference access token
    iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Endpoints.TokenEndpointController]: 7/13/2015 1:44:07 PM +00:00 -- End token request
    iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Results.TokenResult]: 7/13/2015 1:44:07 PM +00:00 -- Returning token response.

我不确定还有什么是相关的,所以我会根据需要提供更多信息。

您必须在请求中明确要求 'offline_access'。用 space 分隔您请求的其他范围。 (在我下面的示例中,我将 '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"
    },
}

在发送令牌请求时在范围内添加 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

            }