【发布时间】:2021-06-29 18:41:26
【问题描述】:
我正在设置一个新的 asp.net 核心应用程序。 我希望我的应用程序具有身份验证和授权,因此我将 Identity Server 4 用作另一个项目(在同一解决方案中)。 我一直在关注复数视觉指南,一切似乎都很好,直到我尝试通过 http 请求授权令牌发送。 使用 Postman,我向“https://localhost:5001/connect/token”发送了一个 http post 请求并获得了一个令牌。 获得令牌后,我发送一个带有 Header - “Authorization : Bearer [token]” 的 GET 请求并获得 500 HTTP 状态码。 我使用 OpenSSL 创建了一个“.cer”文件。
我已经搜索了解决方案,主要是我看到了与我的问题没有必要相关的解决方案。交易是,我猜我正在使用一个相当新版本的 ASP.NET CORE,因为我使用的 api 是不同的。 我尝试安装“.cer”文件,但没有成功。 我读过它与两个项目是相同的解决方案有某种关系,但没有找到具体的解决方案。 我确实使用“dotnet dev-certs https --trust”批准了我的“.cer”文件,它确实批准了它,但还是一样。
至于代码,这里是我的两个项目的 Program.cs,Startup.cs: API Program.cs:
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseUrls("http://127.0.0.1:5000")
.ConfigureLogging((hostingConext, logging) =>
{
logging.AddConfiguration(hostingConext.Configuration.GetSection("Logging"));
logging.AddConsole();
logging.AddDebug();
logging.AddEventSourceLogger();
}).UseStartup<Startup>()
.Build();
}
API Startup.cs:
public class Startup
{
private IConfiguration Configuration { get; set; }
public Startup(IHostingEnvironment environment)
{
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.SetBasePath(environment.ContentRootPath);
builder.AddJsonFile("appsettings.json");
builder.AddEnvironmentVariables();
Configuration = builder.Build();
}
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(authOptions =>
{
authOptions.DefaultScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
authOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddIdentityServerAuthentication(options =>
{
options.RequireHttpsMetadata = false;
options.Authority = "https://127.0.0.1:5001";
options.ApiName = "Swap";
});
services.AddSingleton(Configuration);
services.AddScoped<ITokenSetData, SqlTokensetData>();
services.AddDbContext<DbContextTokenSet>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseAuthentication();
app.UseFileServer();
app.UseMvc(ConfigureRoutes);
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
private void ConfigureRoutes(IRouteBuilder routerBuilder)
{
routerBuilder.MapRoute("Default", "{controller=Home}/{action=Index}/{id?}");
}
}
AuthServer Program.cs:
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseUrls("https://localhost:5001")
.UseStartup<Startup>()
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddConsole();
});
}
AuthServer Startup.cs:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services
.AddIdentityServer()
//.AddDeveloperSigningCredential()
.AddSigningCredential(new X509Certificate2(@"D:\Programming Projects\Swap\swap.pfx", "password"))
.AddInMemoryApiResources(InMemoryConfiguration.ApiResources())
.AddInMemoryClients(InMemoryConfiguration.Clients())
.AddTestUsers(InMemoryConfiguration.Users().ToList());
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseDeveloperExceptionPage();
app.UseIdentityServer();
app.UseStaticFiles();
}
}
这是我的控制器和方法(如果重要的话):
[Authorize]
public class HomeController : Controller {
[HttpGet]
public string Hello()
{
return "hello";
}
}
实际结果是: 接口:
System.InvalidOperationException: IDX20803: Unable to obtain configuration from: 'https://127.0.0.1:5001/.well-known/openid-configuration'. ---> System.IO.IOException: IDX20804: Unable to retrieve document from: 'https://127.0.0.1:5001/.well-known/openid-configuration'. ---> System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.PartialFrameCallback(AsyncProtocolRequest asyncRequest)
--- End of stack trace from previous location where exception was thrown ---
at System.Net.Security.SslState.ThrowIfExceptional()
at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result)
at System.Net.Security.SslStream.EndAuthenticateAsClient(IAsyncResult asyncResult)
at System.Net.Security.SslStream.<>c.<AuthenticateAsClientAsync>b__47_1(IAsyncResult iar)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
at System.Threading.Tasks.ValueTask`1.get_Result()
at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Threading.Tasks.ValueTask`1.get_Result()
at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask`1 creationTask)
at System.Threading.Tasks.ValueTask`1.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(Task`1 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.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
--- End of inner exception stack trace ---
at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
at IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler.HandleAuthenticateAsync() in C:\local\identity\server4\AccessTokenValidation\src\IdentityServerAuthenticationHandler.cs:line 61
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Server.IISIntegration.IISMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 222.4963ms 500
认证服务器:
info: Microsoft.AspNetCore.Server.Kestrel[20]
Connection id "0HLMJ502OFSUM" request processing ended abnormally.
System.IO.IOException: The decryption operation failed, see inner exception. ---> System.ComponentModel.Win32Exception: An unknown error occurred while processing the certificate
--- End of inner exception stack trace ---
at System.Net.Security.SslStreamInternal.ReadAsyncInternal[TReadAdapter](TReadAdapter adapter, Memory`1 buffer)
at Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal.AdaptedPipeline.ReadInputAsync(Stream stream)
at System.IO.Pipelines.PipeCompletion.ThrowLatchedException()
at System.IO.Pipelines.Pipe.GetReadResult(ReadResult& result)
at System.IO.Pipelines.Pipe.GetReadAsyncResult()
at System.IO.Pipelines.Pipe.DefaultPipeReader.GetResult(Int16 token)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequestsAsync[TContext](IHttpApplication`1 application)
预期的结果是“你好”。 谢谢。
【问题讨论】:
-
尽量不要使用ips。此问题是因为您在本地使用 https 而没有正确的自签名证书。尝试“localhost:5001/.well-known/openid-configuration”或根本不使用 https。
-
我没有尝试向 'localhost:5001/.well-known/openid-configuration' 发送 GET 请求,IdentityServer 做到了,但不知何故它被阻止了。
-
它不是身份服务器,它是试图获取您的身份提供者配置的 asp.net 核心中间件。它被阻止是因为您没有配置正确的本地 SSL。
-
如果我明白你的意思,我需要将我的代码更改为:options.Authority = "localhost:5001";不幸的是,它不起作用。我理解正确吗?
-
The remote certificate is invalid according to the validation procedure.表示您的客户端无法正确连接到您的 sts 服务器,因此您需要修复它。像 Vidmantas 建议的那样使用 http 作为测试是很好的第一步。
标签: asp.net-core identityserver4