我正在为我的ASP.NET核心API创建一个身份验证方案。
它调用我的处理程序并命中断点,但是API调用仍然返回结果,即使授权失败。
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
if (!Request.Headers.ContainsKey(AuthorizationHeaderName))
{
//Authorization header not in request
return AuthenticateResult.Fail("Missing Authorization header");
}
在我天真的理解中,如果身份验证失败,它不应该返回数据。
我遗漏了什么?
详细信息
我在Startup.ConfigureServices中注册了这样的方案
services.AddAuthentication(options => {
// This (options.Default..Scheme) causes the default authentication scheme to be set.
// Without this, the Authorization header is not checked and
// you'll get no results.
options.DefaultAuthenticateScheme = BasicAuthenticationDefaults.AuthenticationScheme;
}).AddScheme<BasicAuthenticationOptions, BasicAuthenticationHandler>("Basic", null);
Startup.Config调用
app.UseAuthentication();
app.UseHttpsRedirection();
app.UseMvc();
其余代码如下所示:
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Text;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
namespace WebAPI.Authentication
{
public interface IBasicAuthenticationService
{
Task<AuthenticateResult> HandleAuthenticateAsync();
}
public static class BasicAuthenticationDefaults
{
public const string AuthenticationScheme = "Basic";
}
public class BasicAuthenticationOptions : AuthenticationSchemeOptions
{ }
public class BasicAuthenticationHandler : AuthenticationHandler<BasicAuthenticationOptions>
{
private const string AuthorizationHeaderName = "Authorization";
private const string BasicSchemeName = "Basic";
public BasicAuthenticationHandler(
IOptionsMonitor<BasicAuthenticationOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
ISystemClock clock)
: base(options, logger, encoder, clock)
{
}
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
if (!Request.Headers.ContainsKey(AuthorizationHeaderName))
{ // Rejected here. Should fail.
//Authorization header not in request
return AuthenticateResult.Fail("Missing Authorization header");
}
if .... // never gets this far
}
return AuthenticateResult.Success(ticket);
}
}
}
这是控制器,它不正确地返回结果。
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
namespace TMAWebAPI.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value2" };
}
}
}
所有这些代码行都会在调试器中命中,因此该部分似乎工作正常。
但是API调用仍然返回结果,即使它失败了身份验证。
更新:
向Controller添加AuthenticationScheme属性会使其失败。
如下所示:
[Route("api/[controller]")]
[ApiController]
[Authorize(AuthenticationSchemes = "Basic")]
public class ValuesController : ControllerBase
这不是好事。默认情况下,它应该失败,而不是必须将其添加到每个控制器中。
更新2:
向services.AddMvc添加一个过滤器看起来很有希望,但也不起作用。文档声明您不必实现授权筛选器,因为它们包括在内。我找不到。
我继承了AuthorizeAttribute,使用了AddMvc所要求的Matti和IFilterMetadata的想法。它编译但仍然允许未经授权的访问。
public class BasicAuthorizeAttribute : AuthorizeAttribute, IFilterMetadata { }
services.AddMvc(options => {
options.Filters.Add(typeof(BasicAuthorizeAttribute));
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
更新3:
试过
policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser()
就像马蒂建议的那样,但那又回来了
InvalidOperationException: No authenticationScheme was specified, and there was no DefaultChallengeScheme found.
我对重定向到API不存在的登录页面没有任何兴趣,所以我尝试了。
policy = new AuthorizationPolicyBuilder().AddAuthenticationSchemes(new[] {BasicAuthenticationDefaults.AuthenticationScheme })
它编译但抛出异常。
InvalidOperationException Message=AuthorizationPolicy must have at least one requirement.
发布于 2019-07-12 20:23:27
您需要将[Authorize]
属性添加到控制器中,以使授权能够实际对其结果执行任何操作。您可以在全球范围内添加如下内容:
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
});
发布于 2019-07-17 10:50:20
最后的分辨率使用AddMVC。解决办法是,除了增加一个方案外,该计划还需要一个要求。
这挺管用的。如果我没有发送任何auth标头,它将返回一个空页。如果我发送过期的标头,它会发送500。应该是401。但它不返回任何值,这才是我真正关心的。
public class TokenAuthorizationRequirement: IAuthorizationRequirement {}
services.AddMvc(config => {
var policy = new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(new[] {BasicAuthenticationDefaults.AuthenticationScheme })
.AddRequirements(new BasicAuthorizationRequirement())
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
});
https://stackoverflow.com/questions/56981640
复制相似问题