0

I'm using Amazon Cognito for authentication and authorization. I can restrict an endpoint by adding the AuthorizeAttribute [Authorize(Policy = "SomeGroup")] but how do I add some business logic to check if an user is in a specific role inside an endpoint method and basically return a message depending on that?

public static Task<IResult> Test()
{
    if (user is an administrator) 
    {
        return Task.FromResult(Results.BadRequest("admin"));
    }

    return Task.FromResult(Results.Ok("not admin"));
}

Code

builder.Services.AddSingleton<IAuthorizationHandler, CognitoGroupAuthorizationHandler>();
builder.Services.AddCognitoIdentity();

builder.Services
    .AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(options =>
    {
        options.Authority = builder.Configuration["AWSCognito:Authority"];
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            ValidateAudience = false
        };
    });

builder.Services.AddAuthorization(options =>
{
    options.DefaultPolicy = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme).RequireAuthenticatedUser().Build();
    options.AddPolicy("SomeGroup", policy => policy.Requirements.Add(new CognitoGroupAuthorizationRequirement("Example")));
});

public class CognitoGroupAuthorizationHandler : AuthorizationHandler<CognitoGroupAuthorizationRequirement>
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CognitoGroupAuthorizationRequirement requirement)
    {
        if (context.User.HasClaim(c => c.Type == "cognito:groups" && c.Value == requirement.CognitoGroup))
        {
            context.Succeed(requirement);
        }
        else
        {
            context.Fail();
        }

        return Task.CompletedTask;
    }
}

public class CognitoGroupAuthorizationRequirement : IAuthorizationRequirement
{
    public CognitoGroupAuthorizationRequirement(string cognitoGroup)
    {
        CognitoGroup = cognitoGroup;
    }

    public string CognitoGroup { get; }
}
John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
nop
  • 4,711
  • 6
  • 32
  • 93
  • 1
    Get username and then check if user is in the group : https://stackoverflow.com/questions/263486/how-to-get-the-current-user-in-asp-net-mvc?force_isolation=true – jdweng Aug 09 '22 at 09:48
  • @jdweng, https://github.com/danielpereirac/WebAdvert/blob/bf543192605e12da531e8ba32909854c5956937d/WebAdvert/Controllers/AccountsController.cs take a look at that source code. Something like that? – nop Aug 09 '22 at 10:10
  • Where is the code getting the username of the HTTP connection? – jdweng Aug 09 '22 at 10:47
  • is role part of claim? if yes then check [this](https://stackoverflow.com/a/72869487/9247039) – CodingMytra Aug 09 '22 at 11:54
  • @jdweng, I'm not sure how it fits with AWS Cognito. That's why I asked the question. – nop Aug 09 '22 at 12:26
  • @CodingMytra, not sure. Imagine that there is no existing environment and you've to do it from scratch. The only codebase I have is what I gave in the question. https://github.com/aws/aws-aspnet-cognito-identity-provider/blob/master/docs/7-User%20Roles.md – nop Aug 09 '22 at 12:27
  • Question has nothing to do with AWS Cognito. You are using Windows and a controller and the credentials are coming from windows. The credentials then get applied to the AWS Cognito. – jdweng Aug 09 '22 at 15:36

0 Answers0