我有一本书.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相关问答推荐

asp.net、url 重写模块和 web.config

ASP.NET Web 应用程序 (.NET Framework) 与 ASP.NET Core Web 应用程序 (.NET Framework) 之间的差异

ASP.NET 如何将控件呈现为 HTML?

如何在页面加载之前运行 JavaScript 代码?

有没有办法在外部 javascript 文件中使用<%= someObject.ClientID %>?

用于链接字符串中的 url 的 C# 代码

如何计算/查找给定日期的周数?

将 ListItem 的 ASP.NET 列表数据绑定到 DropDownList 问题

部署后网站需要强制刷新

将通用列表绑定到转发器 - ASP.NET

以编程方式从后面的代码中关闭 aspx 页面

如何从 NuGet 安装 EntityFramework 5.0(和其他旧版本)?

应该如何使用 RedirectToRoute?

使用 VirtualPathProvider 从 DLL 加载 ASP.NET MVC 视图

覆盖静态方法

将列表转换为 json 格式 - 快速简便的方法

ASP.NET 中的嵌套中继器

在 ASPNET 标识 2.0 中禁用用户

如何将 DataTable 转换为类 Object?

如何在asp.net的GridView中按列名而不是按索引获取单元格值