Skip to content

Commit 8ba6ea4

Browse files
authored
Authorization Failure Reasons (#35668)
1 parent f6452bf commit 8ba6ea4

File tree

7 files changed

+22
-19
lines changed

7 files changed

+22
-19
lines changed

src/Security/Authorization/Core/src/AuthorizationFailure.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ private AuthorizationFailure() { }
2727
/// <summary>
2828
/// Allows <see cref="IAuthorizationHandler"/> to flow more detailed reasons for why authorization failed.
2929
/// </summary>
30-
public IEnumerable<AuthorizationFailureReason> Reasons { get; private set; } = Array.Empty<AuthorizationFailureReason>();
30+
public IEnumerable<AuthorizationFailureReason> FailureReasons { get; private set; } = Array.Empty<AuthorizationFailureReason>();
3131

3232
/// <summary>
3333
/// Return a failure due to <see cref="AuthorizationHandlerContext.Fail()"/> being called.
@@ -47,7 +47,7 @@ public static AuthorizationFailure Failed(IEnumerable<AuthorizationFailureReason
4747
=> new AuthorizationFailure
4848
{
4949
FailCalled = true,
50-
Reasons = reasons
50+
FailureReasons = reasons
5151
};
5252

5353
/// <summary>

src/Security/Authorization/Core/src/AuthorizationFailureReason.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ public AuthorizationFailureReason(IAuthorizationHandler handler, string message)
2222
/// <summary>
2323
/// A message describing the failure reason.
2424
/// </summary>
25-
public string Message { get; set; }
25+
public string Message { get; }
2626

2727
/// <summary>
2828
/// The <see cref="IAuthorizationHandler"/> responsible for this failure reason.
2929
/// </summary>
30-
public IAuthorizationHandler Handler { get; set; }
30+
public IAuthorizationHandler Handler { get; }
3131
}
3232
}

src/Security/Authorization/Core/src/AuthorizationHandlerContext.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.Authorization
1414
public class AuthorizationHandlerContext
1515
{
1616
private readonly HashSet<IAuthorizationRequirement> _pendingRequirements;
17-
private readonly List<AuthorizationFailureReason> _failedReasons;
17+
private List<AuthorizationFailureReason>? _failedReasons;
1818
private bool _failCalled;
1919
private bool _succeedCalled;
2020

@@ -38,7 +38,6 @@ public AuthorizationHandlerContext(
3838
User = user;
3939
Resource = resource;
4040
_pendingRequirements = new HashSet<IAuthorizationRequirement>(requirements);
41-
_failedReasons = new List<AuthorizationFailureReason>();
4241
}
4342

4443
/// <summary>
@@ -64,7 +63,8 @@ public AuthorizationHandlerContext(
6463
/// <summary>
6564
/// Gets the reasons why authorization has failed.
6665
/// </summary>
67-
public virtual IEnumerable<AuthorizationFailureReason> FailureReasons { get { return _failedReasons; } }
66+
public virtual IEnumerable<AuthorizationFailureReason> FailureReasons
67+
=> (IEnumerable<AuthorizationFailureReason>?)_failedReasons ?? Array.Empty<AuthorizationFailureReason>();
6868

6969
/// <summary>
7070
/// Flag indicating whether the current authorization processing has failed.
@@ -101,6 +101,11 @@ public virtual void Fail(AuthorizationFailureReason reason)
101101
Fail();
102102
if (reason != null)
103103
{
104+
if (_failedReasons == null)
105+
{
106+
_failedReasons = new List<AuthorizationFailureReason>();
107+
}
108+
104109
_failedReasons.Add(reason);
105110
}
106111
}

src/Security/Authorization/Core/src/PublicAPI.Unshipped.txt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
#nullable enable
22
*REMOVED*static Microsoft.AspNetCore.Authorization.AuthorizationServiceExtensions.AuthorizeAsync(this Microsoft.AspNetCore.Authorization.IAuthorizationService! service, System.Security.Claims.ClaimsPrincipal! user, object! resource, Microsoft.AspNetCore.Authorization.IAuthorizationRequirement! requirement) -> System.Threading.Tasks.Task<Microsoft.AspNetCore.Authorization.AuthorizationResult!>!
3-
Microsoft.AspNetCore.Authorization.AuthorizationFailure.Reasons.get -> System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Authorization.AuthorizationFailureReason!>!
3+
Microsoft.AspNetCore.Authorization.AuthorizationFailure.FailureReasons.get -> System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Authorization.AuthorizationFailureReason!>!
44
Microsoft.AspNetCore.Authorization.AuthorizationFailureReason
55
Microsoft.AspNetCore.Authorization.AuthorizationFailureReason.AuthorizationFailureReason(Microsoft.AspNetCore.Authorization.IAuthorizationHandler! handler, string! message) -> void
66
Microsoft.AspNetCore.Authorization.AuthorizationFailureReason.Handler.get -> Microsoft.AspNetCore.Authorization.IAuthorizationHandler!
7-
Microsoft.AspNetCore.Authorization.AuthorizationFailureReason.Handler.set -> void
87
Microsoft.AspNetCore.Authorization.AuthorizationFailureReason.Message.get -> string!
9-
Microsoft.AspNetCore.Authorization.AuthorizationFailureReason.Message.set -> void
108
static Microsoft.AspNetCore.Authorization.AuthorizationFailure.Failed(System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Authorization.AuthorizationFailureReason!>! reasons) -> Microsoft.AspNetCore.Authorization.AuthorizationFailure!
119
static Microsoft.AspNetCore.Authorization.AuthorizationServiceExtensions.AuthorizeAsync(this Microsoft.AspNetCore.Authorization.IAuthorizationService! service, System.Security.Claims.ClaimsPrincipal! user, object? resource, Microsoft.AspNetCore.Authorization.IAuthorizationRequirement! requirement) -> System.Threading.Tasks.Task<Microsoft.AspNetCore.Authorization.AuthorizationResult!>!
1210
virtual Microsoft.AspNetCore.Authorization.AuthorizationHandlerContext.Fail(Microsoft.AspNetCore.Authorization.AuthorizationFailureReason! reason) -> void

src/Security/Authorization/test/DefaultAuthorizationServiceTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,11 +213,11 @@ public async Task CanFailWithReasons()
213213
// Assert
214214
Assert.False(allowed.Succeeded);
215215
Assert.NotNull(allowed.Failure);
216-
Assert.Equal(2, allowed.Failure.Reasons.Count());
217-
var first = allowed.Failure.Reasons.First();
216+
Assert.Equal(2, allowed.Failure.FailureReasons.Count());
217+
var first = allowed.Failure.FailureReasons.First();
218218
Assert.Equal("1", first.Message);
219219
Assert.Equal(handler1, first.Handler);
220-
var second = allowed.Failure.Reasons.Last();
220+
var second = allowed.Failure.FailureReasons.Last();
221221
Assert.Equal("3", second.Message);
222222
Assert.Equal(handler3, second.Handler);
223223
}

