server: .net core 7 AddAuthorizationRule not work

Program:

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("111", policy =>
        policy.Requirements.Add(new MinimumAgeRequirement()));
});

builder.Services.AddTransient<IAuthorizationHandler, MinimumAgeHandler>();

builder.Services.AddGraphQL(b => b
    .AddSchema<Common_Base_Schemas>()
    .AddSchema<IMS_Schemas>()

    .AddAutoClrMappings()
    .AddSystemTextJson()
    .AddAuthorizationRule());

var app = builder.Build();

app.UseDeveloperExceptionPage();

app.UseAuthentication();
app.UseAuthorization();

app.UseWebSockets();

Query:

    public class Query
    {
        [AllowAnonymous]
        public static CompanyEntity? companyEntity()
        {
            return new CompanyEntity() { rowkey = Guid.NewGuid().ToString(), CompanyId = "11", CompanyName = "12" };
        }
        [Authorize(Policy = "111")]
        public static IEnumerable<CompanyEntity>? companyAll()
        {
            return new CompanyEntity[] { new CompanyEntity() { rowkey = Guid.NewGuid().ToString(), CompanyId = "A11"} };
        }
    }

MinimumAgeRequirement :

    public class MinimumAgeRequirement : IAuthorizationRequirement
    {
    }

MinimumAgeHandler :

    public class MinimumAgeHandler : AuthorizationHandler<MinimumAgeRequirement>
    {
        protected override Task HandleRequirementAsync(
            AuthorizationHandlerContext context, MinimumAgeRequirement requirement)
        {
            context.Succeed(requirement);

            return Task.CompletedTask;
        }
    }

Error accessing “companyAll”:

{
   "error": {
     "errors": [
       {
         "message": "Access denied for field 'companyAll' on type 'Query'.",
         "locations": [
           {
             "line": 10,
             "column": 3
           }
         ],
         "extensions": {
           "code": "ACCESS_DENIED",
           "codes": [
             "ACCESS_DENIED"
           ]
         }
       }
     ]
   }
}

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 29 (14 by maintainers)

Most upvoted comments

Here is a sample of the latter:

public class MyAuthorizationVisitor : AuthorizationVisitor
{
    public MyAuthorizationVisitor(ValidationContext context, ClaimsPrincipal claimsPrincipal, IAuthorizationService authorizationService)
        : base(context, claimsPrincipal, authorizationService)
    {
    }

    protected override bool IsAuthenticated => true;
}

public class MyAuthorizationRule : IValidationRule
{
    public virtual async ValueTask<INodeVisitor?> ValidateAsync(ValidationContext context)
    {
        var user = context.User
            ?? throw new InvalidOperationException("User could not be retrieved from ValidationContext. Please be sure it is set in ExecutionOptions.User.");
        var provider = context.RequestServices
            ?? throw new MissingRequestServicesException();
        var authService = provider.GetService<IAuthorizationService>()
            ?? throw new InvalidOperationException("An instance of IAuthorizationService could not be pulled from the dependency injection framework.");

        var visitor = new MyAuthorizationVisitor(context, user, authService);
        // if the schema fails authentication, report the error and do not perform any additional authorization checks.
        return await visitor.ValidateSchemaAsync(context) ? visitor : null;
    }
}

builder.AddValidationRule<MyAuthorizationRule>();
// remove builder.AddAuthorizationRule()