Hello,
I found problem when I converted app from .NET Core 2.2 into 3.0.
In 3.0 is context.Resource
not anymore of type AuthorizationFilterContext, but instead Microsoft.AspNetCore.Routing.RouteEndpoint. Is there anything I'm missing (some changes in configuration or some other place)?
If did really changed, is there any way to redirect from handlers?
Any help is greatly appreciated.
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
T requirement)
{
var resource = context.Resource; // 2.2 - AuthorizationFilterContext
// 3.0 - RouteEndpoint
if (context.Resource is AuthorizationFilterContext mvcContext) // in 3.0 results in null
{
}
}
Thank you
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.
This is the solution: https://github.com/aspnet/AspNetCore/issues/11075
Not exactly, because I need to set RedirectToActionResult to redirect from this handler into specified action. Like
if (context.Resource is AuthorizationFilterContext mvcContext)
{
mvcContext.Result = new RedirectToActionResult("Action", "Controller", null);
}
context.Resource used to provide access to HttpContext so that you could enforce restrictions based on various aspects of the Request, etc... for example: https://www.khalidabuhakmeh.com/asp-net-core-resource-authorization-with-authorizationhandler. How can this be done in ASP.NET Core 3?
@sbwalker your link is broken
@HaoK should this go in the 2.2 to 3.0 migration guide?
Sorry.. the link was working when I posted it. I found the answer to my question - you now need to access HttpContext through HttpContextAccessor:
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
{
var ctx = HttpContextAccessor.HttpContext;
if (ctx != null && ctx.Request.Query.ContainsKey("entityid"))
{
int EntityId = int.Parse(ctx.Request.Query["entityid"]);
if (UserPermissions.IsAuthorized(context.User, requirement.EntityName, EntityId, requirement.PermissionName))
{
context.Succeed(requirement);
}
}
return Task.CompletedTask;
}
This is a sideeffect of the endpoint routing changes, so maybe it should go with whatever docs are related to that change?
Neither https://github.com/aspnet/AspNetCore/issues/11075 nor @sbwalker's solutions look to work in my case: I need to resolve a service (via HttpContext.RequestServices
previously) in a AuthorizationPolicyBuilder.RequireAssertion
.
All I have in the assertion is an AuthorizationHandlerContext
. I'm in a static extension method.
How can I do this?
Additionally, this page still says , "For example, MVC passes an instance of AuthorizationFilterContext in the Resource property".
I need to access RequestServices
from within my RequireAssertion
delegate - how can I please?
You can try injecting IHttpContextAccessor
into your handler if you can't get access to the http context via the resource being passed in (which is not usually the case)
@HaoK inject it into what, please? I'm using RequireAssertion
from a static extension method.
"can't get access to the http context via the resource being passed in"... everything referenced here indicates that the resourced passed in is now always an Endpoint
, could I ask what you mean by "not usually the case". Do you say that because most people are using pre-3.0? I'm on 3.0.0.
Require assertion isn't meant for this scenario, you should implement a real handler if you want to access request specific things
“Real handler”...? Am not good at guessing here..
https://docs.microsoft.com/en-us/aspnet/core/security/authorization/dependencyinjection?view=aspnetcore-3.0 is a good example of how you implement a handler that can use things from DI, that would be how you can use context accessor
Thank you, that's solved my use case. FWIW I think the documentation may still have an issue here, where it says AuthorizationFilterContext is passed in - but I'm good to go.
@kierenj can you suggest an edit?
I can - although I've had the same suggestion in a few places, I'm curious about the policy with this. Typically, I'm asking something coming from a position of ignorance on the relevant area of the library/product. Some answer becomes a little clear, then someone suggests I suggest an edit.
My first thought is that in instances like that I might be close to the worst person to edit official documentation: I'm at one step up the ladder from being completely stumped by some issue. Isn't that dangerous - in this scenario and the others, I don't know what I don't know?
I've had a look into this to see what we can do in 3.0.
I found that the following code inside of an IAuthorizationHandler.HandleAsync
implementation allows for getting hold of a ControllerActionDescriptor
, which contains info about the controller, action, filters, etc:
if (context.Resource is Endpoint endpoint)
{
var controllerActionDescriptor = endpoint.Metadata
.GetMetadata<ControllerActionDescriptor>();
if (controllerActionDescriptor != null)
{
// ...
}
}
It's also possible to get the route values for controller
, action
, et al from the HttpContext
(using IHttpContextAccessor
as already noted), so I'm not sure whether it's overly beneficial to grab the ControllerActionDescriptor
like this.
@Rick-Anderson I dunno if this approach would actually be recommended by the engineering team, or if maybe it _is_ a recommended approach for those that want to deal with MVC concepts in the handlers. Can we run it by someone on the engineering team? I guess Hao might still be subscribed to this issue...
EDIT: Updated to show a cleaner approach to getting metadata.
@HaoK can you review the preceding suggestion?
Yeah its a better approach to access things via the endpoint metadata as opposed using IHttpContextAccessor
, which should typically only used as a last resort
@Rick-Anderson can you clarify what you need from the PU here? Do you need us to write up the changes or just confirm that the approach @serpent5 described is appropriate?
just confirm that the approach @serpent5 described is appropriate?
Yes
Do you need us to write up the changes
If anything needs to be added, let us know.
https://github.com/aspnet/AspNetCore.Docs/pull/15218#issuecomment-546100456 summarises the specifics.
@serpent5 let me know if this should be reopened in the master issue https://github.com/aspnet/AspNetCore.Docs/issues/16191
Most helpful comment
context.Resource used to provide access to HttpContext so that you could enforce restrictions based on various aspects of the Request, etc... for example: https://www.khalidabuhakmeh.com/asp-net-core-resource-authorization-with-authorizationhandler. How can this be done in ASP.NET Core 3?