.NET Core Openiddict 无效请求
.NET Core Openiddict invalid request
我在尝试在 .net core 1.0.1 上实施简单的令牌身份验证时遇到问题,我遵循了一个我喜欢的简单教程:
http://kevinchalet.com/2017/01/30/implementing-simple-token-authentication-in-aspnet-core-with-openiddict/
当我尝试向 http://localhost:51863/connect/token?grant_type=password&username=alice%40wonderland.com&password=P%40ssw0rd 发送请求时,我得到了响应:invalid_request","error_description":"指定的 HTTP 方法无效。
我的startup.cs:
services.AddDbContext<AssistDbContext>(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("AssistContext"));
});
services.AddScoped<AssistDbContext, AssistDbContext>();
services.AddDbContext<DbContext>(options =>
{
// Configure the context to use an in-memory store.
options.UseInMemoryDatabase();
// Register the entity sets needed by OpenIddict.
// Note: use the generic overload if you need
// to replace the default OpenIddict entities.
options.UseOpenIddict();
});
services.AddOpenIddict(options =>
{
// Register the Entity Framework stores.
options.AddEntityFrameworkCoreStores<DbContext>();
// Register the ASP.NET Core MVC binder used by OpenIddict.
// Note: if you don't call this method, you won't be able to
// bind OpenIdConnectRequest or OpenIdConnectResponse parameters.
options.AddMvcBinders();
// Enable the token endpoint.
options.EnableTokenEndpoint("/api/authorization/token");
// Enable the password flow.
options.AllowPasswordFlow();
// During development, you can disable the HTTPS requirement.
options.DisableHttpsRequirement();
});
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseApplicationInsightsRequestTelemetry();
app.UseApplicationInsightsExceptionTelemetry();
// Register the validation middleware, that is used to decrypt
// the access tokens and populate the HttpContext.User property.
app.UseOAuthValidation();
// Register the OpenIddict middleware.
app.UseOpenIddict();
app.UseMvcWithDefaultRoute();
}
更新
用 Postman 测试 returns 404:
日志:
Microsoft.AspNetCore.Hosting.Internal.WebHost:信息:请求开始 HTTP/1.1 POST http://localhost:51863/api/Authorization application/x-www-form-urlencoded 49
'dotnet.exe'(CoreCLR:clrhost):已加载 'C:\Users\consultoria.nuget\packages\AspNet.Security.OpenIdConnect.Extensions.0.2\lib\netstandard1.4\AspNet.Security.OpenIdConnect.Extensions.dll'。跳过加载符号。模块已优化,调试器选项 'Just My Code' 已启用。
'dotnet.exe'(CoreCLR:clrhost):已加载 'C:\Users\consultoria.nuget\packages\Microsoft.AspNetCore.WebUtilities.1.0-preview1-final\lib\netstandard1.3\Microsoft.AspNetCore.WebUtilities.dll'。跳过加载符号。模块已优化,调试器选项 'Just My Code' 已启用。
AspNet.Security.OpenIdConnect.Server.OpenIdConnectServerMiddleware:信息:已成功从 HTTP 请求中提取令牌请求:{
"grant_type": "password",
"username": "teste",
"password":“[出于安全原因删除]”
}.
'dotnet.exe'(CoreCLR:clrhost):已加载 'C:\Users\consultoria.nuget\packages\Microsoft.EntityFrameworkCore.InMemory.0.1\lib\netstandard1.3\Microsoft.EntityFrameworkCore.InMemory.dll'。跳过加载符号。模块已优化,调试器选项 'Just My Code' 已启用。
'dotnet.exe'(CoreCLR:clrhost):已加载 'C:\Users\consultoria.nuget\packages\Remotion.Linq.1.1\lib\netstandard1.0\Remotion.Linq.dll'。跳过加载符号。模块已优化,调试器选项 'Just My Code' 已启用。
'dotnet.exe'(CoreCLR:clrhost):已加载 'C:\Users\consultoria.nuget\packages\System.Interactive.Async.0.0\lib\netstandard1.0\System.Interactive.Async.dll'。跳过加载符号。模块已优化,调试器选项 'Just My Code' 已启用。
'dotnet.exe'(CoreCLR:clrhost):已加载 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App.0.1\System.Diagnostics.StackTrace.dll'。跳过加载符号。模块已优化,调试器选项 'Just My Code' 已启用。
'dotnet.exe'(CoreCLR:clrhost):已加载 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App.0.1\System.Reflection.Metadata.dll'。跳过加载符号。模块已优化,调试器选项 'Just My Code' 已启用。
'dotnet.exe'(CoreCLR:clrhost):已加载 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App.0.1\System.IO.MemoryMappedFiles.dll'。跳过加载符号。模块已优化,调试器选项 'Just My Code' 已启用。
'dotnet.exe'(CoreCLR:clrhost):已加载 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App.0.1\System.IO.UnmanagedMemoryStream.dll'。跳过加载符号。模块已优化,调试器选项 'Just My Code' 已启用。
Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware:错误:发生了未处理的异常:程序集 'Microsoft.EntityFrameworkCore.InMemory, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' 中类型 'Microsoft.EntityFrameworkCore.Storage.Internal.InMemoryTransactionManager' 中的方法 'get_CurrentTransaction' 没有实现。
System.TypeLoadException:来自程序集 'Microsoft.EntityFrameworkCore.InMemory, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' 的类型 'Microsoft.EntityFrameworkCore.Storage.Internal.InMemoryTransactionManager' 中的方法 'get_CurrentTransaction' 没有实现。
在 Microsoft.Extensions.DependencyInjection.InMemoryServiceCollectionExtensions.AddEntityFrameworkInMemoryDatabase(IServiceCollection 服务)
在 Microsoft.EntityFrameworkCore.Internal.ServiceProviderCache.<>c__DisplayClass4_1.b__2(Int64k)
在 System.Collections.Concurrent.ConcurrentDictionary2.GetOrAdd(TKey key, Func
2 值工厂)
在 Microsoft.EntityFrameworkCore.DbContext..ctor(DbContextOptions 选项)
--- 从抛出异常的先前位置开始的堆栈跟踪结束 ---
在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite,ServiceProvider 提供者)
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite,ServiceProvider 提供商)
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite,ServiceProvider 提供者)
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite,ServiceProvider 提供商)
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite,ServiceProvider 提供者)
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite,ServiceProvider 提供商)
在 Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass16_0.b__0(服务提供商提供商)
在 Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider 提供者,类型 serviceType)
在 Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider 提供者)
在 OpenIddict.OpenIddictProvider4.<ValidateTokenRequest>d__8.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 AspNet.Security.OpenIdConnect.Server.OpenIdConnectServerHandler.<InvokeTokenEndpointAsync>d__17.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 AspNet.Security.OpenIdConnect.Server.OpenIdConnectServerHandler.<HandleRequestAsync>d__2.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.d__18.MoveNext()
--- 从抛出异常的先前位置开始的堆栈跟踪结束 ---
在 Microsoft.AspNetCore.Authentication.AuthenticationMiddleware1.<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.Authentication.AuthenticationMiddleware
1.d__18.MoveNext()
--- 从抛出异常的先前位置开始的堆栈跟踪结束 ---
在 Microsoft.AspNetCore.Authentication.AuthenticationMiddleware`1.d__18.MoveNext()
--- 从抛出异常的先前位置开始的堆栈跟踪结束 ---
在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)
在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)
在 Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.d__6.MoveNext()
Application Insights 遥测(未配置):{"name":"Microsoft.ApplicationInsights.Dev.Request","time":"2017-10-27T14:41:33.6130254Z","tags":{"ai.operation.id":"VBvjL4hwyqs=","ai.user.userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36","ai.internal.sdkVersion":"aspnet5c:1.0.0","ai.operation.name":"POST /api/Authorization","ai.device.roleInstance": "CPD200"},"data":{"baseType":"RequestData","baseData":{"ver":2,"id":"VBvjL4hwyqs=","name":"POST /api/Authorization","startTime":"2017-10-27T14:41:33.6130254+00:00","duration":"00:00:00.4732983" ,"success":false,"responseCode":"404","url":"http://localhost:51863/api/Authorization","httpMethod":"POST","properties" :{"DeveloperMode":"true"}}}}
Microsoft.AspNetCore.Hosting.Internal.WebHost:信息:请求在 490.1896 毫秒内完成 404
代码段中似乎缺少以下身份验证语句
services.AddAuthentication(options =>
{
options.DefaultScheme = OAuthValidationDefaults.AuthenticationScheme;
});
错误消息非常清楚:您使用了错误的 HTTP 方法(可能是 GET,因为我可以看到附加到 URI 的查询字符串参数)。
按照 OAuth2 规范的要求使用 POST,它应该可以工作。
我在尝试在 .net core 1.0.1 上实施简单的令牌身份验证时遇到问题,我遵循了一个我喜欢的简单教程: http://kevinchalet.com/2017/01/30/implementing-simple-token-authentication-in-aspnet-core-with-openiddict/
当我尝试向 http://localhost:51863/connect/token?grant_type=password&username=alice%40wonderland.com&password=P%40ssw0rd 发送请求时,我得到了响应:invalid_request","error_description":"指定的 HTTP 方法无效。
我的startup.cs:
services.AddDbContext<AssistDbContext>(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("AssistContext"));
});
services.AddScoped<AssistDbContext, AssistDbContext>();
services.AddDbContext<DbContext>(options =>
{
// Configure the context to use an in-memory store.
options.UseInMemoryDatabase();
// Register the entity sets needed by OpenIddict.
// Note: use the generic overload if you need
// to replace the default OpenIddict entities.
options.UseOpenIddict();
});
services.AddOpenIddict(options =>
{
// Register the Entity Framework stores.
options.AddEntityFrameworkCoreStores<DbContext>();
// Register the ASP.NET Core MVC binder used by OpenIddict.
// Note: if you don't call this method, you won't be able to
// bind OpenIdConnectRequest or OpenIdConnectResponse parameters.
options.AddMvcBinders();
// Enable the token endpoint.
options.EnableTokenEndpoint("/api/authorization/token");
// Enable the password flow.
options.AllowPasswordFlow();
// During development, you can disable the HTTPS requirement.
options.DisableHttpsRequirement();
});
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseApplicationInsightsRequestTelemetry();
app.UseApplicationInsightsExceptionTelemetry();
// Register the validation middleware, that is used to decrypt
// the access tokens and populate the HttpContext.User property.
app.UseOAuthValidation();
// Register the OpenIddict middleware.
app.UseOpenIddict();
app.UseMvcWithDefaultRoute();
}
更新 用 Postman 测试 returns 404:
日志:
Microsoft.AspNetCore.Hosting.Internal.WebHost:信息:请求开始 HTTP/1.1 POST http://localhost:51863/api/Authorization application/x-www-form-urlencoded 49 'dotnet.exe'(CoreCLR:clrhost):已加载 'C:\Users\consultoria.nuget\packages\AspNet.Security.OpenIdConnect.Extensions.0.2\lib\netstandard1.4\AspNet.Security.OpenIdConnect.Extensions.dll'。跳过加载符号。模块已优化,调试器选项 'Just My Code' 已启用。 'dotnet.exe'(CoreCLR:clrhost):已加载 'C:\Users\consultoria.nuget\packages\Microsoft.AspNetCore.WebUtilities.1.0-preview1-final\lib\netstandard1.3\Microsoft.AspNetCore.WebUtilities.dll'。跳过加载符号。模块已优化,调试器选项 'Just My Code' 已启用。 AspNet.Security.OpenIdConnect.Server.OpenIdConnectServerMiddleware:信息:已成功从 HTTP 请求中提取令牌请求:{ "grant_type": "password", "username": "teste", "password":“[出于安全原因删除]” }. 'dotnet.exe'(CoreCLR:clrhost):已加载 'C:\Users\consultoria.nuget\packages\Microsoft.EntityFrameworkCore.InMemory.0.1\lib\netstandard1.3\Microsoft.EntityFrameworkCore.InMemory.dll'。跳过加载符号。模块已优化,调试器选项 'Just My Code' 已启用。 'dotnet.exe'(CoreCLR:clrhost):已加载 'C:\Users\consultoria.nuget\packages\Remotion.Linq.1.1\lib\netstandard1.0\Remotion.Linq.dll'。跳过加载符号。模块已优化,调试器选项 'Just My Code' 已启用。 'dotnet.exe'(CoreCLR:clrhost):已加载 'C:\Users\consultoria.nuget\packages\System.Interactive.Async.0.0\lib\netstandard1.0\System.Interactive.Async.dll'。跳过加载符号。模块已优化,调试器选项 'Just My Code' 已启用。 'dotnet.exe'(CoreCLR:clrhost):已加载 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App.0.1\System.Diagnostics.StackTrace.dll'。跳过加载符号。模块已优化,调试器选项 'Just My Code' 已启用。 'dotnet.exe'(CoreCLR:clrhost):已加载 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App.0.1\System.Reflection.Metadata.dll'。跳过加载符号。模块已优化,调试器选项 'Just My Code' 已启用。 'dotnet.exe'(CoreCLR:clrhost):已加载 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App.0.1\System.IO.MemoryMappedFiles.dll'。跳过加载符号。模块已优化,调试器选项 'Just My Code' 已启用。 'dotnet.exe'(CoreCLR:clrhost):已加载 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App.0.1\System.IO.UnmanagedMemoryStream.dll'。跳过加载符号。模块已优化,调试器选项 'Just My Code' 已启用。 Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware:错误:发生了未处理的异常:程序集 'Microsoft.EntityFrameworkCore.InMemory, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' 中类型 'Microsoft.EntityFrameworkCore.Storage.Internal.InMemoryTransactionManager' 中的方法 'get_CurrentTransaction' 没有实现。
System.TypeLoadException:来自程序集 'Microsoft.EntityFrameworkCore.InMemory, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' 的类型 'Microsoft.EntityFrameworkCore.Storage.Internal.InMemoryTransactionManager' 中的方法 'get_CurrentTransaction' 没有实现。
在 Microsoft.Extensions.DependencyInjection.InMemoryServiceCollectionExtensions.AddEntityFrameworkInMemoryDatabase(IServiceCollection 服务)
在 Microsoft.EntityFrameworkCore.Internal.ServiceProviderCache.<>c__DisplayClass4_1.b__2(Int64k)
在 System.Collections.Concurrent.ConcurrentDictionary2.GetOrAdd(TKey key, Func
2 值工厂)
在 Microsoft.EntityFrameworkCore.DbContext..ctor(DbContextOptions 选项)
--- 从抛出异常的先前位置开始的堆栈跟踪结束 ---
在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite,ServiceProvider 提供者)
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite,ServiceProvider 提供商)
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite,ServiceProvider 提供者)
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite,ServiceProvider 提供商)
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite,ServiceProvider 提供者)
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite,ServiceProvider 提供商)
在 Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass16_0.b__0(服务提供商提供商)
在 Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider 提供者,类型 serviceType)
在 Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider 提供者)
在 OpenIddict.OpenIddictProvider4.<ValidateTokenRequest>d__8.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 AspNet.Security.OpenIdConnect.Server.OpenIdConnectServerHandler.<InvokeTokenEndpointAsync>d__17.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 AspNet.Security.OpenIdConnect.Server.OpenIdConnectServerHandler.<HandleRequestAsync>d__2.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.d__18.MoveNext()
--- 从抛出异常的先前位置开始的堆栈跟踪结束 ---
在 Microsoft.AspNetCore.Authentication.AuthenticationMiddleware1.<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.Authentication.AuthenticationMiddleware
1.d__18.MoveNext()
--- 从抛出异常的先前位置开始的堆栈跟踪结束 ---
在 Microsoft.AspNetCore.Authentication.AuthenticationMiddleware`1.d__18.MoveNext()
--- 从抛出异常的先前位置开始的堆栈跟踪结束 ---
在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)
在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)
在 Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.d__6.MoveNext()
Application Insights 遥测(未配置):{"name":"Microsoft.ApplicationInsights.Dev.Request","time":"2017-10-27T14:41:33.6130254Z","tags":{"ai.operation.id":"VBvjL4hwyqs=","ai.user.userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36","ai.internal.sdkVersion":"aspnet5c:1.0.0","ai.operation.name":"POST /api/Authorization","ai.device.roleInstance": "CPD200"},"data":{"baseType":"RequestData","baseData":{"ver":2,"id":"VBvjL4hwyqs=","name":"POST /api/Authorization","startTime":"2017-10-27T14:41:33.6130254+00:00","duration":"00:00:00.4732983" ,"success":false,"responseCode":"404","url":"http://localhost:51863/api/Authorization","httpMethod":"POST","properties" :{"DeveloperMode":"true"}}}}
Microsoft.AspNetCore.Hosting.Internal.WebHost:信息:请求在 490.1896 毫秒内完成 404
代码段中似乎缺少以下身份验证语句
services.AddAuthentication(options =>
{
options.DefaultScheme = OAuthValidationDefaults.AuthenticationScheme;
});
错误消息非常清楚:您使用了错误的 HTTP 方法(可能是 GET,因为我可以看到附加到 URI 的查询字符串参数)。
按照 OAuth2 规范的要求使用 POST,它应该可以工作。