Wel*_*ing 2 authorization middleware asp.net-core-3.0
在ASP.Net Core 3.0 Preview 7中,我尝试编写一些代码,如下所示:
public void Configure(IApplicationBuilder app) {
app.MapWhen(context =>
context.Request.Path.StartsWithSegments(
new PathString("/UnsecureLog")),
a => {
a.UseRouting();
a.UseEndpoints(endpoints => {
endpoints.MapControllers();
});
}
);
app.UseAuthentication();
app.UseAuthorization();
app.MapWhen(context =>
context.Request.Path.StartsWithSegments(
new PathString("/SecureLog")),
a => {
a.UseRouting();
a.UseEndpoints(endpoints => {
endpoints.MapControllers()
.RequireAuthorization("MustBeReader");
});
}
);
}
Run Code Online (Sandbox Code Playgroud)
我的目标是允许无需身份验证即可在中间件中处理某些控制器,而我的想法是MapWhen()是实现这一目标的方法。
相反,我在到达/UnsecureLog端点时看到此错误:
System.InvalidOperationException: Endpoint ... contains authorization metadata,
but a middleware was not found that supports authorization.
Configure your application startup by adding app.UseAuthorization()
inside the call to Configure(..) in the application startup code.
Run Code Online (Sandbox Code Playgroud)
翻译:“您打算如何为不想保护的端点实施安全功能”。
我的收获是,RequireAuthorization("MustBeReader")在任何 MapWhen()块处理控制器逻辑中的所有调用实际上都将应用于所有 MVC控制器路由。
我当前的解决方法是删除.RequireAuthorization("MustBeReader")第二个MapWhen()代码块中的调用,并将其作为属性([RequireAuthorization("MustBeReader")])重新应用到我希望保护的那些端点。这没有错误,并且产生了所需的行为。
但是那不是目标,不是吗?
我宁愿使用相似的策略来管理整个控制器组,而完全不让其他人使用安全性,并在Configure()中处理所有这些问题。相反,我必须零碎地对每个控制器应用所需的授权要求。
我希望有一种更好的方法来实现路由,从而避免出现此处提到的问题。也许我做错了什么。
有什么想法吗?
小智 5
将下面的代码在Startup类中(在上方app.MapWhen)上移。
app.UseAuthentication();
app.UseAuthorization();
Run Code Online (Sandbox Code Playgroud)
需要注意的是,app.UseAuthorization必须出现在app.UseRouting()和之间app.UseEndpoints(...);
所以,它应该是这样的:
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
});
Run Code Online (Sandbox Code Playgroud)
我相信自己的完整答案,今天花了一些时间在这个问题上并发布了代码。感谢姆威尔森鼓励我再试一次。
在我的新方法之前,每次运行代码时,都会显示此警告......
Startup.cs(189,13): warning ASP0001: The call to UseAuthorization
should appear between app.UseRouting() and app.UseEndpoints(..)
for authorization to be correctly evaluated.
Run Code Online (Sandbox Code Playgroud)
因此,解决方案不仅是认识到该警告并予以注意,而且还要找到一种安抚编译器诸神的方法。(你会在下面看到我仍然不知道如何做到这一点。)
这就是我今天所弄清楚的。我将UseAuthentication和UseAuthorization调用放在两个不同的地方。这有效。有些。
在这个 API 项目中,我现在可以运行匿名的不安全端点、安全端点,并且还可以运行安全的 GraphQL 端点(为了奖励积分)。
FWIW,代码如下:
public void Configure(...)
{
...
...
app.UseStaticFiles();
app.UseRouting();
app.MapWhen(
context => (context.Request.Path
.StartsWithSegments(new PathString("/api"))
),
a =>
{
a.UseRouting();
a.UseAuthentication();
a.UseAuthorization();
a.UseEndpoints(endpoints =>
{
endpoints
.MapControllers()
.RequireAuthorization(...);
});
}
);
app.UseAuthentication();
app.UseAuthorization();
app.UseWebSockets();
app.UseGraphQLWebSockets<...>(...);
app.UseGraphQL<...>(...);
}
Run Code Online (Sandbox Code Playgroud)
这可行,但我仍然收到编译器警告。更重要的是,如果我变得太聪明并尝试使用以下控制器......
[Route("vapi/[controller]")]
//[AllowAnonymous]
public class VersionController : Controller
{ ...
Run Code Online (Sandbox Code Playgroud)
连同这个额外的 Startup.cs 代码......
app.MapWhen(
context => (context.Request.Path
.StartsWithSegments(new PathString("/vapi"))
),
a =>
{
a.UseRouting();
// a.UseAuthentication(); <-- look, Ma, no authentication!
// a.UseAuthorization(); <-- look, Ma, no authorization!
a.UseEndpoints(endpoints =>
{
endpoints
.MapControllers()
.RequireAuthorization(...);
});
}
);
Run Code Online (Sandbox Code Playgroud)
我仍然收到我的 OP 中指出的错误。(这一切又回到了我的脑海,就像一场古老的噩梦......)
Endpoint ....Controllers.VersionController.Version (...) contains authorization
metadata, but a middleware was not found that supports authorization.
Configure your application startup by adding app.UseAuthorization() ...
Run Code Online (Sandbox Code Playgroud)
所以我要留下的问题是:我仍然无法做我想做的事,即仅保护某些控制器路径。我能做的(不添加“vapi”路径支持代码到启动)是这样的:
[Route("api/[controller]")]
[AllowAnonymous]
public class VersionController : Controller
{ ...
Run Code Online (Sandbox Code Playgroud)
所以......我将称之为答案,直到有人发布一组可用的代码来改进它。
| 归档时间: |
|
| 查看次数: |
1662 次 |
| 最近记录: |