如何从发送到 ASP.NET Core 2.0 API 控制器操作的请求中获取身份验证标头

13

我正在开发一个ASP.NET Core 2.0的RESTful API。我有一个场景,需要使用HTTPGet方法调用API控制器上的操作,并且我需要提取一个用户名和密码值,这些值将用于调用另一个第三方API。这个用户名和密码与当前已登录的用户身份无关,它们只是我想从自己的API中发送到另一个API的值,但是我不想在查询字符串中传递它们。

我能否在客户端中使用基本认证,将用户名和密码添加到HttpRequestMessage身份验证标头中,然后在我的ASP.NET Core 2.0 API控制器操作中提取该标头?

我的客户端代码中会有类似以下的内容,用于调用API:

    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, relativeUrl);
    var byteArray = new UTF8Encoding().GetBytes(string.Format($"username:password"));
    request.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));

而且,我的 API 控制器操作将从以下部分开始;

    [HttpGet()]
    public IActionResult GetUploadedFileList([FromQuery]int pageNumber, [FromQuery]int pageSize)
    {

        //Extract Authentication header values for username and password

    }

有人能提供一个从HTTPGet请求中获取授权头的示例吗?

我意识到使用HTTPPost [FromBody]可以很容易地实现这一点,但我的用例要求该方法为HTTGet。

非常感谢任何帮助。

编辑1-解决方案

我通过此链接得到了一些提示,成功运行了下面的代码。虽然这似乎是很多工作,但如果有更好或更清晰的解决方案,请发表您的示例。

    [HttpGet()]
    public IActionResult GetUploadedFiles([FromQuery]int pageNumber, [FromQuery]int pageSize)
    {

        string username = string.Empty;
        string password = string.Empty;

        if (Request.Headers.TryGetValue("Authorization", out StringValues authToken))
        {
            string authHeader = authToken.First();
            string encodedUsernamePassword = authHeader.Substring("Basic ".Length).Trim();
            Encoding encoding = Encoding.GetEncoding("iso-8859-1");
            string usernamePassword = encoding.GetString(Convert.FromBase64String(encodedUsernamePassword));
            int seperatorIndex = usernamePassword.IndexOf(':');
            username = usernamePassword.Substring(0, seperatorIndex);
            password = usernamePassword.Substring(seperatorIndex + 1);
        }
        else
        {
            return BadRequest("Missing Authorization Header.");
        }


        //Build FilesUploadedListRequest
        FilesUploadedListRequest filesUploadedListRequest = new FilesUploadedListRequest
        {
            Username = username,
            Password = password,
            PageNumber = pageNumber,
            PageSize = pageSize
        };

        //Call GetUploadedFilesList
        CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
        CancellationToken cancellationToken = cancellationTokenSource.Token;
        Task<FilesUploadedListResponse> FilesUploadedListResponse = _clientService.GetListOfUploadedFilesAsync(filesUploadedListRequest, cancellationToken);

        //Return results
        if (filesUploadedListResponse.Result.Success)
        {
            return Ok(filesUploadedListResponse.Result);
        }

        return StatusCode(filesUploadedListResponse.Result.StatusCode, filesUploadedListResponse.Result.Reason);

    }
1个回答

36

ASP.NET Core支持 [FromHeader] 属性用于操作参数,类似于 [FromBody][FromQuery]。 因此,将[FromHeader]string authorization 参数添加到您的操作中将减少您的解决方案中的几行代码,并使该方法更易于测试,因为您可以避免访问 Request 对象。


谢谢Todd。这正是我在寻找的。 - EiEiGuy
我想要的正是这个。 - user1267177
好的答案。非常感谢。 - SonMauri
我在我的应用程序中尝试了同样的方法,但是无法使用Request.Headers.TryGetValue("Authorization", out StringValues authToken)从请求中读取身份验证标头。是否需要对应用程序或服务进行一些初始化? - Andrea Cattaneo
在位于 DMZ 的控制器 API 中获取和授权标头是否被认为是一种不良实践? - Vkl125

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接