【问题标题】:Materializing Custom Principal With AspNet.Security.OpenIdConnect.Server (ASP.NET vNext)使用 AspNet.Security.OpenIdConnect.Server 实现自定义主体 (ASP.NET vNext)
【发布时间】:2016-02-04 06:59:37
【问题描述】:

我正在使用 Visual Studio 2015 Enterprise 和 ASP.NET vNext Beta8 来构建一个端点,该端点发出和使用 JWT 令牌,如详细所述 here

我正处于项目的阶段,我希望允许 JWT 不记名身份验证按照上述文章中的讨论继续进行,但是一旦令牌通过身份验证,我想:

  • 在成功进行 JWT 身份验证后介入并检查其各种声明。
  • 根据我在令牌中找到的内容,水合我自己的主体对象(例如 IContosoPrincipal)的范围实例。
  • 确保 IContosoPrincipal 的支持具体对象的范围仅限于当前请求。
  • 稍后将依赖项注入 IContosoPrincipal 到我的一个令牌保护控制器中。

我确定这将涉及一个范围内的 IContosoPrincipal 对象,我可能会弄清楚这部分,但我不确定如何在令牌成功通过身份验证之后但在控制器之前拦截 JWT 身份验证 /action 调用发生。

任何有关如何解决此问题的建议将不胜感激。

【问题讨论】:

    标签: asp.net asp.net-core jwt iprincipal aspnet-contrib


    【解决方案1】:

    ASP.NET 5 不(也不会)正式支持自定义主体/身份。您可以找到有关此主题的更多信息:https://github.com/aspnet/Security/issues/323

    相反,我们强烈建议您将所需的数据存储为单独的声明,并在需要时提供围绕ClaimsIdentity/ClaimsPrincipal 的扩展方法(例如,如果您需要格式化声明值)。

    FWIW,ASP.NET Identity 3 本身大量使用这种模式,它带有内置扩展(如GetUserNameGetUserId),您可以在自己的代码中使用:

    /// <summary>
    /// Returns the User ID claim value if present otherwise returns null.
    /// </summary>
    /// <param name="principal">The <see cref="ClaimsPrincipal"/> instance this method extends.</param>
    /// <returns>The User ID claim value, or null if the claim is not present.</returns>
    /// <remarks>The User ID claim is identified by <see cref="ClaimTypes.NameIdentifier"/>.</remarks>
    public static string GetUserId(this ClaimsPrincipal principal)
    {
        if (principal == null)
        {
            throw new ArgumentNullException(nameof(principal));
        }
        return principal.FindFirstValue(ClaimTypes.NameIdentifier);
    }
    

    https://github.com/aspnet/Identity/blob/dev/src/Microsoft.AspNet.Identity/PrincipalExtensions.cs

    【讨论】:

    • 感谢您提供信息丰富且全面的回答。如果我说我并不失望,那我就是在撒谎; ) 所以请允许我以不同的方式问这个问题 - 我想将 something 依赖注入到我的控制器中,该控制器知道我的令牌中的用户 ID 的 ID(实际上我有一个方面正在这样做,但它仍然是DI)。在 vNext 中,可接受的方法是什么。我在 AspNet.Identity 源代码中闲逛,但他们的构建器扩展立即开始使用 cookie 做事,所以不确定这是否是错误的存储库。
    • 为此,建议直接从 HTTP 请求中检索主体(通过HttpContext)。当您的组件无法直接访问 HTTP 上下文时,您可以注入 IHttpContextAccessor 作为依赖项并通过 IHttpContextAccessor.HttpContext.User 访问主体。
    • 请注意,截至今天,PrincipalExtensions url 已损坏。不确定this AspNetCore是不是真的,因为内容不同
    • 他们似乎转向了更通用的助手
    • @superjos 仅供参考:这些扩展已被 UserManagerSignManager (*.com/questions/35693239/…) 上的实例方法所取代。
    最近更新 更多