-
Notifications
You must be signed in to change notification settings - Fork 9.8k
/
AuthorizationEndpointConventionBuilderExtensions.cs
159 lines (138 loc) · 6.11 KB
/
AuthorizationEndpointConventionBuilderExtensions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Linq;
using Microsoft.AspNetCore.Authorization;
namespace Microsoft.AspNetCore.Builder;
/// <summary>
/// Authorization extension methods for <see cref="IEndpointConventionBuilder"/>.
/// </summary>
public static class AuthorizationEndpointConventionBuilderExtensions
{
private static readonly IAllowAnonymous _allowAnonymousMetadata = new AllowAnonymousAttribute();
/// <summary>
/// Adds the default authorization policy to the endpoint(s).
/// </summary>
/// <param name="builder">The endpoint convention builder.</param>
/// <returns>The original convention builder parameter.</returns>
public static TBuilder RequireAuthorization<TBuilder>(this TBuilder builder) where TBuilder : IEndpointConventionBuilder
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
return builder.RequireAuthorization(new AuthorizeAttribute());
}
/// <summary>
/// Adds authorization policies with the specified names to the endpoint(s).
/// </summary>
/// <param name="builder">The endpoint convention builder.</param>
/// <param name="policyNames">A collection of policy names. If empty, the default authorization policy will be used.</param>
/// <returns>The original convention builder parameter.</returns>
public static TBuilder RequireAuthorization<TBuilder>(this TBuilder builder, params string[] policyNames) where TBuilder : IEndpointConventionBuilder
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
ArgumentNullException.ThrowIfNull(policyNames);
return builder.RequireAuthorization(policyNames.Select(n => new AuthorizeAttribute(n)).ToArray());
}
/// <summary>
/// Adds authorization policies with the specified <see cref="IAuthorizeData"/> to the endpoint(s).
/// </summary>
/// <param name="builder">The endpoint convention builder.</param>
/// <param name="authorizeData">
/// A collection of <paramref name="authorizeData"/>. If empty, the default authorization policy will be used.
/// </param>
/// <returns>The original convention builder parameter.</returns>
public static TBuilder RequireAuthorization<TBuilder>(this TBuilder builder, params IAuthorizeData[] authorizeData)
where TBuilder : IEndpointConventionBuilder
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
ArgumentNullException.ThrowIfNull(authorizeData);
if (authorizeData.Length == 0)
{
authorizeData = new IAuthorizeData[] { new AuthorizeAttribute(), };
}
RequireAuthorizationCore(builder, authorizeData);
return builder;
}
/// <summary>
/// Adds an authorization policy to the endpoint(s).
/// </summary>
/// <param name="builder">The endpoint convention builder.</param>
/// <param name="policy">The <see cref="AuthorizationPolicy"/> policy.</param>
/// <returns>The original convention builder parameter.</returns>
public static TBuilder RequireAuthorization<TBuilder>(this TBuilder builder, AuthorizationPolicy policy)
where TBuilder : IEndpointConventionBuilder
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
ArgumentNullException.ThrowIfNull(policy);
RequirePolicyCore(builder, policy);
return builder;
}
/// <summary>
/// Adds an new authorization policy configured by a callback to the endpoint(s).
/// </summary>
/// <typeparam name="TBuilder"></typeparam>
/// <param name="builder">The endpoint convention builder.</param>
/// <param name="configurePolicy">The callback used to configure the policy.</param>
/// <returns>The original convention builder parameter.</returns>
public static TBuilder RequireAuthorization<TBuilder>(this TBuilder builder, Action<AuthorizationPolicyBuilder> configurePolicy)
where TBuilder : IEndpointConventionBuilder
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
ArgumentNullException.ThrowIfNull(configurePolicy);
var policyBuilder = new AuthorizationPolicyBuilder();
configurePolicy(policyBuilder);
RequirePolicyCore(builder, policyBuilder.Build());
return builder;
}
/// <summary>
/// Allows anonymous access to the endpoint by adding <see cref="AllowAnonymousAttribute" /> to the endpoint metadata. This will bypass
/// all authorization checks for the endpoint including the default authorization policy and fallback authorization policy.
/// </summary>
/// <param name="builder">The endpoint convention builder.</param>
/// <returns>The original convention builder parameter.</returns>
public static TBuilder AllowAnonymous<TBuilder>(this TBuilder builder) where TBuilder : IEndpointConventionBuilder
{
builder.Add(endpointBuilder =>
{
endpointBuilder.Metadata.Add(_allowAnonymousMetadata);
});
return builder;
}
private static void RequirePolicyCore<TBuilder>(TBuilder builder, AuthorizationPolicy policy)
where TBuilder : IEndpointConventionBuilder
{
builder.Add(endpointBuilder =>
{
// Only add an authorize attribute if there isn't one
if (!endpointBuilder.Metadata.Any(meta => meta is IAuthorizeData))
{
endpointBuilder.Metadata.Add(new AuthorizeAttribute());
}
endpointBuilder.Metadata.Add(policy);
});
}
private static void RequireAuthorizationCore<TBuilder>(TBuilder builder, IEnumerable<IAuthorizeData> authorizeData)
where TBuilder : IEndpointConventionBuilder
{
builder.Add(endpointBuilder =>
{
foreach (var data in authorizeData)
{
endpointBuilder.Metadata.Add(data);
}
});
}
}