繁体   English   中英

自定义身份验证中间件:身份验证失败时出现InvalidOperationException

Custom authentication middleware: InvalidOperationException on failed authentication

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

我想使用HTTP标头(例如Authorization ToggledKey 10079a4c-d27e-4898-915a-968850c756ef来验证对ASP.NET Core 1.0应用程序的调用的身份验证

我的想法是,我可以发布API密钥,并且人们可以使用它们,撤销它们,等等。我只需要一个非常简单的密钥-我不想进入OAuth,IdentityServer或其他任何东西。

我遵循了本教程该教程讨论了如何为测试目的“伪造”成功的响应,最终得到了以下代码:

public class TestAuthenticationOptions : AuthenticationOptions  
{
    public virtual ClaimsIdentity Identity { get; } = new ClaimsIdentity(new Claim[]
    {
        new Claim(ClaimTypes.Name, Guid.NewGuid().ToString()),
        // Other claims omitted for brevity
    }, "Toggled");

    public TestAuthenticationOptions()
    {
        this.AuthenticationScheme = "ToggledAuthenticationMiddleware";
        this.AutomaticAuthenticate = true;
    }
}

public class TestAuthenticationHandler : AuthenticationHandler<TestAuthenticationOptions>  
{
    protected override Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        var authenticationTicket = new AuthenticationTicket(
                                        new ClaimsPrincipal(Options.Identity),
                                        new AuthenticationProperties(),
                                        this.Options.AuthenticationScheme);

        return Task.FromResult(AuthenticateResult.Success(authenticationTicket));
    }
}

public class TestAuthenticationMiddleware : AuthenticationMiddleware<TestAuthenticationOptions>  
{
    private readonly RequestDelegate next;

    public TestAuthenticationMiddleware(RequestDelegate next, IOptions<TestAuthenticationOptions> options, ILoggerFactory loggerFactory)
        : base(next, options, loggerFactory, System.Text.Encodings.Web.UrlEncoder.Default)
    {
        this.next = next;
    }

    protected override AuthenticationHandler<TestAuthenticationOptions> CreateHandler()
    {
        return new TestAuthenticationHandler();
    }
}

首先,我只是尝试获得一个硬编码的成功身份验证,该身份验证将使我能够看到具有User.Identity.Name的用户和一个硬编码的失败身份验证,以使我看到401 Unauthorized -只是为了了解它是如何进行的作品。

添加到Configure方法中:

app.UseMiddleware<TestAuthenticationMiddleware>(); 
app.UseMvc();

到目前为止,一切正常,它可以正常工作- [Authorize]属性放在控制器上,我在User.Identity.Name获得一个GUID。

问题:

当我更改失败的响应时:

return Task.FromResult(AuthenticateResult.Fail("Auth Failed!"));
//return Task.FromResult(AuthenticateResult.Success(authenticationTicket));

我得到的不是500,而是401,但有以下异常:

Unknown error responding to request: InvalidOperationException:
System.InvalidOperationException: No authentication handler is configured to handle the scheme: Automatic
at Microsoft.AspNetCore.Http.Authentication.Internal.DefaultAuthenticationManager.<ChallengeAsync>d__12.MoveNext()

我确实在记录的中间件中看到身份验证失败:

[Information] ToggledAppServices.TestAuthenticationMiddleware: ToggledAuthenticationMiddleware was not authenticated. Failure message: Auth failed! 

因此,我可以看到它确实使用了中间件,但未通过身份验证,但也看到了InvalidOperationException之前:

[Information] Microsoft.AspNetCore.Mvc.ChallengeResult: Executing ChallengeResult with authentication schemes ().

在此之后,我还是很困惑。 我该怎么做才能使中间件成为身份验证的“唯一”点,如果失败,则返回401,而不是尝试做更多的事情并导致InvalidOperationException失败?

完整日志:

[Debug] Microsoft.AspNetCore.Hosting.Internal.WebHost: Hosting starting 
[Debug] Microsoft.AspNetCore.Hosting.Internal.WebHost: Hosting started 
START RequestId: 52c7358f-e50a-11e7-a5a6-b3632cca0b75 Version: $LATEST
Incoming GET requests to /api/values
[Information] Microsoft.AspNetCore.Hosting.Internal.WebHost: Request starting GET https://www.example.com/api/controller application/json 
[Information] ToggledAppServices.TestAuthenticationMiddleware: ToggledAuthenticationMiddleware was not authenticated. Failure message: Auth failed! 
[Debug] Microsoft.AspNetCore.Routing.Tree.TreeRouter: Request successfully matched the route with name '' and template 'api/values'. 
[Debug] Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Executing action ToggledAppServices.Controllers.ValuesController.Get (ToggledAppServices) 
[Information] Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Authorization failed for user: . 
[Warning] Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'. 
[Information] Microsoft.AspNetCore.Mvc.ChallengeResult: Executing ChallengeResult with authentication schemes (). 
Unknown error responding to request: InvalidOperationException:
System.InvalidOperationException: No authentication handler is configured to handle the scheme: Automatic
at Microsoft.AspNetCore.Http.Authentication.Internal.DefaultAuthenticationManager.<ChallengeAsync>d__12.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Mvc.ChallengeResult.<ExecuteResultAsync>d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeResultAsync>d__32.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeAsync>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Hosting.Internal.RequestServicesContainerMiddleware.<Invoke>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction.<ProcessRequest>d__15.MoveNext()
InvalidOperationException:
System.InvalidOperationException: No authentication handler is configured to handle the scheme: Automatic
at Microsoft.AspNetCore.Http.Authentication.Internal.DefaultAuthenticationManager.<ChallengeAsync>d__12.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Mvc.ChallengeResult.<ExecuteResultAsync>d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeResultAsync>d__32.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeAsync>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Hosting.Internal.RequestServicesContainerMiddleware.<Invoke>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction.<ProcessRequest>d__15.MoveNext()

