从 ASP.NET Core Web API 中的控制器访问用户身份

Posted

技术标签:

【中文标题】从 ASP.NET Core Web API 中的控制器访问用户身份【英文标题】:Access user identity from controller in ASP.NET Core Web API 【发布时间】:2019-02-11 03:36:19 【问题描述】:

根据本文档:

ASP.NET Core 2.1 Documentation

我应该能够使用 ControllerBase.UserHttpContext.User 访问用户身份。

根据上面的链接:

“从应用程序的 DI 服务集合中获取当前用户的身份也更具可测试性,因为可以轻松注入测试身份。”

据我了解,我应该在 Startup.cs 或控制器的构造函数中使用依赖注入来注入身份信息。

但是,经过无数小时的调查,我无法找到程序。

以下步骤描述了我的方案。我希望有人能指引我正确的方向。

1) 使用 Visual Studio 2017,使用以下选项创建一个 ASPNET.core Web API 项目:

类型:API 启用 Docker 支持:否 身份验证:无身份验证 HTTPS 配置:是

2) 使用以下代码将 AuthDetailsController.cs 添加到 Controllers 文件夹:

using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace CoreWebApi.Controllers

    [Route("api/[controller]")]
    [ApiController]
    public class AuthDetailsController : Controller
    


        [HttpGet]
        public JsonResult Get()
        
            var r = new Dictionary<String, Object>();

            r.Add("User.Identities", User.Identities);
            r.Add("User.Claims", User.Claims);
            r.Add("HttpContext.User.Identities", HttpContext.User.Identities);
            r.Add("HttpContext.User.Claims", HttpContext.User.Claims);

            return Json(r );
        

    

3) 作为新应用程序部署到 Azure

4) 导航到https://[site_name].azurewebsites.net/api/AuthDetails

5) 没有用户身份信息,因为访问是匿名的:

"User.Identities":["authenticationType":null,"isAuthenticated":false,"actor":null,"bootstrapContext":null,"claims":[],"label":null,"name":null,"nameClaimType":"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name","roleClaimType":"http://schemas.microsoft.com/ws/2008/06/identity/claims/role"],"User.Claims":[],"HttpContext.User.Identities":["authenticationType":null,"isAuthenticated":false,"actor":null,"bootstrapContext":null,"claims":[],"label":null,"name":null,"nameClaimType":"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name","roleClaimType":"http://schemas.microsoft.com/ws/2008/06/identity/claims/role"],"HttpContext.User.Claims":[]

6) 使用以下选项启用 Azure 身份验证:

请求未通过身份验证时要执行的操作:使用 Azure Active Directory 登录。 Azure 活动目录配置:快速模式

7) 再次打开https://[site_name].azurewebsites.net/api/AuthDetails

8) 你被重定向到登录页面

9) 登录成功后,ControllerBase.User 和 HttpContext.User 中都没有身份信息。响应与启用身份验证之前相同。

【问题讨论】:

发布您的 startup.cs 文件 - 这是需要更改的地方。您可能缺少 cookie 设置。 Cookies 是存储用户信息的地方。请参阅此处了解如何为您的应用设置 cookie:docs.microsoft.com/en-us/aspnet/core/security/authentication/… 【参考方案1】:

你必须在你的 startup.cs 中告诉需要使用的身份验证。

应该是这样的。

services.AddAuthentication(IISDefaults.AuthenticationScheme);

可以在this 上找到此详细信息的链接。

您还需要在控制器中的操作上添加 [Authorize]。只有当它被添加时,您才能检索详细信息。如果在控制器级别添加,对于不需要身份验证的操作,您可以添加 [AllowAnonymous]

[HttpGet]
[Authorize]
        public JsonResult Get()
        
            var r = new Dictionary<String, Object>();

            r.Add("User.Identities", User.Identities);
            r.Add("User.Claims", User.Claims);
            r.Add("HttpContext.User.Identities", HttpContext.User.Identities);
            r.Add("HttpContext.User.Claims", HttpContext.User.Claims);

            return Json(r );
        

【讨论】:

更改后出现异常:InvalidOperationException: No authenticationScheme is specified, and there is no DefaultChallengeScheme found【参考方案2】:

这个例子有效:

https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2

我可以使用以下方法在控制器中识别用户:

User.FindAll("preferred_username").First().Value;

这是一个不同的项目类型。它是一个 MVC 网站,而不是 API 项目。

这不是我想要的,但至少它有效。 我将研究如何将它应用到我的 API 项目中。

【讨论】:

比较工作项目和非工作项目的startup.cs文件。你应该在那里找到你的答案。【参考方案3】:

我成功了!!!

这个documentation 为我指明了正确的方向。

这些是重现我的场景的步骤:

1) 使用 Visual Studio 2017,使用以下选项创建一个 ASPNET.core Web API 项目:

类型:API 启用 Docker 支持:否 身份验证:无身份验证 HTTPS 配置:是

2) 使用以下代码将 AuthDetailsController.cs 添加到 Controllers 文件夹:

using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;

namespace CoreWebApiTest2.Controllers

    [Route("api/[controller]")]
    [ApiController]
    public class AuthDetailsController : ControllerBase
    
        // GET: api/AuthDetails
        [HttpGet]
        public Dictionary<string,string> Get()
        
            return new Dictionary<string, string>  "X-MS-CLIENT-PRINCIPAL-NAME", Request.Headers["X-MS-CLIENT-PRINCIPAL-NAME"] ,
                                                    "X-MS-CLIENT-PRINCIPAL-ID", Request.Headers["X-MS-CLIENT-PRINCIPAL-ID"]   ;

        
    

3) 作为新应用程序部署到 Azure

4) 使用以下选项启用 Azure 身份验证:

请求未通过身份验证时要执行的操作:使用 Azure Active Directory 登录。 Azure 活动目录配置:快速模式

5) 打开https://[site_name].azurewebsites.net/api/AuthDetails

6) 你被重定向到登录页面

7) 登录成功后,得到响应:

"X-MS-CLIENT-PRINCIPAL-NAME":"your_user@your_domain","X-MS-CLIENT-PRINCIPAL-ID":"your_user_ad_guid"

【讨论】:

以上是关于从 ASP.NET Core Web API 中的控制器访问用户身份的主要内容,如果未能解决你的问题,请参考以下文章

如何从 ASP.NET Core Web API 中的 SQL Server 存储过程中获取返回值

将文件从 ASP.NET Core Web api 发布到另一个 ASP.NET Core Web api

从 ASP.NET CORE Web Api 获取 React 中的特定响应标头(例如,Content-Disposition)

如何从 ASP.NET MVC 到 ASP.NET Core Web API 的 PUT?

来自静态类的 ASP.NET Core Web API 日志记录

如何通过 ASP.NET Core 3 中的中间 Web API 传递未更改的 HTTP 响应?