我有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客户端应用程序不必在到期时登录
建议/解决方案好吗?
答案 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