我有一本书.NET Core 2.0应用程序,但存在授权问题.我想对特殊请求使用自定义授权.标头和标准默认身份验证.

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    // ...
    services.AddAuthorization(options =>
    {
        options.AddPolicy(DefaultAuthorizedPolicy, policy =>
        {
            policy.Requirements.Add(new TokenAuthRequirement());
        });
    });
    services.AddSingleton<IAuthorizationHandler, AuthTokenPolicy>();
    // ...
}

AuthTokenPolicy.cs:

public class AuthTokenPolicy : AuthorizationHandler<TokenAuthRequirement>
{   
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, TokenAuthRequirement requirement)
    {
        var filterContext = context.Resource as AuthorizationFilterContext;
        var response = filterContext.HttpContext.Response;
        try
        {
            // some validation code

            var isValidToken = isValidTokenTask.Result;
            if (!isValidToken)
            {
                response.StatusCode = 401;
                return Task.CompletedTask;
            }

            response.StatusCode = 200;
            context.Succeed(requirement);
        }
        catch (Exception)
        {
            return Task.CompletedTask;
        }
        return Task.CompletedTask;
    }
}

HomeController.cs年后:

[Authorize(Policy = Startup.DefaultAuthorizedPolicy)]
public async Task<IActionResult> IsVisible()

如果我使用了错误的请求.AuthTokenPolicy中的标题我看到了,但在日志(log)中我看到了这个错误:

系统InvalidOperationException:未指定authenticationScheme,也未找到DefaultChallengeScheme.\r\n在Microsoft.AspNetCore.认证.认证服务.迪乌11.MoveNext().运行时.例外服务.例外DispatchInfo.在系统上抛出().运行时.编译器服务.任务等待者.HandleNonSuccessAndDebuggerNotification(任务)\r\n在Microsoft上.AspNetCore.Mvc.挑战者结果.d__14.MoveNext().运行时.例外服务.例外DispatchInfo.在系统上抛出().运行时.编译器服务.任务等待者.HandleNonSuccessAndDebuggerNotification(任务)\r\n在Microsoft上.AspNetCore.Mvc.内部的资源调用者.d__19.MoveNext().运行时.例外服务.例外DispatchInfo.在系统上抛出().运行时.编译器服务.任务等待者.HandleNonSuccessAndDebuggerNotification(任务)\r\n在Microsoft上.AspNetCore.Mvc.内部的资源调用者.d__17.MoveNext().运行时.例外服务.例外DispatchInfo.在系统上抛出().运行时.编译器服务.任务等待者.HandleNonSuccessAndDebuggerNotification(任务)\r\n在Microsoft上.AspNetCore.Mvc.内部的资源调用者.d__15.MoveNext().运行时.例外服务.例外DispatchInfo.在系统上抛出().运行时.编译器服务.任务等待者.HandleNonSuccessAndDebuggerNotification(任务)\r\n在Microsoft上.AspNetCore.建设者路由软件.d__4.MoveNext().运行时.例外服务.例外DispatchInfo.在系统上抛出().运行时.编译器服务.任务等待者.HandleNonSuccessAndDebuggerNotification(任务)\r\n在Microsoft上.AspNetCore.诊断学.StatusCodePagesMiddleware.d__3.MoveNext().运行时.例外服务.例外DispatchInfo.在系统上抛出().运行时.编译器服务.任务等待者.HandleNonSuccessAndDebuggerNotification(任务)\r\n位于React.AspNet.Babelfile.5.MoveNext().运行时.例外服务.例外DispatchInfo.在系统上抛出().运行时.编译器服务.任务等待者.HandleNonSuccessAndDebuggerNotification(任务)\r\n在Microsoft上.AspNetCore.认证.认证中间件.d__6.MoveNext().运行时.例外服务.例外DispatchInfo.在系统上抛出().运行时.编译器服务.任务等待者.HandleNonSuccessAndDebuggerNotification(任务)\r\n位于核心位置.常见的中间件.日志(log)记录.d__3.D:\Dev\microservicePDP\Template\core中的MoveNext().公共\中间件\日志(log)中间件.政务司司长:第72行

在阅读了Migrating Authentication and Identity to ASP.NET Core 2.0之后,我将这段代码添加到Startup.cs中

