简体   繁体   English

如何从 AuthorizationHandler .NET Core 获取参数

[英]How to get params from AuthorizationHandler .NET Core

I am using an authorization handler to put custom authorization in my controller in .net core.我正在使用授权处理程序将自定义授权放入 .net 核心的控制器中。 How can I get the parameters from the controller and use it to the authorization handler?如何从控制器获取参数并将其用于授权处理程序?

In the old .NET I can get the parameters from HttpContext request param like this:在旧的 .NET 中,我可以像这样从HttpContext请求参数中获取参数:

var eventId = filterContext.RequestContext.HttpContext.Request.Params["id"];

I am not sure how can I achieved it in .net core我不确定如何在 .net core 中实现它

public class HasAdminRoleFromAnySiteRequirement : AuthorizationHandler<HasAdminRoleFromAnySiteRequirement>, IAuthorizationRequirement
{
    public HasAdminRoleFromAnySiteRequirement()
    {

    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
        HasAdminRoleFromAnySiteRequirement requirement)
    {   

    //need to call get param from controller to used in the validation
    // something like this 
    //var eventId = filterContext.RequestContext.HttpContext.Request.Params["id"];
   // I tried the suggestion below but I can't get the parameter from routedata
   // var mvcContext = context.Resource as     Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext;            

        return Task.FromResult(0);
    }
}

In ASP.NET Core 3.0 with endpoint routing enabled, you can get a route parameter value like this:在启用端点路由的 ASP.NET Core 3.0 中,您可以获得如下所示的路由参数值:

public class MyRequirementHandler : AuthorizationHandler<MyRequirement>
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public MyRequirementHandler(IHttpContextAccessor httpContextAccessor)
    {
       _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
    }

    protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, MyRequirement requirement)
    {
        var routeData = _httpContextAccessor.HttpContext.GetRouteData();

        var areaName = routeData?.Values["area"]?.ToString();
        var area = string.IsNullOrWhiteSpace(areaName) ? string.Empty : areaName;

        var controllerName = routeData?.Values["controller"]?.ToString();
        var controller = string.IsNullOrWhiteSpace(controllerName) ? string.Empty : controllerName;

        var actionName = routeData?.Values["action"]?.ToString();
        var action = string.IsNullOrWhiteSpace(actionName) ? string.Empty : actionName;

        //...
    }
}

In your handler you can do the following在您的处理程序中,您可以执行以下操作

var mvcContext = context.Resource as 
    Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext;

if (mvcContext != null)
{
    // Examine MVC specific things like routing data.
}

If you want parameter values then the authorize attribute pieces run before binding has taking place.如果您想要参数值,那么授权属性片段会在绑定发生之前运行。 Instead you would move to an imperative call, inside your controller.相反,您将转到控制器内部的命令式调用。 This is basically resource based authorization , your parameter is a resource.这基本上是基于资源的授权,您的参数是一个资源。

You would inject the authorization service into your controller;您将授权服务注入您的控制器;

public class DocumentController : Controller
{
    IAuthorizationService _authorizationService;

    public DocumentController(IAuthorizationService authorizationService)
    {
        _authorizationService = authorizationService;
    }
}

Then write your handler slightly differently;然后稍微不同地编写您的处理程序;

public class DocumentAuthorizationHandler : AuthorizationHandler<MyRequirement, Document>
{
    public override Task HandleRequirementAsync(AuthorizationHandlerContext context,
                                                MyRequirement requirement,
                                                Document resource)
    {
        // Validate the requirement against the resource and identity.

        return Task.CompletedTask;
    }
}

You can see this handler takes a document, this can be whatever you like, be it an integer for an ID, or some type of view model.你可以看到这个处理程序接受一个文档,它可以是任何你喜欢的,可以是一个 ID 的整数,或者某种类型的视图模型。

Then you have access to it inside your HandleRequirementAsync() method.然后您可以在 HandleRequirementAsync() 方法中访问它。

Finally, you'd call it from within your controller, once binding has taken place;最后,一旦绑定发生,您将从控制器内部调用它;

if (await authorizationService.AuthorizeAsync(
    User, 
    document,     
    yourRequirement))
{
}

In ASP.NET Core 2.2, you can get a route parameter value like this:在 ASP.NET Core 2.2 中,您可以获得这样的路由参数值:

