Identity Server 4 令牌到期 Api 与 ClientApp
Identity Server 4 token expiration Api vs ClientApp
我目前正在构建一个带有 authentication/authorization 的 WebApp 以访问它并访问多个 WebAPI,所有这些都指向一个 Identity Server 4 主机。
我遵循了 IdentityServer4 的官方文档及其演示,以及客户端身份验证、令牌生成、用户登录、API 被令牌成功调用,显然一切正常,但最近我注意到一段时间后不活动时,对 API 的调用开始收到 401,但客户端应用程序仍然使用相同的标记。
是这样的:
- 启动浏览器进行调试
- 用某个用户登录
- 转到调用一个 API 为其检索数据的视图
- 继续导航和测试,其他一切正常
现在,问题(在前面的第 4 步之后)
- 停止调试但保持浏览器启动并运行(保留 cookie)
- 更改代码,实现新的东西(基本上是在消磨一些时间)
- 再次启动调试
- 在已打开的浏览器上使用相同的 sessions/cookie,尝试在应用程序上导航工作正常,不需要重新登录
- 导航到将使用当前令牌调用 API 的视图,在以前没有的情况下给了我 401
我发现令牌已过期,Visual Studio 输出指出了这一点(同时检查 https://jwt.io/ 上的令牌我可以确认日期时间)。
为什么相同的令牌对 ClientApp 可以正常工作,而调用 API 却不行?由于 API 的调用,我是否需要手动生成新令牌?
我使用的配置是:
---客户申请---
new Client
{
ClientId = "idWebApp",
ClientSecrets = new List<Secret> { new Secret("secret".Sha256()) },
AllowedGrantTypes = GrantTypes.Hybrid,
AllowAccessTokensViaBrowser = false,
EnableLocalLogin = true,
RedirectUris = { "http://localhost:5901/signin-oidc" },
FrontChannelLogoutUri = "http://localhost:5901/signout-oidc",
PostLogoutRedirectUris = { "http://localhost:5901/signout-callback-oidc" },
AllowOfflineAccess = true,
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.OfflineAccess,
"apiAccess",
},
RequireConsent = false,
}
---API资源---
(仅使用简单的 ctor 以 'Name' 进行初始化)
new ApiResource("apiAccess")
---自定义声明---
new IdentityResource()
{
Name = "appCustomClaims",
UserClaims = new List<string>()
{
"customRole"
}
}
---ClientApp的启动代码---
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.Authority = "http://localhost:5900";
options.RequireHttpsMetadata = false;
options.ClientId = "idWebApp";
options.ClientSecret = "secret";
options.ResponseType = "code id_token";
options.Scope.Add("profile");
options.Scope.Add("offline_access");
options.ClaimActions.MapUniqueJsonKey("offline_access", "offline_access");
options.Scope.Add("appCustomClaims");
options.ClaimActions.MapJsonKey("customRole", "customRole");
options.Scope.Add("apiAccess");
options.GetClaimsFromUserInfoEndpoint = true;
options.SaveTokens = true;
options.TokenValidationParameters.RoleClaimType = "customRole";
});
Why the same token works fine for the ClientApp while invoking the API
doesn't?
两件事:
- 访问令牌的过期时间与您的操作无关。
JWT 令牌一旦颁发就无法更改。默认情况下,令牌会在 3600 秒后过期。
- 应用程序与api的区别:应用程序使用cookies,api一个bearer token。
cookie 有自己的过期逻辑。这意味着它在不同的时间过期,与访问令牌的过期时间无关,并且还可以保持活动状态,因为可以更新 cookie,这与 JWT 访问令牌不同。
对于 offline_access
,您需要使用刷新令牌获取新的访问令牌。正如所解释的 .
我目前正在构建一个带有 authentication/authorization 的 WebApp 以访问它并访问多个 WebAPI,所有这些都指向一个 Identity Server 4 主机。 我遵循了 IdentityServer4 的官方文档及其演示,以及客户端身份验证、令牌生成、用户登录、API 被令牌成功调用,显然一切正常,但最近我注意到一段时间后不活动时,对 API 的调用开始收到 401,但客户端应用程序仍然使用相同的标记。
是这样的:
- 启动浏览器进行调试
- 用某个用户登录
- 转到调用一个 API 为其检索数据的视图
- 继续导航和测试,其他一切正常
现在,问题(在前面的第 4 步之后)
- 停止调试但保持浏览器启动并运行(保留 cookie)
- 更改代码,实现新的东西(基本上是在消磨一些时间)
- 再次启动调试
- 在已打开的浏览器上使用相同的 sessions/cookie,尝试在应用程序上导航工作正常,不需要重新登录
- 导航到将使用当前令牌调用 API 的视图,在以前没有的情况下给了我 401
我发现令牌已过期,Visual Studio 输出指出了这一点(同时检查 https://jwt.io/ 上的令牌我可以确认日期时间)。 为什么相同的令牌对 ClientApp 可以正常工作,而调用 API 却不行?由于 API 的调用,我是否需要手动生成新令牌?
我使用的配置是:
---客户申请---
new Client
{
ClientId = "idWebApp",
ClientSecrets = new List<Secret> { new Secret("secret".Sha256()) },
AllowedGrantTypes = GrantTypes.Hybrid,
AllowAccessTokensViaBrowser = false,
EnableLocalLogin = true,
RedirectUris = { "http://localhost:5901/signin-oidc" },
FrontChannelLogoutUri = "http://localhost:5901/signout-oidc",
PostLogoutRedirectUris = { "http://localhost:5901/signout-callback-oidc" },
AllowOfflineAccess = true,
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.OfflineAccess,
"apiAccess",
},
RequireConsent = false,
}
---API资源---
(仅使用简单的 ctor 以 'Name' 进行初始化)
new ApiResource("apiAccess")
---自定义声明---
new IdentityResource()
{
Name = "appCustomClaims",
UserClaims = new List<string>()
{
"customRole"
}
}
---ClientApp的启动代码---
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.Authority = "http://localhost:5900";
options.RequireHttpsMetadata = false;
options.ClientId = "idWebApp";
options.ClientSecret = "secret";
options.ResponseType = "code id_token";
options.Scope.Add("profile");
options.Scope.Add("offline_access");
options.ClaimActions.MapUniqueJsonKey("offline_access", "offline_access");
options.Scope.Add("appCustomClaims");
options.ClaimActions.MapJsonKey("customRole", "customRole");
options.Scope.Add("apiAccess");
options.GetClaimsFromUserInfoEndpoint = true;
options.SaveTokens = true;
options.TokenValidationParameters.RoleClaimType = "customRole";
});
Why the same token works fine for the ClientApp while invoking the API doesn't?
两件事:
- 访问令牌的过期时间与您的操作无关。
JWT 令牌一旦颁发就无法更改。默认情况下,令牌会在 3600 秒后过期。
- 应用程序与api的区别:应用程序使用cookies,api一个bearer token。
cookie 有自己的过期逻辑。这意味着它在不同的时间过期,与访问令牌的过期时间无关,并且还可以保持活动状态,因为可以更新 cookie,这与 JWT 访问令牌不同。
对于 offline_access
,您需要使用刷新令牌获取新的访问令牌。正如所解释的