关于这个问题的答案,我默认使用以下代码添加了对所有内容的授权:
public void ConfigureServices(IServiceCollection aServices)
{
aServices.AddMvc(options =>
{
var lBuilder = new AuthorizationPolicyBuilder().RequireAuthenticatedUser();
var lFilter = new AuthorizeFilter(lBuilder.Build());
options.Filters.Add(lFilter);
});
aServices.AddMvc();
}
public void Configure(IApplicationBuilder aApp, IHostingEnvironment aEnv, ILoggerFactory aLoggerFactory)
{
aApp.UseCookieAuthentication(options =>
{
options.AuthenticationScheme = "Cookies";
options.AutomaticAuthentication = true;
});
}
Run Code Online (Sandbox Code Playgroud)
但是,当有人试图访问未经授权的内容时,它会返回一个(看似默认的)重定向URL(http://foo.bar/Account/Login?ReturnUrl=%2Fapi%2Ffoobar%2F).
我希望它只返回HTTP 401,而不是重定向.
如何在ASP.NET 5中为WebAPI执行此操作?
我正在尝试创建这样的通用控制器:
[Route("api/[controller]")]
public class OrdersController<T> : Controller where T : IOrder
{
[HttpPost("{orderType}")]
public async Task<IActionResult> Create(
[FromBody] Order<T> order)
{
//....
}
}
Run Code Online (Sandbox Code Playgroud)
我打算使用{orderType} URI段变量来控制控制器的泛型类型.我正在尝试自定义IControllerFactory和IControllerActivator,但没有任何工作.每次我尝试发送请求时,都会收到404响应.我的自定义控制器工厂(和激活器)的代码永远不会执行.
显然问题是ASP.NET Core期望有效的控制器以后缀"Controller"结束,但我的通用控制器却具有(基于反射的)后缀"Controller`1".因此,它声明的基于属性的路线将被忽视.
在ASP.NET MVC中,至少在早期,它DefaultControllerFactory负责发现所有可用的控制器.它测试了"Controller"后缀:
MVC框架提供了一个默认的控制器工厂(恰当地命名为DefaultControllerFactory),它将搜索appdomain中的所有程序集,查找实现IController的所有类型,其名称以"Controller"结尾.
显然,在ASP.NET Core中,控制器工厂不再负有此责任.正如我之前所说,我的自定义控制器工厂为"普通"控制器执行,但从不为通用控制器调用.因此,在评估过程的早期还有其他一些东西可以控制控制器的发现.
有谁知道什么"服务"界面负责该发现?我不知道自定义界面或"钩子"点.
有没有人知道如何让ASP.NET Core"转储"它发现的所有控制器的名称?编写单元测试可以很好地验证我期望的任何自定义控制器发现确实有效.
顺便提一下,如果存在允许发现通用控制器名称的"钩子",则意味着还必须规范路由替换:
[Route("api/[controller]")]
public class OrdersController<T> : Controller { }
Run Code Online (Sandbox Code Playgroud)
无论给出什么值T,[controller]名称必须保持简单的基本通用名称.使用上面的代码作为示例,[controller]值将是"Orders".它不会是"Orders`1"或"OrdersOfSomething".
这个问题也可以通过显式声明封闭泛型类型来解决,而不是在运行时生成它们:
public class VanityOrdersController : OrdersController<Vanity> { }
public class ExistingOrdersController : OrdersController<Existing> { }
Run Code Online (Sandbox Code Playgroud)
上面的工作,但它产生我不喜欢的URI路径:
~/api/VanityOrders
~/api/ExistingOrders
Run Code Online (Sandbox Code Playgroud)
我真正想要的是这个:
~/api/Orders/Vanity
~/api/Orders/Existing
Run Code Online (Sandbox Code Playgroud)
另一个调整让我得到我正在寻找的URI:
[Route("api/Orders/Vanity", …Run Code Online (Sandbox Code Playgroud) 我已经实现了自己的自定义身份验证中间件和处理程序,并在应用启动时配置了它们.这一切都很好.
在我的自定义auth处理程序中,我已经覆盖了HandleAuthenticateAsync()以执行我自己的自定义身份验证,我还重写了HandleUnauthorizedAsync()以便将用户重定向到登录页面,但是这不会被调用.
浏览器在响应中收到401(未授权).我期待调用我的HandleUnauthorizedAsync().
我在这里没有正确理解管道吗?
谢谢