文章引述:

services.AddAuthentication(options => 
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
});

如果以下条件之一为真,则在2.0中定义默认方案:

我在ConfigureServices()中加了AuthenticationSchemeDefaultChallengeScheme.这没用,这里也有同样的错误.我试着在Startup.Configure()方法中使用app.UseAuthentication();,但没有结果.

如何在没有身份验证的情况下使用自定义授权?

推荐答案

不要使用授权而不是身份验证.我应该有权使用header为所有客户提供服务.

工作代码为:

public class TokenAuthenticationHandler : AuthenticationHandler<TokenAuthenticationOptions> 
{
    public IServiceProvider ServiceProvider { get; set; }

    public TokenAuthenticationHandler (IOptionsMonitor<TokenAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IServiceProvider serviceProvider) 
        : base (options, logger, encoder, clock) 
    {
        ServiceProvider = serviceProvider;
    }

    protected override Task<AuthenticateResult> HandleAuthenticateAsync () 
    {
        var headers = Request.Headers;
        var token = "X-Auth-Token".GetHeaderOrCookieValue (Request);

        if (string.IsNullOrEmpty (token)) {
            return Task.FromResult (AuthenticateResult.Fail ("Token is null"));
        }           

        bool isValidToken = false; // check token here

        if (!isValidToken) {
            return Task.FromResult (AuthenticateResult.Fail ($"Balancer not authorize token : for token={token}"));
        }

        var claims = new [] { new Claim ("token", token) };
        var identity = new ClaimsIdentity (claims, nameof (TokenAuthenticationHandler));
        var ticket = new AuthenticationTicket (new ClaimsPrincipal (identity), this.Scheme.Name);
        return Task.FromResult (AuthenticateResult.Success (ticket));
    }
}

Startup.cs:

#region Authentication
services.AddAuthentication (o => {
    o.DefaultScheme = SchemesNamesConst.TokenAuthenticationDefaultScheme;
})
.AddScheme<TokenAuthenticationOptions, TokenAuthenticationHandler> (SchemesNamesConst.TokenAuthenticationDefaultScheme, o => { });
#endregion

和myControler.cs:

[Authorize(AuthenticationSchemes = SchemesNamesConst.TokenAuthenticationDefaultScheme)]
public class MainController : BaseController
{ ... }

我现在找不到TokenAuthenticationOptions,但它是空的.我找到相同的类PhoneNumberAuthenticationOptions:

public class PhoneNumberAuthenticationOptions : AuthenticationSchemeOptions
{
    public Regex PhoneMask { get; set; }// = new Regex("7\\d{10}");
}

您应该定义静态类SchemesNamesConst.比如:

public static class SchemesNamesConst
{
    public const string TokenAuthenticationDefaultScheme = "TokenAuthenticationScheme";
}

Asp.net相关问答推荐

Web 服务器配置为不列出此目录的内容. asp.net vs 2012 错误?

log4net 记录所有未处理的应用程序错误

将 Global.asax 迁移到 Startup.cs

模型项的类型为 CookMeIndexViewModel,但需要类型为 IEnumerable 的模型项

没有身份的 ASP.NET Core 2.0 承载身份验证

Web.config 导致被组策略阻止错误

无法加载文件或程序集'System.Web.WebPages.Razor,版本 = 3.0.0.0

如何为角色以及特定用户使用自定义授权属性?

Razor 主机工厂错误

在 asp.net 中为动态 PDF 指定文件名

如何以编程方式将标签的前景色设置为其默认值?

与 Twitter Bootstrap Bundle 的 ASP.NET MVC4

DropDownList AppendDataBoundItems(第一项为空白且无重复项)

aspnet_compiler 发现错误版本的 System.Web.WebPages 1.0.0.0 而不是 2.0.0.0

ASP .NET Button 事件处理程序不会在第一次单击时触发,而是在 PostBack 后的第二次单击时触发

如何在实体框架中添加表?

如何将参数传递给 ASP.NET MVC 2 中的自定义 ActionFilter?

ASP.NET 发布try 复制不存在的文件

ASP.NET 邮箱验证器正则表达式

获取 Application_Start 中的当前应用程序物理路径