【问题标题】:.NET Core Openiddict invalid request.NET Core Openiddict 无效请求
【发布时间】:2018-04-07 23:49:25
【问题描述】:

我在尝试在 .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 进行测试返回 404:

日志:

Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: 请求开始 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\1.0.2\lib\netstandard1.4\AspNet.Security.OpenIdConnect.Extensions。 dll'。跳过加载符号。模块已优化,调试器选项“仅我的代码”已启用。 'dotnet.exe' (CoreCLR: clrhost): 加载'C:\Users\consultoria.nuget\packages\Microsoft.AspNetCore.WebUtilities\1.1.0-preview1-final\lib\netstandard1.3\Microsoft.AspNetCore.WebUtilities。 dll'。跳过加载符号。模块已优化,调试器选项“仅我的代码”已启用。 AspNet.Security.OpenIdConnect.Server.OpenIdConnectServerMiddleware:信息:已成功从 HTTP 请求中提取令牌请求:{ "grant_type": "密码", "用户名": "teste", "password": "[出于安全原因删除]" }。 “dotnet.exe”(CoreCLR:clrhost):已加载“C:\Users\consultoria.nuget\packages\Microsoft.EntityFrameworkCore.InMemory\1.0.1\lib\netstandard1.3\Microsoft.EntityFrameworkCore.InMemory.dll”。跳过加载符号。模块已优化,调试器选项“仅我的代码”已启用。 “dotnet.exe”(CoreCLR:clrhost):已加载“C:\Users\consultoria.nuget\packages\Remotion.Linq\2.1.1\lib\netstandard1.0\Remotion.Linq.dll”。跳过加载符号。模块已优化,调试器选项“仅我的代码”已启用。 “dotnet.exe”(CoreCLR:clrhost):已加载“C:\Users\consultoria.nuget\packages\System.Interactive.Async\3.0.0\lib\netstandard1.0\System.Interactive.Async.dll”。跳过加载符号。模块已优化,调试器选项“仅我的代码”已启用。 “dotnet.exe”(CoreCLR:clrhost):已加载“C:\Program Files\dotnet\shared\Microsoft.NETCore.App\1.0.1\System.Diagnostics.StackTrace.dll”。跳过加载符号。模块已优化,调试器选项“仅我的代码”已启用。 “dotnet.exe”(CoreCLR:clrhost):已加载“C:\Program Files\dotnet\shared\Microsoft.NETCore.App\1.0.1\System.Reflection.Metadata.dll”。跳过加载符号。模块已优化,调试器选项“仅我的代码”已启用。 “dotnet.exe”(CoreCLR:clrhost):已加载“C:\Program Files\dotnet\shared\Microsoft.NETCore.App\1.0.1\System.IO.MemoryMappedFiles.dll”。跳过加载符号。模块已优化,调试器选项“仅我的代码”已启用。 “dotnet.exe”(CoreCLR:clrhost):已加载“C:\Program Files\dotnet\shared\Microsoft.NETCore.App\1.0.1\System.IO.UnmanagedMemoryStream.dll”。跳过加载符号。模块已优化,调试器选项“仅我的代码”已启用。 Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware:错误:发生了未处理的异常:来自程序集“Microsoft.EntityFrameworkCore.Storage.Internal.InMemoryTransactionManager”的方法“get_CurrentTransaction”来自程序集“Microsoft.EntityFrameworkCore.InMemory,版本=1.0.1.0,Culture=中性,PublicKeyToken=adb9793829ddae60' 没有实现。

System.TypeLoadException:来自程序集“Microsoft.EntityFrameworkCore.InMemory,版本=1.0.1.0,文化=中性,PublicKeyToken=adb9793829ddae60”的“Microsoft.EntityFrameworkCore.Storage.Internal.InMemoryTransactionManager”类型中的方法“get_CurrentTransaction”没有一个实现。 在 Microsoft.Extensions.DependencyInjection.InMemoryServiceCollectionExtensions.AddEntityFrameworkInMemoryDatabase(IServiceCollection 服务) 在 Microsoft.EntityFrameworkCore.Internal.ServiceProviderCache.c__DisplayClass4_1.b__2(Int64 k) 在 System.Collections.Concurrent.ConcurrentDictionary2.GetOrAdd(TKey key, Func2 valueFactory) 在 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(ServiceProvider 提供程序) 在 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.AuthenticationMiddleware1.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.AuthenticationMiddleware1.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, 像 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" ,"属性":{"DeveloperMode":"true"}}}} Microsoft.AspNetCore.Hosting.Internal.WebHost:信息:请求在 490.1896 毫秒内完成 404

【问题讨论】:

    标签: .net-core asp.net-core-webapi bearer-token openiddict


    【解决方案1】:

    看起来代码 sn-p 中缺少以下身份验证语句

    services.AddAuthentication(options =>
    {
        options.DefaultScheme = OAuthValidationDefaults.AuthenticationScheme;
    });
    

    【讨论】:

    • 其实就是.NET Core 2.x,我用的是1.0.1
    【解决方案2】:

    错误信息非常清楚:您使用了错误的 HTTP 方法(可能是 GET,因为我可以看到附加到 URI 的查询字符串参数)。

    按照 OAuth2 规范的要求使用 POST,它应该可以工作。

    【讨论】:

    • 我现在使用 POST 并使用 Postman 进行测试,他返回 404,由于某种原因我无法访问 AuthorizationController 上的 Exchange 功能
    • 您确定与 Exchange 操作关联的路由有效吗?
    • 应该是,我使用 [Route("api/[controller]")] 进行映射,就像我的 API 的其余部分一样
    • 和我的方法“[HttpPost] public IActionResult Token(OpenIdConnectRequest request)”(我更改交换令牌)
    • 这很可能是 MVC 路由问题。尝试使用[Route("api/[controller]/[action]")] 或使用[HttpPost("Token")] 装饰您的Token 操作。您还可以选择与根相关的路由:[HttpPost("~/api/authorization/token")]
    猜你喜欢
    • 2018-03-24
    • 2017-03-25
    • 2020-11-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-27
    • 2017-09-17
    • 2021-08-19
    • 2022-09-30
    相关资源
    最近更新 更多