.net 为什么我的授权筛选器不起作用?

n6lpvg4x  于 2023-03-31  发布在  .NET
关注(0)|答案(1)|浏览(138)

我尝试在.net core中使用IAuthorizationFilter创建一个自定义身份验证方法。我遵循了一些说明,因此最终得到了以下代码:

public class JwtCookieAuthenticate : AuthorizeAttribute, IAuthorizationFilter
    {
        public JwtCookieAuthenticate()
        {
            Console.WriteLine("CookieAuthorizeAttribute created."); //purely for debugging purposes
        }
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            var testCookieValue = context.HttpContext.Request.Cookies["test"];
            Console.WriteLine($"test cookie value: {testCookieValue}");
            if (!context.HttpContext.Request.Cookies.ContainsKey("test") || context.HttpContext.Request.Cookies["test"] != "yes")
            {
                context.Result = new RedirectToActionResult("Login", "df", null);
            }
        }
    }

这段代码的基本功能是检查名为“test”的cookie;如果它存在并且具有值yes,则允许用户通过。但是,如果它不满足这些条件,则重定向用户。我面临的问题是没有调用OnAuthorization方法
我在我的Startup.cs代码中引用它作为身份验证的方法,如下所示:

public void ConfigureServices(IServiceCollection services)
        {
            services.AddAuthorization(options =>
            {
                options.DefaultPolicy = new AuthorizationPolicyBuilder()
                    .RequireAuthenticatedUser()
                    .Build();
            });
            services.AddMvc(options =>
            {
                options.Filters.Add(new JwtCookieAuthenticate());
            });
            services.AddControllers();
            services.AddRazorPages();
        }
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if(env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();
            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
                endpoints.MapRazorPages();
            });
        }

我把它作为一个控制器级别的标签添加到我的HomeController中,如下所示:

[JwtCookieAuthenticate]
    public class HomeController : Controller

但是,OnAuthorizationMethod没有被调用,所以对于我哪里出错,如何改进我的代码或如何修复这个问题,有什么建议吗?

bhmjp9jg

bhmjp9jg1#

首先,你需要从AttributeIAuthorizationFilter继承:

public class JwtCookieAuthenticate : Attribute, IAuthorizationFilter

然后,在你进入端点之前,过滤器总是会被命中,所以你需要在过滤器中从你的重定向逻辑中排除Login操作:

public void OnAuthorization(AuthorizationFilterContext context)
{
    if (context.HttpContext.Request.Path.Value == "The url for your Login action")
        return;
    var testCookieValue = context.HttpContext.Request.Cookies["test"];
    Console.WriteLine($"test cookie value: {testCookieValue}");
    if (!context.HttpContext.Request.Cookies.ContainsKey("test") || context.HttpContext.Request.Cookies["test"] != "yes")
    {
        context.Result = new RedirectToActionResult("Login", "df", null);
    }
}

顺便说一句,你使用的是API控制器模板(services.AddControllers();endpoints.MapControllers();),请确保你的控制器包含[Route]属性。否则,路由中间件找不到路由并产生异常:
无效操作异常:没有与提供的值匹配的路由。
1.如果使用API路由模板,需要定义如下属性:

[Route("api/[action]")]   //define this 
public class dfController:Controller
{
    //url should be: 'api/Login'
    public IActionResult Login()
    {
        //...
    }

}

2.如果你使用MVC路由模板,不需要定义[Route]属性,只需要使用下面的模板,它会找到控制器和动作:

services.AddControllersWithViews();
//....
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
    endpoints.MapRazorPages();
});

那么控制器应该是:

public class dfController:Controller
{
    //url should be: 'df/Login'
    public IActionResult Login()
    {
        return View();
    }

}

相关问题