如何在 ASP.NET 核心 WEB API 控制器中获取 OpenID 信息

How to get OpenID info in ASP.NET core WEB API controllers

有两个应用程序:

  1. 启用 OpenID 连接的 OneLogin 身份提供者。
  2. 我的ASP.NET核心WEBAPI是前端应用的资源服务器。

最初我只使用以下代码实现了授权逻辑:

serviceCollection
            .AddAuthentication(options =>
            {
                options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(options =>
            {
                options.Audience = clientId;
                options.Authority = authority;
            });

我为我的控制器设置了 [AuthorizeAttribute],授权逻辑工作正常。 现在我需要在我的控制器中获取有关用户的信息。为此,我想使用 OpenID 信息。我通过添加 OpenID 连接修改了我的代码:

serviceCollection
            .AddAuthentication(options =>
            {
                options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(options =>
            {
                options.Audience = clientId;
                options.Authority = authority;
            })
            .AddOpenIdConnect(options =>
            {
                options.ClientId = clientId;
                options.Authority = authority;
                options.GetClaimsFromUserInfoEndpoint = true;
            });

但我在我的控制器 (User.Identity) 中仍然只看到 access_token 个声明。我错过了什么?

您可以像这样扩展 HttpContext(不需要这样做,但是调用您的控制器会更好一些,您可以将代码直接放入您的控制器中)。

public static class AuthExtensions
{
    public static string GetUserId(this HttpContext httpContext)
    {
        if (httpContext.User == null)
            return string.Empty;

        return httpContext.User.Claims.Single(x => x.Type == "id").Value;
    }

    public static UserRole GetUserRole(this HttpContext httpContext)
    {
        if (httpContext.User == null)
            throw new InvalidOperationException("User not set on httpContext.");

        var roleStr = httpContext.User.Claims.Single(x => x.Type == ClaimTypes.Role).Value;
        return (UserRole) Enum.Parse(typeof(UserRole), roleStr);
    }
}

然后你可以从你的控制器中调用它们 var userId = Request.HttpContext.GetUserId();。请注意,声明中的内容取决于您在创建令牌时放入其中的内容。例如,您可能没有角色。如果您不知道,您可以通过 copy/pasting 一到 jwt.io.

中查找您的令牌包含的内容

你有两个选择。

您可以将所需的声明添加到访问令牌(在 ApiScope 或 ApiResources 中),然后通过 API.

中的 AddJwtBearer 进行访问

或者,您可以获取访问令牌并将其发送到令牌 introspection endpoint, from the response you can get more details about the user. You can also manually call the userinfo endpoint using the access token. However, AddJWtBearer won't call these endpoints for you. The helper classes in IdentityModel 可以帮助您做到这一点。

将 AddOpenIdConnect 添加到 API,只是为了获取用户详细信息是错误的做法。