首页 > 解决方案 > 如何在 ASP.NET 核心 WEB API 控制器中获取 OpenID 信息

问题描述

有两种应用:

  1. 启用了 OpenID 连接的 OneLogin 身份提供程序。
  2. 我的 ASP.NET 核心 WEB API,它是前端应用程序的资源服务器。

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

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 声明。我错过了什么?

标签: c#asp.net-web-apiopenid-connectclaims

解决方案


您可以像这样扩展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();。请注意,声明中的内容取决于您在创建令牌时所做的投入。例如,您可能没有角色。如果您不知道,您可以通过将一个复制/粘贴到 jwt.io 来查找您的令牌包含的内容。


推荐阅读