I'm new to AWS and need to secure access to a .NET Core Web API application using Cognito. I'm largely following the excellent video on YouTube by Les Jackson (https://www.youtube.com/watch?v=3PyUjOmuFic) but he uses Azure rather than AWS.
So far, I have a very simple API controller action that just pulls some records from SQL Server and sends a JSON response.
[HttpGet]
public async Task<IEnumerable<TodoItem>> Get()
{
var items = await context.TodoItem.ToListAsync();
return items;
}
This works fine locally in Visual Studio and also when deployed to an AWS instance using Elastic Beanstalk.
To secure the application I added to the ConfigureServices method in Startup.cs
services.AddAuthentication("Bearer")
.AddJwtBearer(options =>
{
options.Audience = "App client id";
options.Authority = "https://cognito-idp.eu-west-2.amazonaws.com/Cognito User Pool id";
});
And in the Configure method
app.UseAuthentication();
I added a controller to the application just to authenticate with Cognito and get back an Access token.
private const string _clientId = "App client id";
private readonly RegionEndpoint _region = RegionEndpoint.EUWest2;
[HttpPost]
[Route("/api/signin")]
public async Task<ActionResult<string>> SignIn(User user)
{
var cognito = new AmazonCognitoIdentityProviderClient(_region);
var request = new AdminInitiateAuthRequest
{
UserPoolId = "Cognito User Pool id",
ClientId = _clientId,
AuthFlow = AuthFlowType.ADMIN_USER_PASSWORD_AUTH
};
request.AuthParameters.Add("USERNAME", user.Username);
request.AuthParameters.Add("PASSWORD", user.Password);
var response = await cognito.AdminInitiateAuthAsync(request);
return Ok(response.AuthenticationResult);
}
After a bit of messing around I've got this working locally and on AWS, returning tokens when a Cognito user name and password are POSTed using Postman, e.g.
{
"accessToken": ".....",
"expiresIn": 3600,
"idToken": "...",
"newDeviceMetadata": null,
"refreshToken": "...",
"tokenType": "Bearer"
}
So, I added the [Authorize] attribute to my API method, got an Access Token using the SignIn method and constructed a request in Postman that includes the Authorization HTTP header with the value "Bearer " + accessToken.
Sadly, this is not working and I can't think of anything else to try.
Using Postman requests to the application running locally in IIS Express via Visual Studio, I get the response
System.InvalidOperationException: IDX20803: Unable to obtain configuration from: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
---> System.IO.IOException: IDX20807: Unable to retrieve document from: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'. HttpResponseMessage: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]', HttpResponseMessage.Content: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
When the application is deployed using Elastic Beanstalk I just get a 500 Internal Server Error with no additional messages.
What am I doing wrong? I would be grateful for any help / pointers.
Doug