如何通过在身份服务器4上调用授权端点来获取刷新令牌

时间:2019-01-03 18:16:52

标签: c# asp.net-mvc asp.net-mvc-3 identityserver4

我有ASP.Net MVC客户端应用程序,API.Net Web API 2项目和身份服务器4。我想保护我的API免受未经授权的访问,因此我从IS4获取了JWT令牌,然后将标头作为Bearer传入调用API时使用令牌。所有这些工作正常(登录到应用程序,获取JWT令牌,然后传递给API,以便在授权令牌后调用它)。我正在使用IdentityModel 3.9.0版本与Identity Server 4端点进行交互。

我正在尝试从身份服务器4获取刷新令牌,这是问题所在。我无法通过调用授权端点来获取它。我很困惑。下面是配置文件

中的文件IS4 GetClients方法

我当时使用HybridAndClientCredentials,然后发现使用客户端证书不支持刷新令牌流。

public static IEnumerable<Client> GetClients()
{
   return new List<Client>
    {
    new Client
        {
        ClientId = "client",
        AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,

        AccessTokenLifetime = 1800,

        AllowOfflineAccess  = true,

        // secret for authentication
        ClientSecrets =
        {
            new Secret("secret".Sha256())
        },
        // scopes that client has access to
        AllowedScopes = { "nidhiapi", "offline_access" }            
    }
};

我刚刚创建了一个基本控制台应用程序来测试我的身份验证服务器,下面是main方法中的代码

   var discoveryClient = await DiscoveryClient.GetAsync("http://localhost:5000/");
        if (discoveryClient.IsError)
        {
            Console.WriteLine(discoveryClient.Error);
            return;
        }

        // request the token from the Auth server
    var tokenClient = new TokenClient(discoveryClient.TokenEndpoint, "client", "secret");

    var tokenResponse = await tokenClient.RequestClientCredentialsAsync("nidhiapi"); 

我能够使用已定义的客户端和HybridClientCredentials流在tokenResponse变量中获取AccessToken

我想从Authorize端点获取RefreshToken。我尝试使用相同的GetClients方法在客户端代码中进行以下更改

 var tokenResponse = await tokenClient.RequestClientCredentialsAsync("offline_access");

使用上面的代码行,我收到一个错误“ Invalid_Scope”。我读了一下,发现我们需要使用offline_access来获取刷新令牌

我还有一个问题。当我试图为此找到解决方案时,我想到了使用AuthorizeEndPoint创建tokenClient的方法,但是除非我验证我的客户端凭据,否则下面的语句毫无用处。

另一件事:我应该在RequestRefreshToken方法中传递什么,因为它需要令牌

 var authTokenClient = new TokenClient(discoveryClient.AuthorizeEndpoint, "client", "secret");

 var refreshTokenResponse = await tokenClient.RequestRefreshTokenAsync("offline_access");

然后我尝试将GetClients方法更改为仅使用混合流,而不使用HybridClientCredentials,因为我还看到RefreshToken流不适用于ClientCredentials。

实际上,我现在很困惑。我的要求是从IS4获取令牌,然后使用刷新令牌刷新它,以便MVC客户端应用程序不必在到期时登录

建议/解决方案好吗?

2 个答案:

答案 0 :(得分:0)

您需要使用授权代码流,并且需要请求“ openid offline_access”范围。据我所知,您只能在使用授权代码流时使用刷新令牌。

希望这会有所帮助。

答案 1 :(得分:0)

它已经有一段时间了,但我相信我的回答会对某人有所帮助。要在 ID4 中获取刷新令牌以及访问令牌,您需要在客户端范围内和请求令牌时指定 offline_access。 让我们以基于用户名/密码的令牌生成为例。客户端应该是这样的

Client
            {
                ClientId = clientName,
                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
                RequireClientSecret = false,
                AllowedScopes = { apiResourceName, "offline_access" },
                AllowOfflineAccess = true,
                AccessTokenLifetime = 63113904,
                IdentityTokenLifetime = 63113904,
                RefreshTokenExpiration = TokenExpiration.Sliding,
                SlidingRefreshTokenLifetime = 63113904
            }

此后,当您调用身份服务器时,您必须使用 apiResourceName 和 offline_access 定义范围,以生成刷新令牌和访问令牌。 要生成访问/刷新令牌,使用用户名/密码,你可以这样做

var response = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
        {
            Address = "http://locahost/connect/token",
            ClientId = Enumerations.Client,
            Scope = Enumerations.API+" offline_access",
            UserName = "username",
            Password = "password"
        });

现在您将填充 response.RefreshToken 和 response.AccessToken。如果你不指定offline_score,你只会在refresh token中得到null。

现在下一部分是如何使用刷新令牌生成新的访问令牌。这是更简单的部分,您只需要再次调用 /connect/token 但使用刷新令牌,这就是您需要做的全部。这是来自身份服务器文档

POST /connect/token

client_id=client&
client_secret=secret&
grant_type=refresh_token&
refresh_token=hdh922