【问题标题】:Identityserver4 authorization across multiple applications (Grafana, .net API)跨多个应用程序的 Identityserver4 授权(Grafana、.net API)
【发布时间】:2021-09-26 20:37:05
【问题描述】:

我有以下设置:

我想为 grafana 开发自定义前端面板插件,该插件使用登录的用户凭据来授权对我的 API 的调用。根据文档,Grafana 将令牌存储在名为 grafana_session (https://grafana.com/docs/grafana/latest/administration/configuration/#login_cookie_name) 的 cookie 中。此外,with credentials 标志设置为include cookie 与调用 (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#sending_a_request_with_credentials_included)。 这是我的 identityserver4 客户端配置:

// Grafana client
new Client
{
    ClientId = "grafana_client_id",
    AllowedGrantTypes = GrantTypes.Code,
    ClientSecrets = { new Secret("grafana_client_secret".Sha256()) },
    AllowedScopes = { "openid", "profile", "email", "grafana_role" },
    RedirectUris = { "https://localhost:3000/login/generic_oauth" },
    RequirePkce = false,
},
// API
new Client
{
    ClientId = "myAPI_id",
    AllowedGrantTypes = GrantTypes.Code,
    ClientSecrets = { new Secret("myAPI_secret".Sha256()) },
    AllowedScopes = { "openid", "profile", "email", "myAPI" },
    RedirectUris = { "https://localhost:5005/signin-oidc" },
    RequirePkce = false,
},

API 端的身份验证设置:

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = "Cookies";
    options.DefaultChallengeScheme = "oidc";
})
    .AddCookie()
    .AddOpenIdConnect("oidc", options =>
    {
        options.SignInScheme = "Cookies";
        options.Authority = "https://localhost:5001";
        options.ClientId = "myAPI_id";
        options.ClientSecret = "myAPI_secret";
        options.ResponseType = "code";
        options.SaveTokens = true;
        options.GetClaimsFromUserInfoEndpoint = true;
        options.Scope.Add("openid");
        options.Scope.Add("profile");
        options.Scope.Add("myAPI");
    });

我可以使用 grafana 授权用户(id_token 保存在 cookie 中),但是当从浏览器调用 API 时,/connect/authorize 会再次使用 API 客户端的设置调用(使用 ClientId = myAPI_id 的那个)。然后,没有任何事情发生,API 端点没有被调用(看起来 API 正在等待用户再次登录)。是否可以设置身份验证以使用 Grafana 令牌来授权对我的 API 的调用?任何帮助将不胜感激。

【问题讨论】:

  • 只是为了澄清 - 我无法获得 IS 生成的 access_token 并且保存在 cookie 中的令牌不是 id_token 而是 Grafana 间隔身份验证令牌。

标签: .net-core oauth identityserver4 openid-connect grafana


【解决方案1】:

您不想在 API 中使用 OIDC。只需在启动时添加授权和身份验证:

services.AddAuthentication("bearer")
            .AddJwtBearer("bearer", options =>
            {
                options.Authority = myIDS4URL;                    
                options.Events = new Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerEvents
                {
                    OnMessageReceived = context =>
                    {

                        var accessToken = context.Request.Query["access_token"];

                        var path = context.HttpContext.Request.Path;
                        if (!string.IsNullOrEmpty(accessToken) && (path.StartsWithSegments("/myendpoint")))
                        {
                            context.Token = accessToken;
                        }
                        return Task.CompletedTask;
                    },
                    OnTokenValidated = context =>
                    {
                        var token = context.SecurityToken as JwtSecurityToken;
                        if (token != null)
                        {
                            ClaimsIdentity identity = context.Principal.Identity as ClaimsIdentity;
                            if (identity != null)
                            {
                                identity.AddClaim(new Claim("access_token", token.RawData));
                            }
                        }

                        return Task.CompletedTask;
                    }
                };

                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateAudience = false,
                    NameClaimType = "name",
                    RoleClaimType = "role"
                };
            });

然后:

services.AddAuthorization(options =>
        {
            options.AddPolicy("ApiScope", policy =>
            {
                policy.RequireAuthenticatedUser();
                policy.RequireClaim("scope", "myAPI_id");
            });
        });

【讨论】:

  • 是的,当我能够获得 Grafana 在通过身份服务器进行身份验证后获得的访问令牌时,这将起作用。经过更深入的研究,我发现 Grafana 将来自 IS 的 access_token 存储在其内部数据库中,据我所知,无法从 JavaScript 面板获取它。对于这种情况,我的解决方案是我使用 Grafana 作为身份验证权限 - 我的 API 会询问 Grafana 它的 grafana session 令牌是否仍然有效。
猜你喜欢
  • 2018-10-21
  • 2017-10-10
  • 1970-01-01
  • 2021-12-04
  • 2019-08-18
  • 2018-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多