【问题标题】:How to make Identity Server to add claims for given scope?如何使 Identity Server 为给定范围添加声明?
【发布时间】:2022-02-15 23:54:27
【问题描述】:

我有托管我的 Blazor Webasm 的服务器,我有 Blazor Webasm,我有我的后端 REST 服务。我控制的那 3 个(即可以更改代码)。授权是通过 Identity Server 完成的(在这里,我无法更改代码)。

到目前为止,它的工作原理是这样的,用户看到网页,登录,执行一些操作,请求发送到 REST 服务,验证授权和声明(某些操作需要管理员声明)。它有效。

但现在我想对普通用户隐藏管理员操作,为此我想检查声明。问题是,虽然 REST 服务看到了声明,但 blazor 没有——它只有少数“默认”声明,但不适用于我的范围。

REST 服务的配置非常简单:

services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
  .AddIdentityServerAuthentication(options =>
  {
    options.Authority = "identityserver_addresss";
  });

而 Blazor webasm 使用这个:

builder.Services.AddOidcAuthentication((RemoteAuthenticationOptions<OidcProviderOptions> options) =>
{
  // Configure your authentication provider options here.
  // For more information, see https://aka.ms/blazor-standalone-auth
  builder.Configuration.Bind("oidc", options.ProviderOptions);
});

builder.Services.AddHttpClient("api")
  .AddHttpMessageHandler(sp =>
  {
    var handler = sp.GetService<AuthorizationMessageHandler>()!
                  .ConfigureHandler(
                    authorizedUrls: "rest_service_address",
                    scopes: new[] { "my_scope" });
    return handler;
  });

并且配置有入口:

  "oidc": {
    "DefaultScopes": [
      "openid",
      "profile",
      "my_scope"
    ],
  }

所以从表面上看它对我来说看起来不错,我在告诉我对哪个范围感兴趣,REST 服务得到它,但我不知道为什么 blazor wasm 看不到它(它只看到“默认”声明,用户 ID,用户名)。

那么如何告诉 blazor wasm 从给定范围获取声明,或者如何告诉 IS 将它们也包含在 blazor 中?

为了检查我在 Blazor wasm 中得到的声明,我打印了来自 AuthorizeView.Context.User 的所有声明。

更新

Blazor 令牌解码(取自“userinfo”请求):

{
  "nbf": 1644922079,
  "exp": 1645051679,
  "iss": "https://identityserver_address",
  "aud": [
    "https://identityserver_address/resources",
    "my_app_rc"
  ],
  "client_id": "my_app_client",
  "sub": "-guid-",
  "auth_time": 1642149284,
  "idp": "local",
  "my_app_claim_type": [
    "user",
    "admin"
  ],
  "jti": "ae61d547b81c970c135f2a13fb5e353a",
  "scope": [
    "openid",
    "profile",
    "my_scope"
  ],
  "amr": [
    "pwd"
  ]
}

代码中可见的声明类型:

sid
sub
auth_time
idp
amr
name
preferred_username

因此,令牌(至少已转移)具有我正在寻找的信息(声明保存在“my_app_claim_type”条目中),但从代码中我看不到它(我看到令牌中不存在更多声明,但它是另一个故事)。

【问题讨论】:

    标签: blazor identityserver4 blazor-webassembly


    【解决方案1】:

    客户端看到的声明和 REST API 看到的声明通常是不同的。客户端看到的声明是 ID-token 中的声明,而 API 看到的声明是访问令牌中的声明。您的 Blazor 客户端不应该关心或查看访问令牌,因为它只是由您的 API 使用。

    您能否在您的问题中添加示例 ID 令牌和访问令牌?

    在 API 中,您可以将其设置为 false 以避免声明被重命名:

    // Or set this flag to false
    .AddJwtBearer(opt =>
    {
        ...
        opt.MapInboundClaims = false;
    });
    

    或添加这两行:

    public void ConfigureServices(IServiceCollection services)
    {
     // By default, Microsoft has some legacy claim mapping that converts
        // standard JWT claims into proprietary ones. This removes those mappings.
        JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
        JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear();
    

    在客户端,你可以添加上面两行,也可以试试下面的: (在 AddOpenIdConnect() 中)

    options.ClaimActions.MapUniqueJsonKey("website", "website");
    options.ClaimActions.MapUniqueJsonKey("gender", "gender");
    options.ClaimActions.MapUniqueJsonKey("birthdate", "birthdate");
    

    【讨论】:

    • 好的,谢谢,我添加了令牌(已解码)和可见声明。至于“不应该关心”——好吧,为了改善用户体验,我想为某些用户禁用或隐藏给定的操作(不是安全措施,纯用户体验)。为此,我需要知道给定的操作是否适用于用户。最短的方法是检查声明。
    • 我更新的答案有帮助吗?
    • 谢谢,我暂时跳过了 REST 服务,因为它(在某种程度上)在这里无关紧要,并且专注于 blazor webasm。您显示的映射的问题是AddOidcAuthentication 没有这样的成员“ClaimActions”,而您指出的“AddOpenIdConnect”来自 Microsoft.AspNetCore.Authentication.OpenIdConnect,webasm 不支持。
    猜你喜欢
    • 1970-01-01
    • 2017-05-14
    • 2015-05-29
    • 2021-10-01
    • 1970-01-01
    • 2020-06-05
    • 1970-01-01
    • 1970-01-01
    • 2018-10-16
    相关资源
    最近更新 更多