自定义身份验证中间件 - 如何检查请求是匿名还是授权?

Moj*_*oDK 6 c# asp.net-mvc asp.net-core

我正在尝试编写自己的身份验证中间件代码。

在老式的 HttpModule 中,当请求“授权”页面时,我可以使用“OnAuthenticateRequest”。

我的中间件代码是这样的:

public async Task Invoke(HttpContext context)
{
    if (!context.User.Identity.IsAuthenticated)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

...但这也会检查具有 [AllowAnonymous] 属性的请求的 IsAuthenticated。

如何从我的中间件检查请求是否具有属性 [AllowAnonymous] 或 [Authorize]?

我需要能够做一些类似的事情...

public async Task Invoke(HttpContext context)
{
    if (HasAuthorizeAttribute && !context.User.Identity.IsAuthenticated)
    {
    }
    await _next.Invoke(context);
}
Run Code Online (Sandbox Code Playgroud)

谢谢。

ham*_*ose 15

有一种方法可以从中间件内部检查请求是否针对标记为[匿名]的页面。

//inside your middleware
var endpoint = context.GetEndpoint();
if (endpoint?.Metadata?.GetMetadata<IAllowAnonymous>() is object)
{
    await _next(context);
    return;
}
Run Code Online (Sandbox Code Playgroud)

在此博客上找到的原始解决方案:Anonymous Aware Middleware

  • 在 Net 6.0 中,您可以使用 (context.GetEndpoint()?.Metadata?.GetMetadata&lt;AuthorizeAttribute&gt;() is object) 检查 [Authorize] (3认同)
  • 当将此属性与“[AllowAnonymous]”属性结合使用时,“endpoint?.Metadata?.GetMetadata&lt;IAllowAnonymous&gt;()”仍然始终为空。这在 .NET Core 5.x 中仍然有效吗? (2认同)
  • 实际上我们可以在.NET 6中使用`endpoint?.Metadata?.GetMetadata&lt;IAllowAnonymous&gt;()`,因为我们确保在启动时`app.UseRouting();`在`app.UseMiddleware&lt;MyMiddleware&gt;( );`。 (2认同)

Tân*_*Tân -5

如果我理解你的意思是正确的,你正在寻找这样的东西:你想对控制器中的某些操作进行分类,某些操作可以在授权后执行,等等。

在这种情况下,您可以在该操作之上设置[Authorize]和:[AllowAnonymous]

public class HomeController : Controller
{
    [AllowAnonymous]
    public async Task Invoke(HttpContext context)
    {
        // all of codes here can be executed with unauthorized request(s).
        // code goes here...
    }

    [Authorized]
    public async Task Invoke_2(HttpContext context)
    {
        // all of codes here can be executed WHEN the request is authorized
        // code goes here...
    }
}
Run Code Online (Sandbox Code Playgroud)

而且,如果您想授权所有将到达控制器的请求,您可以[Authorize]在控制器名称顶部设置该属性:

[Authorize]
public class HomeController : Controller
{
    // this attribute is still required when you allow anonymous request(s)
    [AllowAnonymous]
    public async Task Invoke(HttpContext context)
    {
        // all of codes here can be executed with unauthorized request(s).
        // code goes here...
    }

    // you can remove [Authorize] attribute from this action, because
    // it's authorized by default
    public async Task Invoke_2(HttpContext context)
    {
        // all of codes here can be executed WHEN the request is authorized
        // code goes here...
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:由于您正在使用Task,因此最好将操作命名为以 结尾Async,例如:InvokeAsyncInvoke_2Async