Support AuthorizationPolicy and IAuthorizationRequirementData metadata everywhere#67765
Open
javiercn wants to merge 11 commits into
Open
Support AuthorizationPolicy and IAuthorizationRequirementData metadata everywhere#67765javiercn wants to merge 11 commits into
javiercn wants to merge 11 commits into
Conversation
…rement metadata everywhere
Adds a higher-level overload:
AuthorizationPolicy.CombineAsync(IAuthorizationPolicyProvider policyProvider, IEnumerable<object> metadata)
that inspects endpoint metadata and combines any IAuthorizeData, AuthorizationPolicy,
and IAuthorizationRequirementData instances into a single effective policy, mirroring the
logic previously only implemented in AuthorizationMiddleware.
Wires the new API into the sites that make the same authorization decision but previously
ignored AuthorizationPolicy / IAuthorizationRequirementData endpoint metadata:
- AuthorizationMiddleware now delegates to the new overload (removing duplicated logic).
- MVC AuthorizeFilter gathers full endpoint metadata instead of only IAuthorizeData.
- SignalR HubMethodDescriptor/DefaultHubDispatcher collect and evaluate all authorization
metadata (IAuthorizeData + IAuthorizationRequirementData) on hub methods.
- Blazor AuthorizeViewCore gains a virtual GetAuthorizeMetadata() extension point, and
AuthorizeRouteView honors requirement-data attributes on routed page types.
Adds tests for requirements-only metadata, combined requirements + authorization data, and
an attribute implementing both IAuthorizeData and IAuthorizationRequirementData, plus SignalR
and Blazor coverage.
Fixes #63365
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 58d6d84a-9144-44e2-9460-92c0841414c9
…ment data Blazor's AuthorizeViewCore now exposes a typed GetAuthorizationRequirementData() -> IAuthorizationRequirementData[]? extension point instead of an object[] method. The IAuthorizeData and IAuthorizationRequirementData sources are combined internally, de-duplicating attributes that implement both interfaces so they aren't processed twice. AuthorizationPolicy.CombineAsync no longer passes a nullable requirement-data list to its core; callers coalesce to an empty array, matching how authorizeData and policies are handled. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 58d6d84a-9144-44e2-9460-92c0841414c9
Cover the previously-untested paths from #63365: MVC AuthorizeFilter now honoring IAuthorizationRequirementData and AuthorizationPolicy endpoint metadata (with an allow/deny enforcement test), and a Blazor AuthorizeView allow/deny pair for requirement-data metadata. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a3d9633a-47ce-45fb-9db2-f366f11bc90f
Contributor
There was a problem hiding this comment.
Pull request overview
This PR centralizes authorization-policy computation so all callers (middleware, MVC filters, SignalR hub method dispatch, and Blazor components) honor the same endpoint authorization metadata types: IAuthorizeData, AuthorizationPolicy metadata instances, and IAuthorizationRequirementData.
Changes:
- Add
AuthorizationPolicy.CombineAsync(IAuthorizationPolicyProvider, IEnumerable<object> metadata)to compute an effective policy from mixed endpoint metadata. - Refactor authorization evaluation sites (middleware, MVC
AuthorizeFilter, SignalR hub dispatch, BlazorAuthorizeViewCore/AuthorizeRouteView) to use the shared combine logic. - Add/extend tests across Authorization, MVC, SignalR, and Components to cover
IAuthorizationRequirementDataand policy-instance metadata.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Security/Authorization/Core/src/AuthorizationPolicy.cs | Adds new CombineAsync overload that inspects endpoint metadata and merges requirements consistently. |
| src/Security/Authorization/Policy/src/AuthorizationMiddleware.cs | Replaces in-middleware metadata handling with the new shared CombineAsync(metadata) overload. |
| src/Security/Authorization/test/AuthorizationPolicyFacts.cs | Adds unit tests for new metadata-based policy combination behavior. |
| src/Security/Authorization/Core/src/PublicAPI/net11.0/PublicAPI.Unshipped.txt | Declares the new AuthorizationPolicy.CombineAsync(..., IEnumerable<object>) API for shipping. |
| src/Mvc/Mvc.Core/src/Authorization/AuthorizeFilter.cs | Updates endpoint-routing path to combine the full endpoint.Metadata instead of only IAuthorizeData. |
| src/Mvc/Mvc.Core/test/Authorization/AuthorizeFilterTest.cs | Adds MVC tests validating requirement-data and policy-instance endpoint metadata are enforced. |
| src/SignalR/server/Core/src/Internal/HubMethodDescriptor.cs | Stores full authorization metadata (not just IAuthorizeData) for hub methods. |
| src/SignalR/server/Core/src/Internal/DefaultHubDispatcher.cs | Discovers and evaluates hub authorization from combined metadata via shared CombineAsync. |
| src/SignalR/server/SignalR/test/.../Hubs.cs | Adds a test-only IAuthorizationRequirementData attribute requiring NameIdentifier claim. |
| src/SignalR/server/SignalR/test/.../HubConnectionHandlerTests.cs | Adds SignalR tests ensuring hub method requirement-data metadata is honored. |
| src/Components/Authorization/src/AuthorizeViewCore.cs | Adds virtual requirement-data hook and combines metadata for Blazor component authorization. |
| src/Components/Authorization/src/AuthorizeRouteView.cs | Flows requirement-data attributes from routed page types into authorization evaluation. |
| src/Components/Authorization/src/AttributeAuthorizeDataCache.cs | Extends attribute cache to track both IAuthorizeData and IAuthorizationRequirementData. |
| src/Components/Authorization/src/PublicAPI.Unshipped.txt | Declares new AuthorizeViewCore.GetAuthorizationRequirementData() API. |
| src/Components/Authorization/test/AuthorizeViewTest.cs | Adds Blazor tests validating requirement-data metadata is passed to authorization. |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
Fixes #63365.
Only the
AuthorizationMiddleware(endpoint routing) honored all three kinds of authorization endpoint metadata:IAuthorizeData(e.g.[Authorize])AuthorizationPolicyinstances used directly as metadata, relevant to routing onlyIAuthorizationRequirementData(e.g. a custom attribute carrying requirements)Other places that make the same authorization decision ignored those metadata types:
AuthorizeFilter(GetEffectivePolicyAsync)HubMethodDescriptor(previously gatheredPoliciesonly)AuthorizeViewCore/AuthorizeRouteView(didn't considerIAuthorizationRequirementData)The legacy non-endpoint-routing path (
EnableEndpointRouting=false+UseMvc) is a deliberately-frozen, opt-out code path untouched for ~7 years, so extending it isn't worth the risk.This PR adds a higher-level API that takes all the metadata associated with an endpoint and returns the effective policy, then routes the existing sites through it.
New API
The overload inspects each metadata item and combines any
IAuthorizeData,AuthorizationPolicy, andIAuthorizationRequirementDatainstances into a single effective policy. A single item (for example an attribute) that implements more than one of these interfaces contributes to each. The requirement-data handling that previously lived inAuthorizationMiddlewarenow lives in a shared code path so behavior is identical.Changes
AuthorizationMiddleware: refactor - replace the existing correct logic with the new shared method call.AuthorizeFilter: endpoint-routing now passes the wholeendpoint.Metadatainstead of justIAuthorizeData, so thatAuthorizationPolicyandIAuthorizationRequirementData` are honored.IAuthorizeData, now alsoIAuthorizationRequirementData, using the new API to combine them.Tests
CombineAsyncIAuthorizeData,IAuthorizationRequirementData,AuthorizationPolicyinstance, both-interfaces dedupAuthorizationPolicyFacts.csIAuthorizationRequirementDataHubConnectionHandlerTests.csAuthorizeFilter)IAuthorizationRequirementData,AuthorizationPolicyinstanceAuthorizeFilterTest.csAuthorizeView)IAuthorizationRequirementDataAuthorizeViewTest.cs