让 IS4 发出刷新令牌
Getting IS4 to issue refresh tokens
好的,我无法让 IS4 在 authorization_code 流程期间发出刷新令牌,即使我(相信)打开了它,并且客户端通过在 offline_access
中包含来请求它范围。我使用以下方式添加 IS4:
services.AddIdentityServer()
.AddInMemoryClients(Config.Clients)
.AddPersistedGrantStore<PersistedGrantStore>()
.AddInMemoryIdentityResources(Config.IdentityResources)
.AddSigningCredential(loadedX509pfx);
// identity resources from another file:
public static IEnumerable<IdentityResource> IdentityResources =>
new IdentityResource[]
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
};
客户端定义为(为简洁起见,我包括了除 URLs 之外的所有内容):
ClientId = "MyClientBlahBlah",
ClientSecrets = new List<Secret> { new("secretXX".Sha256()) },
RequireClientSecret = false,
RequireConsent = false,
AllowedGrantTypes = GrantTypes.Code,
AccessTokenType = AccessTokenType.Jwt,
AccessTokenLifetime = (int)TimeSpan.FromDays(7).TotalSeconds,
IdentityTokenLifetime = (int)TimeSpan.FromDays(7).TotalSeconds,
AbsoluteRefreshTokenLifetime = (int)TimeSpan.FromDays(30).TotalSeconds,
SlidingRefreshTokenLifetime = (int)TimeSpan.FromDays(15).TotalSeconds,
UpdateAccessTokenClaimsOnRefresh = true,
AllowOfflineAccess = true,
RefreshTokenExpiration = TokenExpiration.Sliding,
RefreshTokenUsage = TokenUsage.OneTimeOnly,
AlwaysSendClientClaims = true,
Enabled = true,
AllowedScopes = {
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.OfflineAccess
},
RequirePkce = false,
...
但是,当请求通过此请求发出时:
GET /connect/authorize?client_id=MyClientBlahBlah&response_type=code&scope=openid%20profile%20offline_access&redirect_uri=<targeturl>
并且用户登录,重定向 URL 仅使用授权码调用:
没有任何地方提到刷新令牌。当我检查授予持久性存储时,记录已创建(尽管其设置为 5 分钟后过期),但是,存储记录中的 Data
JSON 再次没有提及刷新并且没有为该主题创建其他记录。
{
"CreationTime" : "2022-03-28T15:56:26Z",
"Lifetime" : 300,
"ClientId" : "MyClientBlahBlah",
"Subject" : {...} <full json of claims, which is ok>
"IsOpenId" : true,
"RequestedScopes" : [
"0" : "opened",
"1" : "profile",
"2" : "offline_access"
],
"RedirectUri" : "targetURL",
"Nonce" : null,
"StateHash" : "d8EeV5-CyXT_-vbd8gRcRA",
"WasConsentShown" :false,
"SessionId" : "8DBD74DF791AD6C04FCCB78A3CF57C6E",
"CodeChallenge" : "",
"CodeChallengeMethod" : null,
"Description" : null,
"Properties" : { }
}
我哪里做错了或者我忘了包括什么?我似乎无法找到有关文档的任何帮助,大多数人在忘记在 scope
中包含 offline_access
时都会遇到这个问题,但这里不是这种情况。
令牌 (ID/Access/Refresh) 不应包含在此请求中:
GET /connect/authorize?client_id=MyClientBlahBlah&response_type=code&scope=openid%20profile%20offline_access&redirect_uri=<targeturl>
相反,ASP.NET Core 中的 OpenIDConnect 处理程序将在收到授权代码后,在 ASP.NET Core 和 IdentityServer 之间的单独请求中请求令牌。 user/browser.
不可见的请求
使用下面的代码您可以检查您实际收到了哪些令牌:
string accessToken = await HttpContext.GetTokenAsync("access_token");
string idToken = await HttpContext.GetTokenAsync("id_token");
string refreshToken = await HttpContext.GetTokenAsync("refresh_token");
string tokenType = await HttpContext.GetTokenAsync("token_type");
string accessTokenExpire = await HttpContext.GetTokenAsync("expires_at");
好的,我无法让 IS4 在 authorization_code 流程期间发出刷新令牌,即使我(相信)打开了它,并且客户端通过在 offline_access
中包含来请求它范围。我使用以下方式添加 IS4:
services.AddIdentityServer()
.AddInMemoryClients(Config.Clients)
.AddPersistedGrantStore<PersistedGrantStore>()
.AddInMemoryIdentityResources(Config.IdentityResources)
.AddSigningCredential(loadedX509pfx);
// identity resources from another file:
public static IEnumerable<IdentityResource> IdentityResources =>
new IdentityResource[]
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
};
客户端定义为(为简洁起见,我包括了除 URLs 之外的所有内容):
ClientId = "MyClientBlahBlah",
ClientSecrets = new List<Secret> { new("secretXX".Sha256()) },
RequireClientSecret = false,
RequireConsent = false,
AllowedGrantTypes = GrantTypes.Code,
AccessTokenType = AccessTokenType.Jwt,
AccessTokenLifetime = (int)TimeSpan.FromDays(7).TotalSeconds,
IdentityTokenLifetime = (int)TimeSpan.FromDays(7).TotalSeconds,
AbsoluteRefreshTokenLifetime = (int)TimeSpan.FromDays(30).TotalSeconds,
SlidingRefreshTokenLifetime = (int)TimeSpan.FromDays(15).TotalSeconds,
UpdateAccessTokenClaimsOnRefresh = true,
AllowOfflineAccess = true,
RefreshTokenExpiration = TokenExpiration.Sliding,
RefreshTokenUsage = TokenUsage.OneTimeOnly,
AlwaysSendClientClaims = true,
Enabled = true,
AllowedScopes = {
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.OfflineAccess
},
RequirePkce = false,
...
但是,当请求通过此请求发出时:
GET /connect/authorize?client_id=MyClientBlahBlah&response_type=code&scope=openid%20profile%20offline_access&redirect_uri=<targeturl>
并且用户登录,重定向 URL 仅使用授权码调用:
没有任何地方提到刷新令牌。当我检查授予持久性存储时,记录已创建(尽管其设置为 5 分钟后过期),但是,存储记录中的 Data
JSON 再次没有提及刷新并且没有为该主题创建其他记录。
{
"CreationTime" : "2022-03-28T15:56:26Z",
"Lifetime" : 300,
"ClientId" : "MyClientBlahBlah",
"Subject" : {...} <full json of claims, which is ok>
"IsOpenId" : true,
"RequestedScopes" : [
"0" : "opened",
"1" : "profile",
"2" : "offline_access"
],
"RedirectUri" : "targetURL",
"Nonce" : null,
"StateHash" : "d8EeV5-CyXT_-vbd8gRcRA",
"WasConsentShown" :false,
"SessionId" : "8DBD74DF791AD6C04FCCB78A3CF57C6E",
"CodeChallenge" : "",
"CodeChallengeMethod" : null,
"Description" : null,
"Properties" : { }
}
我哪里做错了或者我忘了包括什么?我似乎无法找到有关文档的任何帮助,大多数人在忘记在 scope
中包含 offline_access
时都会遇到这个问题,但这里不是这种情况。
令牌 (ID/Access/Refresh) 不应包含在此请求中:
GET /connect/authorize?client_id=MyClientBlahBlah&response_type=code&scope=openid%20profile%20offline_access&redirect_uri=<targeturl>
相反,ASP.NET Core 中的 OpenIDConnect 处理程序将在收到授权代码后,在 ASP.NET Core 和 IdentityServer 之间的单独请求中请求令牌。 user/browser.
不可见的请求使用下面的代码您可以检查您实际收到了哪些令牌:
string accessToken = await HttpContext.GetTokenAsync("access_token");
string idToken = await HttpContext.GetTokenAsync("id_token");
string refreshToken = await HttpContext.GetTokenAsync("refresh_token");
string tokenType = await HttpContext.GetTokenAsync("token_type");
string accessTokenExpire = await HttpContext.GetTokenAsync("expires_at");