src/Security/samples/CustomAuthorizationFailureResponse/Authorization/SampleAuthorizationMiddlewareResultHandler.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ public async Task HandleAsync(
3131
// if the authorization was forbidden, let's use custom logic to handle that.
3232
if (policyAuthorizationResult.Forbidden && policyAuthorizationResult.AuthorizationFailure != null)
3333
{
34-
if (policyAuthorizationResult.AuthorizationFailure.Reasons.Any())
34+
if (policyAuthorizationResult.AuthorizationFailure.FailureReasons.Any())
3535
{
36-
await httpContext.Response.WriteAsync(policyAuthorizationResult.AuthorizationFailure.Reasons.First().Message);
36+
await httpContext.Response.WriteAsync(policyAuthorizationResult.AuthorizationFailure.FailureReasons.First().Message);
3737

3838
// return right away as the default implementation would overwrite the status code
3939
return;

src/Security/samples/CustomAuthorizationFailureResponse/Startup.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ public void ConfigureServices(IServiceCollection services)
3535

3636
services.AddAuthorization(options =>
3737
{
38-
options.AddPolicy(SamplePolicyNames.CustomPolicy, policy =>
38+
options.AddPolicy(SamplePolicyNames.CustomPolicy, policy =>
3939
policy.AddRequirements(new SampleRequirement()));
4040

41-
options.AddPolicy(SamplePolicyNames.FailureReasonPolicy, policy =>
41+
options.AddPolicy(SamplePolicyNames.FailureReasonPolicy, policy =>
4242
policy.AddRequirements(new SampleFailReasonRequirement()));
43-
44-
options.AddPolicy(SamplePolicyNames.CustomPolicyWithCustomForbiddenMessage, policy =>
43+
44+
options.AddPolicy(SamplePolicyNames.CustomPolicyWithCustomForbiddenMessage, policy =>
4545
policy.AddRequirements(new SampleWithCustomMessageRequirement()));
4646
});
4747

0 commit comments

Comments
 (0)