403 Forbidden/500 Internal Server Error after deploying .net core api AWS serverless application
- Created a .net core AWS serverless application.
- Cognito is used for authentication.
- The user and application clients have been configured.
- When I run the solution locally it works fine (remember it's http).
When I publish using the publish wizard and hit the new url using
postman ( https://myendpoint/Prod ) I immediately get:{"message":"forbidden"}
I can only guess it has something to do with http/https here.
Authentication Controller:
public class AuthenticationController : Controller
{
[HttpPost]
[Route("api/signin")]
public async Task<ActionResult<string>> SignIn(User user)
{
var cognito = new AmazonCognitoIdentityProviderClient(RegionEndpoint.APSoutheast2);
var request = new AdminInitiateAuthRequest
{
UserPoolId = "ap-southeast-2_MYPOOLID",
ClientId = "MYCLIENTID",
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);
}
}
start.config service
services.AddSingleton<IAuthorizationHandler, CognitoGroupAuthorisationHandler>();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = "https://cognito-idp.ap-southeast-2.amazonaws.com/ap-southeast-2_MYPOOL",
ValidateIssuerSigningKey = true,
ValidateIssuer = true,
ValidateLifetime = true,
ValidAudience = "MYKEY",
ValidateAudience = true
};
});
EDIT #1 It looks like I fixed the forbidden msg, but am now getting a 500 error.
Postman produces: 500 Internal Server Error
Use API Gateway for testing (Api Gateway->Resources-> /{proxy+}->Any->Test->Post)
Method: POST proxy set to: /api/signin Request body:
{
"username": "xxx",
"password":"yyy"
}
Yield:
{"Strict-Transport-Security":"max-age=2592000","ErrorType":"AmazonCognitoIdentityProviderException","X-Amzn-Trace-Id":"Root=xxxxx;Sampled=0","Content-Type":""}
ok - this might help someone at some stage
The original "forbidden" error wasn't actually a permissions issue. When you deploy the API through the wizard, it actually adds a "staging" directory to the end of the URL. I didn't add this to my postman request. It's simple to do and ignore. This is a bit misleading - it really should be a 404.
Second part (edit #1) 500 Internal Server Error. There is no real "easy" way to fix this other than enabling cloudwatch logs for your API and then searching.
Follow this YouTube video to learn how to set it up : https://www.youtube.com/watch?v=R67huNjk88w
After looking at the logs, I found that it was a permissions issue:
Amazon.CognitoIdentityProvider.AmazonCognitoIdentityProviderException: User: arn:aws:sts::xxxxx:assumed-role/xxx-AspNetCoreFunctionRole-xxx/xxx-AspNetCoreFunction-xxxx is not authorized to perform: cognito-idp:AdminInitiateAuth on resource: arn:aws:cognito-idp:ap-southeast-2:xxxx:userpool/ap-southeast-2_xxxxx --->
Credit goes to the following articles:
https://medium.com/@fcavalcantirj/tutorial-aws-api-gateway-cognito-userpool-8cc5838eac0
Step 2.2.4.4 to be specific. Since I found that the Visual Studio wizards can handle pretty much everything else, I just had to add these extra policies.
{
"Version":"2012–10–17",
"Statement":[
{
"Effect":"Allow",
"Action":[
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource":"arn:aws:logs:*:*:*"
},
{
"Effect":"Allow",
"Action":[
"cognito-identity:*",
"cognito-idp:*",
"cognito-sync:*",
"iam:ListRoles",
"iam:ListOpenIdConnectProviders",
"sns:ListPratformApplications"
],
"Resource":"*"
}
]
}
Policies are created and applied by:
- Service->IAM->Policies->Create Policy->Json->
Paste the strategy above. (If you get an error about malformed JSON, use the existing JSON in the JSON box and just copy the content between the curly braces under Statement in the above strategy - including the curly braces themselves, obviously).
{"version":"2012-10-17","statement":[]}
Go to view policy and finish creating
Go to role click on AspNetCoreFunctionRole user logged and shown in Cloudwatch log
- Under Permissions click Attach Policy
- Enter the name of your newly created policy
- Publish to your login page and voila