-
Notifications
You must be signed in to change notification settings - Fork 241
Jennyf/scopes roles #1742
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Jennyf/scopes roles #1742
Changes from 3 commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
src/Microsoft.Identity.Web/Policy/IAuthRequiredScopeOrAppPermissionMetadata.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. | ||
|
|
||
| using System.Collections.Generic; | ||
|
|
||
| namespace Microsoft.Identity.Web | ||
| { | ||
| /// <summary> | ||
| /// This is the metadata that describes required auth scopes or app permissions for a given endpoint | ||
| /// in a web API. It's the underlying data structure the requirement <see cref="ScopeAuthorizationRequirement"/> will look for | ||
| /// in order to validate scopes in the scope claims. | ||
jennyf19 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| /// </summary> | ||
| public interface IAuthRequiredScopeOrAppPermissionMetadata | ||
| { | ||
| /// <summary> | ||
| /// App permissions accepted by this web API. | ||
| /// App permissions appear in the roles claim of the token. | ||
| /// </summary> | ||
| string[]? AcceptedAppPermission { get; } | ||
|
|
||
| /// <summary> | ||
| /// Fully qualified name of the configuration key containing the required scopes | ||
jennyf19 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| /// or app permissions (separated by spaces). | ||
jennyf19 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| /// </summary> | ||
| string? RequiredAppPermissionsConfigurationKey { get; } | ||
|
|
||
| /// <summary> | ||
| /// Scopes accepted by this web API. | ||
| /// </summary> | ||
| string[]? AcceptedScope { get; } | ||
|
|
||
| /// <summary> | ||
| /// Fully qualified name of the configuration key containing the required scopes (separated | ||
| /// by spaces). | ||
| /// </summary> | ||
| string? RequiredScopesConfigurationKey { get; } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
src/Microsoft.Identity.Web/Policy/RequireScopeOrAppPermissionOptions.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. | ||
|
|
||
| using System; | ||
| using Microsoft.AspNetCore.Authorization; | ||
| using Microsoft.Extensions.Options; | ||
|
|
||
| namespace Microsoft.Identity.Web | ||
| { | ||
| /// <summary> | ||
| /// RequireScopeOrAppPermissionOptions. | ||
| /// </summary> | ||
| internal class RequireScopeOrAppPermissionOptions : IPostConfigureOptions<AuthorizationOptions> | ||
| { | ||
| private readonly AuthorizationPolicy _defaultPolicy; | ||
|
|
||
| /// <summary> | ||
| /// Sets the default policy. | ||
| /// </summary> | ||
| public RequireScopeOrAppPermissionOptions() | ||
| { | ||
| _defaultPolicy = new AuthorizationPolicyBuilder() | ||
| .AddRequirements(new ScopeOrAppPermissionAuthorizationRequirement()) | ||
| .Build(); | ||
| } | ||
|
|
||
| /// <inheritdoc/> | ||
| public void PostConfigure( | ||
| string name, | ||
| AuthorizationOptions options) | ||
| { | ||
| if (options == null) | ||
| { | ||
| throw new ArgumentNullException(nameof(options)); | ||
| } | ||
|
|
||
| options.DefaultPolicy = options.DefaultPolicy is null | ||
| ? _defaultPolicy | ||
| : AuthorizationPolicy.Combine(options.DefaultPolicy, _defaultPolicy); | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
106 changes: 106 additions & 0 deletions
106
src/Microsoft.Identity.Web/Policy/RequiredScopeOrAppPermissionAttribute.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. | ||
|
|
||
| using System; | ||
| using System.Collections.Generic; | ||
|
|
||
| namespace Microsoft.Identity.Web.Resource | ||
| { | ||
| /// <summary> | ||
| /// This attribute is used on a controller, pages, or controller actions | ||
| /// to declare (and validate) the scopes or app permissions required by a web API. | ||
| /// These scopes or app permissions can be declared in two ways: | ||
| /// hardcoding them, or declaring them in the configuration. Depending on your | ||
| /// choice, use either one or the other of the constructors. | ||
| /// For details, see https://aka.ms/ms-id-web/required-scope-or-app-permissions-attribute. | ||
| /// </summary> | ||
| [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] | ||
| public class RequiredScopeOrAppPermissionAttribute : Attribute, IAuthRequiredScopeOrAppPermissionMetadata | ||
| { | ||
| /// <summary> | ||
| /// Scopes accepted by this web API. | ||
| /// </summary> | ||
| public string[]? AcceptedScope { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Fully qualified name of the configuration key containing the required scopes (separated | ||
| /// by spaces). | ||
| /// </summary> | ||
| /// <example> | ||
| /// If the appsettings.json file contains a section named "AzureAd", in which | ||
| /// a property named "Scopes" contains the required scopes, the attribute on the | ||
| /// controller/page/action to protect should be set to the following: | ||
| /// <code> | ||
| /// [RequiredScope(RequiredScopesConfigurationKey="AzureAd:Scopes")] | ||
jennyf19 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| /// </code> | ||
| /// </example> | ||
| public string? RequiredScopesConfigurationKey { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Unused: Compatibility of interface with the Authorization Filter. | ||
| /// </summary> | ||
| public bool IsReusable { get; set; } | ||
jennyf19 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| /// <summary> | ||
| /// App permissions accepted by this web API. | ||
| /// App permissions appear in the roles claim of the token. | ||
| /// </summary> | ||
| public string[]? AcceptedAppPermission { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Fully qualified name of the configuration key containing the required app permissions (separated | ||
| /// by spaces). | ||
| /// </summary> | ||
| /// <example> | ||
| /// If the appsettings.json file contains a section named "AzureAd", in which | ||
| /// a property named "AppPermissions" contains the required app permissions, the attribute on the | ||
| /// controller/page/action to protect should be set to the following: | ||
| /// <code> | ||
| /// [RequiredScopeOrAppPermission(RequiredAppPermissionsConfigurationKey="AzureAd:AppPermissions")] | ||
| /// </code> | ||
| /// </example> | ||
| public string? RequiredAppPermissionsConfigurationKey { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Verifies that the web API is called with the right app permissions. | ||
| /// If the token obtained for this API is on behalf of the authenticated user does not have | ||
| /// any of these <paramref name="acceptedScopes"/> in its scope claim, | ||
| /// nor <paramref name="acceptedAppPermissions"/> in its roles claim, the | ||
| /// method updates the HTTP response providing a status code 403 (Forbidden) | ||
| /// and writes to the response body a message telling which scopes are expected in the token. | ||
| /// </summary> | ||
| /// <param name="acceptedScopes">Scopes accepted by this web API.</param> | ||
| /// <param name="acceptedAppPermissions">App permissions accepted by this web API.</param> | ||
| /// <remarks>When neither the scopes nor app permissions match, the response is a 403 (Forbidden), | ||
| /// because the user is authenticated (hence not 401), but not authorized.</remarks> | ||
| /// <example> | ||
| /// Add the following attribute on the controller/page/action to protect: | ||
| /// | ||
| /// <code> | ||
| /// [RequiredScopeOrAppPermissionAttribute(new string[] { "access_as_user" }, new string[] { "access_as_app" })] | ||
jennyf19 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| /// </code> | ||
| /// </example> | ||
| /// <seealso cref="M:RequiredScopeOrAppPermissionAttribute()"/> and <see cref="RequiredAppPermissionsConfigurationKey"/> | ||
| /// if you want to express the required scopes or app permissions from the configuration. | ||
| public RequiredScopeOrAppPermissionAttribute(string[] acceptedScopes, string[] acceptedAppPermissions) | ||
| { | ||
| AcceptedScope = acceptedScopes ?? throw new ArgumentNullException(nameof(acceptedScopes)); | ||
| AcceptedAppPermission = acceptedAppPermissions ?? throw new ArgumentNullException(nameof(acceptedAppPermissions)); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Default constructor. | ||
| /// </summary> | ||
| /// <example> | ||
| /// <code> | ||
| /// [RequiredScopeOrAppPermission(RequiredScopesConfigurationKey="AzureAD:Scope", RequiredAppPermissionsConfigurationKey="AzureAD:AppPermission")] | ||
| /// class Controller : BaseController | ||
| /// { | ||
| /// } | ||
| /// </code> | ||
| /// </example> | ||
| public RequiredScopeOrAppPermissionAttribute() | ||
| { | ||
| } | ||
| } | ||
| } | ||
65 changes: 65 additions & 0 deletions
65
src/Microsoft.Identity.Web/Policy/RequiredScopeOrAppPermissionExtensions.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. | ||
|
|
||
| using System; | ||
| using System.Collections.Generic; | ||
| using Microsoft.AspNetCore.Authorization; | ||
| using Microsoft.AspNetCore.Builder; | ||
| using Microsoft.Extensions.DependencyInjection; | ||
| using Microsoft.Extensions.DependencyInjection.Extensions; | ||
| using Microsoft.Extensions.Options; | ||
|
|
||
| namespace Microsoft.Identity.Web | ||
| { | ||
| /// <summary> | ||
| /// Extensions for building the required scope or app permission attribute during application startup. | ||
| /// </summary> | ||
| public static class RequiredScopeOrAppPermissionExtensions | ||
| { | ||
| /// <summary> | ||
| /// This method adds support for the required scope or app permission attribute. It adds a default policy that | ||
| /// adds a scope requirement or app permission requirement. | ||
| /// This requirement looks for IAuthRequiredScopeOrAppPermissionMetadata on the current endpoint. | ||
| /// </summary> | ||
| /// <param name="services">The services being configured.</param> | ||
| /// <returns>Services.</returns> | ||
| public static IServiceCollection AddRequiredScopeOrAppPermissionAuthorization(this IServiceCollection services) | ||
| { | ||
| services.AddAuthorization(); | ||
|
|
||
| services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<AuthorizationOptions>, RequireScopeOrAppPermissionOptions>()); | ||
| services.TryAddEnumerable(ServiceDescriptor.Singleton<IAuthorizationHandler, ScopeOrAppPermissionAuthorizationHandler>()); | ||
| return services; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// This method adds metadata to route endpoint to describe required scopes or app permissions. It's the imperative version of | ||
| /// the [RequiredScopeOrAppPermission] attribute. | ||
| /// </summary> | ||
| /// <typeparam name="TBuilder">Class implementing <see cref="IEndpointConventionBuilder"/>.</typeparam> | ||
| /// <param name="endpointConventionBuilder">To customize the endpoints.</param> | ||
| /// <param name="scope">Scope.</param> | ||
| /// <param name="appPermission">App permission.</param> | ||
| /// <returns>Builder.</returns> | ||
| public static TBuilder RequireScope<TBuilder>(this TBuilder endpointConventionBuilder, string[] scope, string[] appPermission) | ||
jennyf19 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| where TBuilder : IEndpointConventionBuilder | ||
| { | ||
| return endpointConventionBuilder.WithMetadata(new RequiredScopeOrAppPermissionMetadata(scope, appPermission)); | ||
| } | ||
|
|
||
| private sealed class RequiredScopeOrAppPermissionMetadata : IAuthRequiredScopeMetadata | ||
| { | ||
| public RequiredScopeOrAppPermissionMetadata(string[] scope, string[] appPermission) | ||
| { | ||
| AcceptedScope = scope; | ||
| AcceptedAppPermission = appPermission; | ||
| } | ||
|
|
||
| public string[]? AcceptedScope { get; } | ||
| public string[]? AcceptedAppPermission { get; } | ||
|
|
||
| public string? RequiredScopesConfigurationKey { get; } | ||
| public string? RequiredAppPermissionsConfigurationKey { get; } | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.