I am working on an ASP.NET Core 2.0 RESTful API. I have a scenario where I need to use an HTTPGet method to call an action on my API controller and I need to extract a username and password value that will be used to call another 3rd party API. The username and password are not related to the current logged in user Identity, they are just values I want to send to another API from within my own API, but I do not want to just pass them in a query string.
Can I use basic authentication in the client to add the username and password to the HttpRequestMessage authentication header and then extract that header in my ASP.NET Core 2.0 API controller action?
My client wold have something like this in the code that will call the 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));
and, my API controller action would start something like this;
[HttpGet()]
public IActionResult GetUploadedFileList([FromQuery]int pageNumber, [FromQuery]int pageSize)
{
//Extract Authentication header values for username and password
}
Can anyone provide an example of how to get the Authorization header from the HTTPGet request
I realize I can easily do this with an HTTPPost [FromBody] but my use case calls for this method to be an HTTGet.
Thanks in advance for any help.
EDIT 1 - SOLUTION
I was able to get the code below to work, thanks to some hints from this link. Although this seems like a lot of work, so if anyone has a better or cleaner solution, please post your example.
[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);
}
ASP.NET Core supports a [FromHeader]
attribute for action parameters, similar to [FromBody]
and [FromQuery]
. So adding a [FromHeader]string authorization
arg to your action will shave a couple lines off your solution, as well as make the method more testable since you can avoid accessing the Request
object.