[Information] Microsoft.AspNetCore.Hosting.Internal.WebHost: Request finished in 7360.5673ms 0 
Response Base 64 Encoded: False
END RequestId: 52c7358f-e50a-11e7-a5a6-b3632cca0b75
1 个回复
System.InvalidOperationException: No authentication handler is configured to handle the scheme: Automatic
  at Microsoft.AspNetCore.Http.Authentication.Internal.DefaultAuthenticationManager.<ChallengeAsync>d__12.MoveNext()

这表明您的身份验证处理程序的身份验证工作正常,并且由于身份验证失败而正确创建了质询结果。

因此,现在,默认的质询身份验证处理程序应运行以处理质询请求。 但是,没有配置默认的质询方案,因此失败。

为了告诉您的TestAuthenticationHandler也处理质询请求,您应该将TestAuthenticationOptions类型的AutomaticChallenge选项设置为true

// handle authenticate requests by default
AutomaticAuthenticate = true;

// handle challenge requests by default
AutomaticChallenge = true;

然后,您的处理程序将针对质询请求运行,并且由于您未提供自定义实现, 因此默认行为只会生成401 HTTP响应。

1 自定义 Laravel 身份验证中间件

在我的users表中,我有一个对应于用户权限的列rank 。 如果rank &gt; 0 ,则用户可以登录并继续,因为rank为0表示他们(暂时)被阻止或不活动。 所以我需要的是自定义auth中间件,所以只有 rank &gt; 0才会被认证。 我对它进行了一些研究,但没有找到确切地放置我的代码的 ...

3 在身份验证中间件之后调用自定义中间件

在 Django REST framework 中,身份验证中间件仅在执行视图中间件之后才在请求中设置用户对象,而在此之前执行任何自定义中间件。 在身份验证中间件设置用户对象后,是否有某种方法可以更改此顺序并执行自定义中间件 作为替代方案,我在中间件本身中创建了用户对象,它工作正常,但这只是一个 h ...

5 在哪里将自定义中间件用于身份验证Laravel 5.2

在我的项目中,两种类型的用户:管理员和普通用户。 它们由users表中的isAdmin字段isAdmin 。 用户可以使用以下功能编辑个人资料 路线是 管理员还可以使用来编辑任何用户个人资料 在两种情况下,动作都是相同的,但在第一种方法中,不需要参数。 但是对于ad ...

6 Lumen / Laravel-自定义身份验证中间件错误

我已经为流明项目创建了身份验证中间件。 身份验证使用外部API,但是除非我弄错了,否则这不是问题。 如果我未通过身份验证,中间件会正确地将我重定向到登录页面,并在我输入良好凭据后正确地将我登录并保存在会话中。 但是,只要我使用中间件,它就不会显示内部主页。 App \\ Http \\ ...

7 自定义身份验证中间件在MVC 6中

我正在尝试为MVC 6构建一个自定义身份验证中间件,并有一些问题。 首先,有没有可用的东西来演示实现自定义身份验证中间件的正确方法? 我试图破解现有的框架代码,但我感觉这不是最好的方法。 在执行上述黑客攻击后 ,我最终得到的东西看起来可能有效,但我不确定原因。 在我的Star ...

8 .Net Core 2.1自定义中间件与身份验证的问题

我编写了一个自定义中间件,以检查用户是否有特定的声明(需要使用该应用程序)。 如果用户没有,我将返回422无法处理。 但是,我注意到,如果不提供令牌,则会收到422,而不是401。如果我检查自定义中间件上的IsAuthenticated属性,则不提供令牌时为false,如果提供则为true。 ...

10 用于特定路由的ASP .NET Core自定义身份验证中间件

我有一个ASP .NET Core应用程序,当前正在为JWT使用身份验证架构,在该应用程序中,它以JWT的形式检查Bearer令牌的“授权”标头,然后从中建立身份。 这是我们要在此服务上使用的主要身份验证架构,但是我想使用基本身份验证来代替一个MVC Controller端点。 该端点将受到 ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2021 STACKOOM.COM