我有一个使用JwtBearer
身份验证配置和Identity Server 4正常运行的ASP.NET Core 2.2应用程序,直到我希望拥有由[Authorize]
属性处理的多个权限为止,一切正常。 / p>
我经历了多个线程并就此问题进行了讨论,并查看了文档:https://docs.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-2.2&tabs=aspnetcore2x#use-multiple-authentication-schemes完全相同的代码不起作用,并产生了以下故障:
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
System.InvalidOperationException: IDX20803: Unable to obtain configuration from: '[PII is hidden]'. ---> System.IO.IOException: IDX20804: Unable to retrieve document from: '[PII is hidden]'. ---> System.Net.Http.HttpRequestException: No connection could be made because the target machine actively refused it ---> System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
at System.Threading.Tasks.ValueTask1.get_Result() at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Threading.Tasks.ValueTask1.get_Result()
at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask1 creationTask) at System.Threading.Tasks.ValueTask1.get_Result()
at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts) at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel) --- End of inner exception stack trace --- at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel) at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String address, IDocumentRetriever retriever, CancellationToken cancel) at Microsoft.IdentityModel.Protocols.ConfigurationManager1.GetConfigurationAsync(CancellationToken cancel)
--- End of inner exception stack trace ---
at Microsoft.IdentityModel.Protocols.ConfigurationManager1.GetConfigurationAsync(CancellationToken cancel) at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync() at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync() at Microsoft.AspNetCore.Authentication.AuthenticationHandler1.AuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
at Microsoft.AspNetCore.Authorization.Policy.PolicyEvaluator.AuthenticateAsync(AuthorizationPolicy policy, HttpContext context)
at Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter.OnAuthorizationAsync(AuthorizationFilterContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at JQ.GrupoFontana.API.Startup.<>c.<<Configure>b__9_1>d.MoveNext() in C:\Users\carlostorrecillas\Documents\git\jq.grupofontana.api\JQ.GrupoFontana.API\Startup.cs:line 264
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware.InvokeCore(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 3073.2088ms 500 text/html; charset=utf-8
Authorization标头的示例是:
Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Ijk4NDM3ZDYxM2Y3N2NhNmFmMzViZWRkYzNhOTA5MDFhIiwidHlwIjoiSldUIn0.eyJuYmYiOjE1NTYyOTY0MTcsImV4cCI6MTU1NjMwMDAxNywiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDoxMTcxMCIsImF1ZCI6WyJodHRwOi8vbG9jYWxob3N0OjExNzEwL3Jlc291cmNlcyIsImdydXBvZm9udGFuYWFwaSJdLCJjbGllbnRfaWQiOiJuZWdyb2NhcmJvbiIsInN1YiI6IjI1ZjExN2M5LWJjYzgtNDU3Ny1iNzIwLTk5YmVjYTlmZTk4MyIsImF1dGhfdGltZSI6MTU1NjI5NjQxNywiaWRwIjoibG9jYWwiLCJlbWFpbCI6ImluZm9AanVzdC1xdWFsaXR5LmNvbSIsInVzZXJuYW1lIjoianVzdHF1YWxpdHlAbmVncm9jYXJib24uZXMiLCJzY29wZSI6WyJvcGVuaWQiLCJwcm9maWxlIiwiZ3J1cG9mb250YW5hYXBpIl0sImFtciI6WyJwd2QiXX0.RofpWBaFKFaS9W5w6kjxVI6lfr7aWChIMHht3ibZ5LmTarAsGGoof-9GpWZxL3D9KfjoEC9gcmVIA7saB-Yikvz6i3yvHYsqhMkg7cLaBlUiz6lEpLQOS1-vYRYou0veyvI_EmSkZb9k00ErjA4BrNeb0kw3tL3PJI9A2nznnJPBU8hT7xiXeabQ9ROuuqxJU-GkP_3yr88CVfwuKiU8ur5xAbsLDyUCYiSL0DMbvoLhvLVdkHTJTuWcvfUcEK3Vidv38v490XZs7l2oI14ptA1vamIQ8iE_Pkb_NNv3S_F0hWmLHBWjaqGRlRdUE7R2kfFETRJdT6izzGOompuQwA
哪个好。我现在拥有的API中的代码是:
services.AddAuthentication("authority1")
.AddJwtBearer("authority1", options =>
{
options.Authority = "http://localhost:11710";
options.Audience = "myaudience";
options.RequireHttpsMetadata = false;
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
if (context.Request.Path.Value.StartsWith("/hub", StringComparison.InvariantCultureIgnoreCase))
{
context.Token = context.Request.Query["access_token"];
}
return Task.CompletedTask;
},
OnTokenValidated = context =>
{
return Task.CompletedTask;
},
OnAuthenticationFailed = context =>
{
return Task.CompletedTask;
},
OnChallenge = context =>
{
return Task.CompletedTask;
}
};
})
.AddJwtBearer("authority2", options =>
{
options.Authority = "http://localhost:11910";
options.Audience = "myaudience";
options.RequireHttpsMetadata = false;
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
if (context.Request.Path.Value.StartsWith("/hub", StringComparison.InvariantCultureIgnoreCase))
{
context.Token = context.Request.Query["access_token"];
}
return Task.CompletedTask;
},
OnTokenValidated = context =>
{
return Task.CompletedTask;
},
OnAuthenticationFailed = context =>
{
return Task.CompletedTask;
},
OnChallenge = context =>
{
return Task.CompletedTask;
}
};
});
services.AddAuthorization(options =>
{
options.DefaultPolicy = new AuthorizationPolicyBuilder("authority1", "authority2").RequireAuthenticatedUser()
.Build();
});
您可以忽略/hub
检查内容,因为这将处理令牌和SignalR。我为每个事件添加了一个断点,以查看失败的地方和顺序(请注意,authority1
正在运行的应用程序,authority2
当前已停止):
authority1.onMessageReceived - OK
authority1.onTokenValidated - OK
authority2.onMessageReceived - OK
authority2.onAuthenticationFailed - Method completes then I get the exception
我不确定问题是否是我需要让所有权限都运行以进行某种形式的验证/通信(我本来不会这样认为)还是ASP.NET代码本身是否存在实际错误? -嘿,也可能是这种情况。从API的角度来看,我不确定是否会错过任何其他配置,但我会说它已经设置好了。
我在控制器中使用的标准[Authorize]
属性中没有任何身份验证方案的内容-我已经尝试过,但是也没有用。
如果您遇到任何问题,我将非常感谢您的帮助。
非常感谢!
更新:
多进行一些挖掘之后,我可以看到此解决方法:
https://github.com/aspnet/Security/issues/1680#issuecomment-370416251
在OnAuthenticationFailed上设置context.NoResult()
,但是我不确定这是否是有效的配置?