diff --git a/src/Transports.AspNetCore/AuthorizationHelper.cs b/src/Transports.AspNetCore/AuthorizationHelper.cs index 09d5666f..c9c85bea 100644 --- a/src/Transports.AspNetCore/AuthorizationHelper.cs +++ b/src/Transports.AspNetCore/AuthorizationHelper.cs @@ -12,9 +12,7 @@ public static class AuthorizationHelper /// public static async ValueTask AuthorizeAsync(AuthorizationParameters options, TState state) { - var anyRolesRequired = options.AuthorizedRoles?.Any() ?? false; - - if (options.AuthorizationRequired || anyRolesRequired || options.AuthorizedPolicy != null) + if (options.AuthorizationRequired) { if (!((options.HttpContext.User ?? NoUser()).Identity ?? NoIdentity()).IsAuthenticated) { @@ -24,7 +22,7 @@ public static async ValueTask AuthorizeAsync(AuthorizationParamete } } - if (anyRolesRequired) + if (options.AuthorizedRoles?.Any() ?? false) { var user = options.HttpContext.User ?? NoUser(); foreach (var role in options.AuthorizedRoles!) diff --git a/src/Transports.AspNetCore/AuthorizationVisitorBase.Validation.cs b/src/Transports.AspNetCore/AuthorizationVisitorBase.Validation.cs index cef523c5..8c3d5c9d 100644 --- a/src/Transports.AspNetCore/AuthorizationVisitorBase.Validation.cs +++ b/src/Transports.AspNetCore/AuthorizationVisitorBase.Validation.cs @@ -71,15 +71,15 @@ public readonly record struct ValidationInfo( /// protected virtual async ValueTask ValidateAsync(ValidationInfo info) { - bool requiresAuthorization = info.Obj.IsAuthorizationRequired(); - if (!requiresAuthorization) - return true; - - var authorized = _userIsAuthorized ??= IsAuthenticated; - if (!authorized) + //note: in v7 currently: IsAuthorizationRequired returns true if authorization is required, or if policies or roles are set + if (info.Obj.GetMetadata(AuthorizationExtensions.AUTHORIZE_KEY, false) /* info.Obj.IsAuthorizationRequired() */) { - HandleNodeNotAuthorized(info); - return false; + var authorized = _userIsAuthorized ??= IsAuthenticated; + if (!authorized) + { + HandleNodeNotAuthorized(info); + return false; + } } var policies = info.Obj.GetPolicies(); diff --git a/tests/Samples.Jwt.Tests/EndToEndTests.cs b/tests/Samples.Jwt.Tests/EndToEndTests.cs index 9ee2ca73..e6ae9b06 100644 --- a/tests/Samples.Jwt.Tests/EndToEndTests.cs +++ b/tests/Samples.Jwt.Tests/EndToEndTests.cs @@ -42,7 +42,7 @@ public async Task GraphQLGet_Authorized() [Fact] public async Task GraphQLGet_Unauthorized() { - await _testServer.VerifyGraphQLGetAsync(expected: ACCESS_DENIED_RESPONSE, statusCode: HttpStatusCode.Unauthorized); + await _testServer.VerifyGraphQLGetAsync(expected: ACCESS_DENIED_RESPONSE, statusCode: HttpStatusCode.Forbidden); } [Fact] @@ -55,7 +55,7 @@ public async Task GraphQLPost_Authorized() [Fact] public async Task GraphQLPost_Unauthorized() { - await _testServer.VerifyGraphQLPostAsync(expected: ACCESS_DENIED_RESPONSE, statusCode: HttpStatusCode.Unauthorized); + await _testServer.VerifyGraphQLPostAsync(expected: ACCESS_DENIED_RESPONSE, statusCode: HttpStatusCode.Forbidden); } [Fact] diff --git a/tests/Transports.AspNetCore.Tests/Middleware/AuthorizationTests.cs b/tests/Transports.AspNetCore.Tests/Middleware/AuthorizationTests.cs index 9c5f558a..94dd0efc 100644 --- a/tests/Transports.AspNetCore.Tests/Middleware/AuthorizationTests.cs +++ b/tests/Transports.AspNetCore.Tests/Middleware/AuthorizationTests.cs @@ -191,7 +191,7 @@ public async Task NotAuthorized_Roles(bool authenticated) _options.AuthorizedRoles.Add("AnotherRole"); _options.AuthorizedRoles.Add("FailingRole"); using var response = await PostQueryAsync("{ __typename }", authenticated); - response.StatusCode.ShouldBe(authenticated ? HttpStatusCode.Forbidden : HttpStatusCode.Unauthorized); + response.StatusCode.ShouldBe(HttpStatusCode.Forbidden); var actual = await response.Content.ReadAsStringAsync(); actual.ShouldBe("""{"errors":[{"message":"Access denied for schema.","extensions":{"code":"ACCESS_DENIED","codes":["ACCESS_DENIED"]}}]}"""); } @@ -205,16 +205,9 @@ public async Task NotAuthorized_Roles_2(bool authenticated) _options.AuthorizedRoles.Add("FailingRole"); _enableCustomErrorInfoProvider = true; using var response = await PostQueryAsync("{ __typename }", authenticated); - response.StatusCode.ShouldBe(authenticated ? HttpStatusCode.Forbidden : HttpStatusCode.Unauthorized); + response.StatusCode.ShouldBe(HttpStatusCode.Forbidden); var actual = await response.Content.ReadAsStringAsync(); - if (authenticated) - { - actual.ShouldBe("""{"errors":[{"message":"Access denied; roles required \u0027AnotherRole\u0027/\u0027FailingRole\u0027.","extensions":{"code":"ACCESS_DENIED","codes":["ACCESS_DENIED"]}}]}"""); - } - else - { - actual.ShouldBe("""{"errors":[{"message":"Access denied; authorization required.","extensions":{"code":"ACCESS_DENIED","codes":["ACCESS_DENIED"]}}]}"""); - } + actual.ShouldBe("""{"errors":[{"message":"Access denied; roles required \u0027AnotherRole\u0027/\u0027FailingRole\u0027.","extensions":{"code":"ACCESS_DENIED","codes":["ACCESS_DENIED"]}}]}"""); } [Fact] @@ -235,7 +228,7 @@ public async Task NotAuthorized_Policy(bool authenticated) { _options.AuthorizedPolicy = "FailingPolicy"; using var response = await PostQueryAsync("{ __typename }", authenticated); - response.StatusCode.ShouldBe(authenticated ? HttpStatusCode.Forbidden : HttpStatusCode.Unauthorized); + response.StatusCode.ShouldBe(HttpStatusCode.Forbidden); var actual = await response.Content.ReadAsStringAsync(); actual.ShouldBe("""{"errors":[{"message":"Access denied for schema.","extensions":{"code":"ACCESS_DENIED","codes":["ACCESS_DENIED"]}}]}"""); } @@ -248,16 +241,9 @@ public async Task NotAuthorized_Policy_2(bool authenticated) _options.AuthorizedPolicy = "FailingPolicy"; _enableCustomErrorInfoProvider = true; using var response = await PostQueryAsync("{ __typename }", authenticated); - response.StatusCode.ShouldBe(authenticated ? HttpStatusCode.Forbidden : HttpStatusCode.Unauthorized); + response.StatusCode.ShouldBe(HttpStatusCode.Forbidden); var actual = await response.Content.ReadAsStringAsync(); - if (authenticated) - { - actual.ShouldBe("""{"errors":[{"message":"Access denied; policy required \u0027FailingPolicy\u0027.","extensions":{"code":"ACCESS_DENIED","codes":["ACCESS_DENIED"]}}]}"""); - } - else - { - actual.ShouldBe("""{"errors":[{"message":"Access denied; authorization required.","extensions":{"code":"ACCESS_DENIED","codes":["ACCESS_DENIED"]}}]}"""); - } + actual.ShouldBe("""{"errors":[{"message":"Access denied; policy required \u0027FailingPolicy\u0027.","extensions":{"code":"ACCESS_DENIED","codes":["ACCESS_DENIED"]}}]}"""); } [Fact]