C# 为什么Asp.Net核心身份验证方案是强制性的

C# 为什么Asp.Net核心身份验证方案是强制性的,c#,asp.net-mvc,security,authentication,asp.net-core,C#,Asp.net Mvc,Security,Authentication,Asp.net Core,在Asp.NETCore中,身份验证方案似乎是强制性的,我对此感到非常失望。 我的目标是构建一个API,我不想知道任何关于客户端的事情。我已经建立了自定义的身份验证和授权,效果很好。我没有使用身份或cookies。但是,如果没有有效的身份验证方案,我不能返回403禁止结果,否则我会得到以下异常 System.InvalidOperationException:未找到任何身份验证处理程序 配置为处理方案:自动 我的问题是,我可以将MVC配置为不使用身份验证方案,或者在不依赖登录路径或任何路径的情况

在Asp.NETCore中,身份验证方案似乎是强制性的,我对此感到非常失望。 我的目标是构建一个API,我不想知道任何关于客户端的事情。我已经建立了自定义的身份验证和授权,效果很好。我没有使用身份或cookies。但是,如果没有有效的身份验证方案,我不能返回403禁止结果,否则我会得到以下异常

System.InvalidOperationException:未找到任何身份验证处理程序 配置为处理方案:自动


我的问题是,我可以将MVC配置为不使用身份验证方案,或者在不依赖登录路径或任何路径的情况下创建身份验证方案吗?

仔细阅读Asp.net核心安全源代码后,我已经成功创建了自定义身份验证处理程序。为此,您需要实现3个类

第一个类实现了一个抽象的AuthenticationOptions

public class AwesomeAuthenticationOptions : AuthenticationOptions {
    public AwesomeAuthenticationOptions() {
        AuthenticationScheme = "AwesomeAuthentication";
        AutomaticAuthenticate = false;
    }
}
第二个类实现了一个抽象AuthenticationHandler

public class AwesomeAuthentication : AuthenticationHandler<AwesomeAuthenticationOptions>
{
    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        var prop = new AuthenticationProperties();
        var ticket = new AuthenticationTicket(Context.User, prop, "AwesomeAuthentication");
        //this is where you setup the ClaimsPrincipal
        //if auth fails, return AuthenticateResult.Fail("reason for failure");
        return await Task.Run(() => AuthenticateResult.Success(ticket));
    }
}
公共类身份验证:AuthenticationHandler
{
受保护的重写异步任务handleAuthenticateAync()
{
var prop=新的AuthenticationProperties();
var ticket=新的身份验证ticket(Context.User,prop,“AwesomeAuthentication”);
//这是您设置ClaimsPrincipal的地方
//如果身份验证失败,则返回AuthenticateResult.Fail(“失败原因”);
返回等待任务。运行(()=>AuthenticateResult.Success(票证));
}
}
第三个类实现了一个抽象的AuthenticationMiddleware

public class AwesomeAuthenticationMiddleware : AuthenticationMiddleware<AwesomeAuthenticationOptions>
{
    public AwesomeAuthenticationMiddleware(RequestDelegate next, 
        IOptions<AwesomeAuthenticationOptions> options,
        ILoggerFactory loggerFactory,
        UrlEncoder urlEncoder) : base(next, options, loggerFactory, urlEncoder) {

    }

    protected override AuthenticationHandler<AwesomeAuthenticationOptions> CreateHandler()
    {
        return new AwesomeAuthentication();
    }
}
公共类AwesomeAuthenticationMiddleware:AuthenticationMiddleware
{
公共AwesomeAuthenticationMiddleware(RequestDelegate下一步,
选项,
伊洛格工厂伐木厂,
UrlEncoder UrlEncoder):基础(下一步,选项,日志工厂,UrlEncoder){
}
受保护的重写AuthenticationHandler CreateHandler()
{
返回新的身份验证();
}
}
最后,在Startup.cs Configure方法中使用中间件组件

app.UseMiddleware<AwesomeAuthenticationMiddleware>();
app.UseMiddleware();

现在,您可以构建自己的身份验证方案。

请发布一些代码,以便我们可以帮助您解决此问题。@Brad这更像是一个体系结构问题。我没有对任何特定的代码有异议。基本上,如果您使用Authorize属性或处理User.Identity的大多数事情,您需要某种身份验证方案。您不需要,也不应该执行return Task.Run()。返回AuthenticateResult.Success(票证);通常情况下,如果没有其他身份验证中间件上下文,用户将是匿名用户。身份验证处理程序的全部要点是设置所有内容以填充Context.User。在handleAuthenticationAsync()中使用它很容易失败。@blowdart我已更正Task.Run()的返回。我明白这是为了设置主体,但我在这里添加了这段代码作为大纲。另外,当我使用属性[Authorize(“PolicyName”)]并且使用未经身份验证时,我收到403。在这一点上,我期待着401。知道为什么吗?谢谢你的反馈。这很棘手,但我想我已经掌握了窍门。一旦我正确地实现了AuthenticationHandler,一切都开始按预期工作。我不必为未经授权和禁止的操作而重写处理程序,因为他们做了我想做的事情。返回AuthenticateResult.Fail(“原因”);将主体上的IsAuthenticated设置为false,然后在质询中返回401。