让IS4发布刷新令牌

发布于 2025-01-17 12:08:07 字数 3010 浏览 1 评论 0原文

好的,我无法让 IS4 在授权码流期间发出刷新令牌,即使我(相信)打开了它,并且客户端通过在范围中包含 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(),
    };

客户端定义为(为了简洁起见,我包含了除 URL 之外的所有内容):

    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=

并且用户登录,仅使用授权代码调用重定向 URL :

querystrings

任何地方都没有提及刷新令牌。当我检查授予持久性存储时,记录已创建(尽管其设置为在 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" : { }
}

我做错了什么或者我忘记包括什么?我似乎找不到任何有关文档的帮助,大多数人在忘记将 offline_access 包含在 scope 中时都会遇到此问题,但这里的情况并非如此。

Ok, I am failing to get IS4 to issue a refresh token during authorization_code flow, even though I (believe) turned it on, and the client is requesting it by including offline_access in the scope. I add the IS4 using:

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(),
    };

Client is defined as (I included everything except URLs for brevity):

    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,
...

However, when the request comes via this request:
GET /connect/authorize?client_id=MyClientBlahBlah&response_type=code&scope=openid%20profile%20offline_access&redirect_uri=<targeturl>

and the user logs in, the redirect URL is called only with authorization code:

querystrings

There is no mention of refresh token anywhere. When I check the grant persistence store, the record was created (though its set to expire in 5 mins), however, again, the Data JSON in the record of store does not contain any mention of the refresh and there is no additional record being created for the subject.

{
    "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" : { }
}

What am I doing wrong or what have I forgotten to include? I can't seem to find any help with documentation, most people have this problem when they forget to include offline_access in scope, which is not the case here.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风轻花落早 2025-01-24 12:08:07

令牌(ID/访问/刷新)并不意味着包含在此请求中:

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 之间的单独请求中请求令牌。用户/浏览器不可见的请求。

使用下面的代码您可以检查您实际收到的代币:

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");    

The tokens (ID/Access/Refresh) are not meant be included in this request:

GET /connect/authorize?client_id=MyClientBlahBlah&response_type=code&scope=openid%20profile%20offline_access&redirect_uri=<targeturl>

Instead the OpenIDConnect handler in ASP.NET Core will after receiving the authorization code, ask for the tokens in a separate request between ASP.NET Core and IdentityServer. A request not visible to the user/browser.

Using the code below you can check what tokens that you actually have received:

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");    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文