Aps .net IdentityServer4授权
Aps .net IdentityServer4 authorize
我正在使用带有 asp .net 身份的 IdentityServer4 作为身份验证点。我的 APIs/WebApps 调用身份服务器以获取访问令牌。
现在,如何在我的 api/app 控制器中的某些操作或内部操作之前授权使用?
我可以将角色添加到访问令牌,然后在控制器中(在网络 api/web 应用程序中)使用 AuthorizeAttribute 并检查用户是否 IsInRole。
但这意味着如果我要更改用户角色,他将在注销-登录后看到它(因为角色是访问令牌的一部分)或者令牌必须过期。
每次我需要授权他执行某些操作(尤其是像 modify/delete 某些数据这样的操作)时,我想询问身份服务器有关用户角色的信息。
问题如何?
或者我需要寻找什么?
所以这里有一些可能的解决方案:
- 调用 OIDC UserInfo 端点以获取每个请求的更新用户声明
- 缩短 cookie 生命周期以更频繁地自动刷新用户信息
- 在 IdentityServer 上实现一个自定义端点,以便 post 将更改信息配置到订阅的客户端列表(例如您的 Web 应用程序)。
- 让 IdentityServer 在用户配置文件数据更改时强制单点注销
就实施难度而言,降低 cookie 生命周期是最简单的(只需更改 cookie 过期时间),但不能保证声明是最新的,并且对用户可见(频繁重定向到 IdentityServer ,尽管如果访问令牌生命周期仍然有效则不需要登录)
让 webapp 在每个请求上调用 UserInfo 端点是下一个最简单的方法(参见下面的示例),但对性能的影响最差。每个请求都会产生到 IdentityServer 的往返行程。
端点/订阅者模型的性能开销最低。 UserInfo 对 IdentityServer 的请求只会在用户配置文件信息实际更改时发生。实现起来会有点复杂:
- 在您的 IdentityServer 项目中,您需要修改配置文件数据的更改,并且 post 向您的 webapp 发送一条 http 消息。该消息可以只包含修改后的用户的用户 ID。此消息需要以某种方式进行身份验证,以防止恶意用户使合法用户会话无效。您可以为此包含一个 ClientCredentials 不记名令牌。
- 您的网络应用程序需要接收和验证消息。它需要将更改后的用户 ID 存储在 OnValidatePrincipal 委托可以访问的某个地方(最有可能通过 DI 容器中的服务)
- Cookie OnValidatePrincipal 委托随后会注入此本地服务,以在验证主体之前检查用户信息是否已更改
代码示例
在每次调用时从端点获取更新的 UserInfo
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "NameOfYourCookieAuthSchemeHere",
Events = new CookieAuthenticationEvents()
{
OnValidatePrincipal = async context =>
{
// Get updated UserInfo from IdentityServer
var accessToken = context.Principal.Claims.FirstOrDefault(c => c.Type == "access_token").Value;
var userInfoClient = new UserInfoClient("https://{IdentityServerUrlGoesHere}");
var userInfoResponse = await userInfoClient.GetAsync(accessToken);
// Invalidate Principal if Error Response
if (userInfoResponse.IsError)
{
context.RejectPrincipal();
await context.HttpContext.Authentication.SignOutAsync("NameOfYourCookieAuthSchemeHere");
}
else
{
// Check if claims changed
var claimsChanged = userInfoResponse.Claims.Except(context.Principal.Claims).Any();
if (claimsChanged)
{
// Update claims and replace principal
var newIdentity = context.Principal.Identity as ClaimsIdentity;
newIdentity.AddClaims(userInfoResponse.Claims);
var updatedPrincipal = new ClaimsPrincipal();
context.ReplacePrincipal(updatedPrincipal);
context.ShouldRenew = true;
}
}
}
}
});
更新来自 IdentityServer 的已订阅更改消息。此示例假设您已经创建了一个服务(例如 IUserChangedService),该服务存储端点从 IdentityServer 接收到的 userId。我没有 webapp 的接收端点或服务的样本。
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "NameOfYourCookieAuthSchemeHere",
Events = new CookieAuthenticationEvents()
{
OnValidatePrincipal = async context =>
{
// Get User ID
var userId = context.Principal.Claims.FirstOrDefault(c => c.Type == "UserIdClaimTypeHere");
var userChangedService = context.HttpContext.RequestServices.GetRequiredService<IUserChangedService>();
var userChanged = await userChangedService.HasUserChanged(userId);
if (userChanged)
{
// Make call to UserInfoEndpoint and update ClaimsPrincipal here. See example above for details
}
}
}
});
asp.net 核心文档也有这方面的示例,但使用本地数据库除外。连接到 OnValidatePrincipal 方法的方法是相同的:
https://docs.microsoft.com/en-us/aspnet/core/security/authentication/cookie#reacting-to-back-end-changes
希望对您有所帮助!
我正在使用带有 asp .net 身份的 IdentityServer4 作为身份验证点。我的 APIs/WebApps 调用身份服务器以获取访问令牌。
现在,如何在我的 api/app 控制器中的某些操作或内部操作之前授权使用?
我可以将角色添加到访问令牌,然后在控制器中(在网络 api/web 应用程序中)使用 AuthorizeAttribute 并检查用户是否 IsInRole。
但这意味着如果我要更改用户角色,他将在注销-登录后看到它(因为角色是访问令牌的一部分)或者令牌必须过期。
每次我需要授权他执行某些操作(尤其是像 modify/delete 某些数据这样的操作)时,我想询问身份服务器有关用户角色的信息。
问题如何? 或者我需要寻找什么?
所以这里有一些可能的解决方案:
- 调用 OIDC UserInfo 端点以获取每个请求的更新用户声明
- 缩短 cookie 生命周期以更频繁地自动刷新用户信息
- 在 IdentityServer 上实现一个自定义端点,以便 post 将更改信息配置到订阅的客户端列表(例如您的 Web 应用程序)。
- 让 IdentityServer 在用户配置文件数据更改时强制单点注销
就实施难度而言,降低 cookie 生命周期是最简单的(只需更改 cookie 过期时间),但不能保证声明是最新的,并且对用户可见(频繁重定向到 IdentityServer ,尽管如果访问令牌生命周期仍然有效则不需要登录)
让 webapp 在每个请求上调用 UserInfo 端点是下一个最简单的方法(参见下面的示例),但对性能的影响最差。每个请求都会产生到 IdentityServer 的往返行程。
端点/订阅者模型的性能开销最低。 UserInfo 对 IdentityServer 的请求只会在用户配置文件信息实际更改时发生。实现起来会有点复杂:
- 在您的 IdentityServer 项目中,您需要修改配置文件数据的更改,并且 post 向您的 webapp 发送一条 http 消息。该消息可以只包含修改后的用户的用户 ID。此消息需要以某种方式进行身份验证,以防止恶意用户使合法用户会话无效。您可以为此包含一个 ClientCredentials 不记名令牌。
- 您的网络应用程序需要接收和验证消息。它需要将更改后的用户 ID 存储在 OnValidatePrincipal 委托可以访问的某个地方(最有可能通过 DI 容器中的服务)
- Cookie OnValidatePrincipal 委托随后会注入此本地服务,以在验证主体之前检查用户信息是否已更改
代码示例
在每次调用时从端点获取更新的 UserInfo
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "NameOfYourCookieAuthSchemeHere",
Events = new CookieAuthenticationEvents()
{
OnValidatePrincipal = async context =>
{
// Get updated UserInfo from IdentityServer
var accessToken = context.Principal.Claims.FirstOrDefault(c => c.Type == "access_token").Value;
var userInfoClient = new UserInfoClient("https://{IdentityServerUrlGoesHere}");
var userInfoResponse = await userInfoClient.GetAsync(accessToken);
// Invalidate Principal if Error Response
if (userInfoResponse.IsError)
{
context.RejectPrincipal();
await context.HttpContext.Authentication.SignOutAsync("NameOfYourCookieAuthSchemeHere");
}
else
{
// Check if claims changed
var claimsChanged = userInfoResponse.Claims.Except(context.Principal.Claims).Any();
if (claimsChanged)
{
// Update claims and replace principal
var newIdentity = context.Principal.Identity as ClaimsIdentity;
newIdentity.AddClaims(userInfoResponse.Claims);
var updatedPrincipal = new ClaimsPrincipal();
context.ReplacePrincipal(updatedPrincipal);
context.ShouldRenew = true;
}
}
}
}
});
更新来自 IdentityServer 的已订阅更改消息。此示例假设您已经创建了一个服务(例如 IUserChangedService),该服务存储端点从 IdentityServer 接收到的 userId。我没有 webapp 的接收端点或服务的样本。
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "NameOfYourCookieAuthSchemeHere",
Events = new CookieAuthenticationEvents()
{
OnValidatePrincipal = async context =>
{
// Get User ID
var userId = context.Principal.Claims.FirstOrDefault(c => c.Type == "UserIdClaimTypeHere");
var userChangedService = context.HttpContext.RequestServices.GetRequiredService<IUserChangedService>();
var userChanged = await userChangedService.HasUserChanged(userId);
if (userChanged)
{
// Make call to UserInfoEndpoint and update ClaimsPrincipal here. See example above for details
}
}
}
});
asp.net 核心文档也有这方面的示例,但使用本地数据库除外。连接到 OnValidatePrincipal 方法的方法是相同的: https://docs.microsoft.com/en-us/aspnet/core/security/authentication/cookie#reacting-to-back-end-changes
希望对您有所帮助!