public class MyRequirementHandler : AuthorizationHandler<MyRequirement>
{
    protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, MyRequirement requirement)
    {
        var authContext = (AuthorizationFilterContext)context.Resource;
        var routeValueOfX = authContext.HttpContext.GetRouteValue("X");
        .
        .
        .
    }
}

For future reference, starting .NET Core 5.0, the HttpContext is now passed instead, so you can do:为了将来参考,从 .NET Core 5.0 开始,现在传递 HttpContext,因此您可以执行以下操作:

if (context.Resource is HttpContext httpContext)
{
   var value = httpContext.GetRouteValue("key");
}

You can access parameters directly from your handler pretty easily.您可以非常轻松地直接从处理程序访问参数。 Now, I'm sure if think works for earlier versions of core (you should update core anyway if you can), but in core 2.0 and beyond, you can cast the context.Resource to an AuthorizationFilterContext in the HandleRequirementAsync method like so现在,我确定 think 是否适用于早期版本的核心(如果可以的话,无论如何都应该更新核心),但是在核心 2.0 及更高版本中,您可以像这样在HandleRequirementAsync方法中将context.Resource转换为AuthorizationFilterContext

if(context.Resource is AuthorizationFilterContext mvcContext)
{
   //do stuff to the mvcContext
}

Then, you can access the parameters like this然后,您可以像这样访问参数

var value = mvcContext.HttpContext.Request.Query[key].FirstOrDefault();

where key is the parameter name you are looking for.其中key是您要查找的参数名称。

Or you could parse the query string like this或者你可以像这样解析查询字符串

var queryString = mvcContext.HttpContext.Request.QueryString.ToString()
var foo = HttpUtility.ParseQueryString(queryString);   
var value = foo[key] 

again, where key is the parameter name you are looking for.同样,其中key是您要查找的参数名称。

For .Net 5.0 (If you are using .NET 3.0, 3.1 then it will be better) use following:对于 .Net 5.0(如果您使用的是 .NET 3.0、3.1 那么它会更好)使用以下内容:

public class MyAuthorizationPolicyHandler : AuthorizationHandler<OperationAuthorizationRequirement>
{

    public MyAuthorizationPolicyHandler()
    {
    }

    protected async override Task HandleRequirementAsync(AuthorizationHandlerContext context, OperationAuthorizationRequirement requirement)
    {
        var result = false;

        if (context.Resource is Microsoft.AspNetCore.Http.DefaultHttpContext httpContext)
        {
            var endPoint = httpContext.GetEndpoint();
            if (endPoint != null)
            {
                var attributeClaims = endPoint.Metadata.OfType<MyAuthorizeAttribute>()
                //TODO: Add your logic here
            }

            if (result)
            {
                context.Succeed(requirement);
            }
        }
    }

Please refer to following related discussion: "context.Resource as AuthorizationFilterContext" returning null in ASP.NET Core 3.0请参考以下相关讨论: “context.Resource as AuthorizationFilterContext”return null in ASP.NET Core 3.0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在AuthorizationHandler中获取POST请求参数 - How get POST request params in AuthorizationHandler 如何将数据从 AuthorizationHandler 传递到 Asp.net 核心中的控制器 - How can pass data from AuthorizationHandler to Controller in Asp.net core .NET Core AuthorizationHandler 失败 - 如何路由到新页面 - .NET Core AuthorizationHandler fails - how to route to a new page ASP.NET 核心 AuthorizationHandler 未被调用 - ASP.NET Core AuthorizationHandler not being called 在.NET Core MVC中,如何在AuthorizationHandler中访问DbContext? - In .NET Core MVC, how do I access the DbContext while inside an AuthorizationHandler? 路由获取方法如何使用查询参数 .net core - How route get method with query params .net core 如何在 AuthorizationHandler 中获取 Controller 和 Action? - How to get Controller and Action inside AuthorizationHandler? 为什么在iframe中使用.net core 2 AuthorizationHandler时身份为null - Why is identity null when using .net core 2 AuthorizationHandler in iframe 从ASP.NET Core路由获取不确定数量的字符串参数 - Get indefinite amount of string params from ASP.NET Core route 如何将“查询参数”从 a.razor 页面传递到 ASP.NET 核心 Blazor 中的 .cshtml 页面 - How can I pass 'Query Params' from a .razor page to .cshtml page in ASP.NET Core Blazor
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM