Closed junaid-ahmed92 closed 3 years ago
It looks like we probably have a bug or at least a confusing UX here. Check out these other issues for more info: https://github.com/aws/aws-aspnet-cognito-identity-provider/issues/86 https://github.com/aws/aws-aspnet-cognito-identity-provider/issues/101
I'm also running into this issue. Based on the docs here:
Based on the guide, you should be able to add [Authorize(Roles = "Admin")]
but when I do that, I get errors. Based on https://github.com/aws/aws-aspnet-cognito-identity-provider/issues/86 the solution is to write a custom authorization handler -- is this still the case?
2020-04-13 20:28:38.495 -05:00 [Information] Service=Services Env=VM Context=Microsoft.AspNetCore.Authorization.DefaultAuthorizationService Authorization failed.
2020-04-13 20:28:38.499 -05:00 [Information] Service=Services Env=VM Context=Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
2020-04-13 20:28:38.508 -05:00 [Information] Service=Services Env=VM Context=Microsoft.AspNetCore.Mvc.ChallengeResult Executing ChallengeResult with authentication schemes ([]).
2020-04-13 20:28:38.537 -05:00 [Information] Service=Services Env=VM Context=Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler AuthenticationScheme: Identity.Application was challenged.
I've been playing with it more without any success on .NET Core 2.2. Following this guide I have in my appsettings.json
"AWS": {
"Region": "us-east-2",
"UserPoolClientId": "xxx",
"UserPoolClientSecret": "xxx",
"UserPoolId": "us-east-2_xxxxxx"
},
Under ConfigureServices
, among a few other settings, I have services.AddCognitoIdentity();
and lately I have app.UseAuthentication();
in Configure
.
In my API controller, I simply have [Authorize(Roles = "name_of_group")]
I successfully have Cognito setup, and issuing tokens based on a SAML link to ADFS. I can get a token via Postman from Cognito and when I use this token with API gateway behind a mock method linked to that group, it successfully works.
When I use that same token hitting the .NET Core API directly using the setup above, it fails without really any messages of value and then tries to forward the API call to https://localhost:8080/Account/Login?ReturnUrl=/api/test
Ultimately I'm trying to maintain multiple user groups in a Cognito pool, and based on that group, authorize (or not) someone the ability to use a specific API in a controller. It looks simple on the guide above, hopefully I'm just missing something silly.
I'm trying to do the same thing and have used the same blog, and I'm seeing the same issue. I noticed that /Account/Login is in the sample code on GitHub so maybe /Account/Login is hardcoded somewhere. I don't even have an /Account/Login in my code.
Hi @junaid-ahmed92,
I came across the useful article ASP.NET Core with AWS Lambda and Cognito which might be useful for configuring Cognito Group based authorization in an ASP.NET Core application. It has a section Groups and Policies which provides the following details to add a custom policy.
You can use [Authorize] to ensure that only logged-in users can access the Page/Controller/Route. However you’d probably like more fine-grained control, so for that you can add users to Cognito Groups. On the ASP.NET Core app, those groups are sent as part of the user Claims. You can create authorization polices during the Startup.Configure method as follows:
services.AddAuthorization(options =>
{
options.AddPolicy("AdminOnly", policy =>
policy.RequireAssertion(context =>
context.User.HasClaim(c => c.Type == "cognito:groups" && c.Value == "Admin")));
});
This creates a policy requiring the logged in user to be part of the Cognito group Admin. To use this on a Page/Controller/Route, refer to the policy name in the Authorize attribute:
[Authorize(Policy = "AdminOnly")]
Article Now generally available: the ASP.NET Core Identity Provider for Amazon Cognito also provides similar guidance.
Please let me know if this helps.
Thanks, Ashish
@ashishdhingra We have many clients that we plan on using one User Pool for in order to enable Single Sign-On. If we use Cognito for authorization groups, then we end up with conflicting group names. We could use AppA_Admin and AppB_Admin, but that just seems too convoluted. Is there a better way to accomplish what we're trying to accomplish? Otherwise, we are thinking we'll just add authorization to each individual app and only use Cognito for Authentication. It would be nice if Cognito had a groups "layer" where we could associate groups to a Client and to a user.
@ellismichaelarb You can create multiple app clients in a user pool having groups. Not sure how it would fit to your scenario, but please refer the Cognito documentation for more details and give it a try.
@junaid-ahmed92 Please review the guidance above and confirm if this issue could be closed.
Thanks, Ashish
This issue has not recieved a response in 2 weeks. If you want to keep this issue open, please just leave a comment below and auto-close will be canceled.
I have solved the issue of [Authorize(Roles = "Admin")] not working correctly by creating a custom authorization handler and registered it in the DI container as follows:
public class CognitoGroupAuthorizationHandler: AuthorizationHandler<RolesAuthorizationRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RolesAuthorizationRequirement requirement)
{
if (context.User.HasClaim(c => c.Type == "cognito:groups" && requirement.AllowedRoles.Contains(c.Value)))
{
context.Succeed(requirement);
}
else
{
context.Fail();
}
return Task.CompletedTask;
}
}
And registration:
builder.Services.AddSingleton<IAuthorizationHandler, CognitoGroupAuthorizationHandler>();
Hope this helps :)
I am totally new to AWS and I am using aws cognito for authetication and authorization purpose. By following this link https://aws.amazon.com/blogs/aws/new-amazon-cognito-groups-and-fine-grained-role-based-access-control-2/ I created one group and added some users in that group. Now the issue I am facing is how can I validate user roles in my .net core webapi? I can validate token signatures (iss, aud) in the middleware but if I have an api with [Authorize(Roles="Admin")] attribute then how can I validate the role?
Except this I have one other question as well. In the above mentioned document, it's written that we have to create an IAM role and assign the role to that group. So would it be a simple role with no attached policies? I created one IAM web identity role for AWS cognito and assigned that role to an Admin group in cognito and I can see a role claim in my IdToken but I just want to make sure that if it's a right way or not?