如何从 ASP.NET Core 2.0 中的自定义中间件请求身份验证
How to request authentication from custom middleware in ASP.NET Core 2.0
我有两个自定义 ASP.NET 核心中间件:一个用于身份验证(注册自己的身份验证方案),另一个用于某些业务工作。
如何在另一个中间件中使用认证中间件?我可以像这样在 MVC 中轻松使用身份验证:
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
});
我也可以提供我自己的 AuthenticationSchemeProvider
以根据请求 URL 使用不同的身份验证方案。但是身份验证中间件只有 运行 用于 MVC 控制器。我希望它在我的自定义中间件 运行 之前 运行。可以吗?
在自定义中间件方法中 Invoke()
如果用户未通过身份验证则调用 ChallengeAsync()
:
public async Task Invoke(HttpContext httpContext, IServiceProvider serviceProvider)
{
if (!httpContext.User.Identity.IsAuthenticated)
{
await httpContext.ChallengeAsync();
}
else { /* logic here */ }
}
必须添加 NuGet 包 Microsoft.AspNetCore.Authentication.Abstractions
。
以上代码将运行默认的认证服务来认证用户。如果默认的是你自定义的认证中间件,那么就会调用它。
这是基于 Rython
对 使用 Windows 身份验证 的具体情况的回答,但也允许设计的控制器使用其他类型的身份验证:
/// <summary>
/// checks if current request resource can be accesses without being Windows-authenticated
/// </summary>
/// <param name="context">http context</param>
/// <returns>true if non-Windows is allowed. Otherwise, false</returns>
public static bool IsAllowedWithoutWindowsAuth(HttpContext context)
{
bool isAllowedWithoutWindowsAuth = context.Request.Method == "OPTIONS" ||
AllowedControllers.Any(c =>
{
string path = context.Request.Path.ToString();
return path.StartsWith(c, StringComparison.InvariantCulture);
});
return isAllowedWithoutWindowsAuth;
}
// custom middleware code
public async Task Invoke(HttpContext context)
{
// anonymous path, skipping
if (IsAllowedWithoutWindowsAuth(context))
{
await _next(context);
return;
}
if (!context.User.Identity.IsAuthenticated)
{
await context.ChallengeAsync("Windows");
return;
}
// other code here
await _next(context);
}
我有两个自定义 ASP.NET 核心中间件:一个用于身份验证(注册自己的身份验证方案),另一个用于某些业务工作。
如何在另一个中间件中使用认证中间件?我可以像这样在 MVC 中轻松使用身份验证:
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
});
我也可以提供我自己的 AuthenticationSchemeProvider
以根据请求 URL 使用不同的身份验证方案。但是身份验证中间件只有 运行 用于 MVC 控制器。我希望它在我的自定义中间件 运行 之前 运行。可以吗?
在自定义中间件方法中 Invoke()
如果用户未通过身份验证则调用 ChallengeAsync()
:
public async Task Invoke(HttpContext httpContext, IServiceProvider serviceProvider)
{
if (!httpContext.User.Identity.IsAuthenticated)
{
await httpContext.ChallengeAsync();
}
else { /* logic here */ }
}
必须添加 NuGet 包 Microsoft.AspNetCore.Authentication.Abstractions
。
以上代码将运行默认的认证服务来认证用户。如果默认的是你自定义的认证中间件,那么就会调用它。
这是基于 Rython
对 使用 Windows 身份验证 的具体情况的回答,但也允许设计的控制器使用其他类型的身份验证:
/// <summary>
/// checks if current request resource can be accesses without being Windows-authenticated
/// </summary>
/// <param name="context">http context</param>
/// <returns>true if non-Windows is allowed. Otherwise, false</returns>
public static bool IsAllowedWithoutWindowsAuth(HttpContext context)
{
bool isAllowedWithoutWindowsAuth = context.Request.Method == "OPTIONS" ||
AllowedControllers.Any(c =>
{
string path = context.Request.Path.ToString();
return path.StartsWith(c, StringComparison.InvariantCulture);
});
return isAllowedWithoutWindowsAuth;
}
// custom middleware code
public async Task Invoke(HttpContext context)
{
// anonymous path, skipping
if (IsAllowedWithoutWindowsAuth(context))
{
await _next(context);
return;
}
if (!context.User.Identity.IsAuthenticated)
{
await context.ChallengeAsync("Windows");
return;
}
// other code here
await _next(context);
}