OpenIddictHandler 第一次后不处理 HTTP 请求
OpenIddictHandler not handle HTTP request after first time
我对 OpenIdDict 身份验证服务器有一些问题。我为密码流设置它,我也使用自定义实体进行授权和令牌实体。当我第一次尝试登录令牌端点时,在我的应用程序启动后它工作正常。在调试日志中我看到这条消息。
[2019.03.20 09:35:58] [40m[32minfo[39m[22m[49m: WebHost[1] Request starting HTTP/1.1 POST http://localhost:32791/api/v1/oauth/token application/x-www-form-urlencoded 152
Loaded '/root/.nuget/packages/aspnet.security.openidconnect.extensions/2.0.0-rc1-final/lib/netstandard2.0/AspNet.Security.OpenIdConnect.Extensions.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
[2019.03.20 09:35:59] [40m[32minfo[39m[22m[49m: OpenIddictHandler The token request was successfully extracted from the HTTP request: {
"username": "oleg@gmail.com",
"password": "[removed for security reasons]",
"BusinessType": "HairSalon",
"TimeZone": "PacificPagoPago",
"Currency": "AED",
"Country": "ABW",
"grant_type": "password",
"SignUp": "false"
}.
[2019.03.20 09:35:59] [40m[37mdbug[39m[22m[49m: OpenIddictProvider The token request validation process was partially skipped because the 'client_id' parameter was missing or empty.
[2019.03.20 09:35:59] [40m[32minfo[39m[22m[49m: OpenIddictHandler The token request was successfully validated.
[2019.03.20 09:35:59] [40m[37mdbug[39m[22m[49m: OpenIddictHandler The default token request handling was skipped from user code.
[2019.03.20 09:35:59] [40m[32minfo[39m[22m[49m: ControllerActionInvoker[1] Executing action method MyProject.Controllers.OAuthTokenController.Post (MyProject) with arguments (MyProject.Models.UserModel) - ModelState is Valid
...
但是所有其他未来请求(在重新启动项目之前)都会抛出 InvalidOperationException:InvalidOperationException:无法从此端点返回授权或令牌响应。
找到此错误的描述后,我再次看到调试输出日志,发现除第一个请求外,所有请求中都没有来自 OpenIddictHandler 的消息。调试输出为:
[2019.03.20 09:36:24] [40m[32minfo[39m[22m[49m: WebHost[1] Request starting HTTP/1.1 POST http://localhost:32791/api/v1/oauth/token application/x-www-form-urlencoded 151
[2019.03.20 09:36:24] [40m[32minfo[39m[22m[49m: ObjectResultExecutor[1] Executing ObjectResult, writing value Microsoft.AspNetCore.Mvc.ControllerContext.
[2019.03.20 09:36:24] [40m[32minfo[39m[22m[49m: ControllerActionInvoker[1] Executing action method MyProject.Controllers.OAuthTokenController.Post (MyProject) with arguments (MyProject.Models.UserModel) - ModelState is Valid
[2019.03.20 09:36:27] [40m[32minfo[39m[22m[49m: Infrastructure[10403] Entity Framework Core 2.2.0-rtm-35687 initialized 'MyDbContext' using provider 'Pomelo.EntityFrameworkCore.MySql' with options: None
[2019.03.20 09:36:27] [40m[32minfo[39m[22m[49m: ControllerActionInvoker[2] Executed action MyProject.Controllers.OAuthTokenController.Post (MyProject) in 28329.7586ms
[2019.03.20 09:36:27] [40m[32minfo[39m[22m[49m: WebHost[2] Request finished in 28835.2212ms 400 application/json; charset=utf-8
[2019.03.20 09:36:27] [40m[32minfo[39m[22m[49m: Command[20101] Executed DbCommand (13ms) [Parameters=[@__normalizedUserName_0='?' (Size = 256)], CommandType='Text', CommandTimeout='30']
SELECT `u`.`Id`, `u`.`ConfirmationToken`, `u`.`CreatedAt`, `u`.`Email`, `u`.`FirstName`, `u`.`LastName`, `u`.`Login`, `u`.`Mobile`, `u`.`NormalizedLogin`, `u`.`Password`, `u`.`RoleId`, `u`.`SecurityStamp`, `u`.`TokenSecurityStamp`, `u`.`UpdatedAt`
FROM `Users` AS `u`
WHERE `u`.`NormalizedLogin` = @__normalizedUserName_0
LIMIT 1
[2019.03.20 09:36:27] [40m[32minfo[39m[22m[49m: Command[20101] Executed DbCommand (21ms) [Parameters=[@__normalizedUserName_0='?' (Size = 256)], CommandType='Text', CommandTimeout='30']
SELECT `u`.`Id`, `u`.`ConfirmationToken`, `u`.`CreatedAt`, `u`.`Email`, `u`.`FirstName`, `u`.`LastName`, `u`.`Login`, `u`.`Mobile`, `u`.`NormalizedLogin`, `u`.`Password`, `u`.`RoleId`, `u`.`SecurityStamp`, `u`.`TokenSecurityStamp`, `u`.`UpdatedAt`
FROM `Users` AS `u`
WHERE `u`.`NormalizedLogin` = @__normalizedUserName_0
LIMIT 1
[2019.03.20 09:36:27] [40m[32minfo[39m[22m[49m: Command[20101] Executed DbCommand (70ms) [Parameters=[@__user_RoleId_0='?' (DbType = Guid)], CommandType='Text', CommandTimeout='30']
SELECT `r`.`Name`
FROM `Roles` AS `r`
WHERE `r`.`Id` = @__user_RoleId_0
[2019.03.20 09:36:32] [40m[32minfo[39m[22m[49m: SignInResult[1] Executing SignInResult with authentication scheme (ASOS) and the following principal: System.Security.Claims.ClaimsPrincipal.
[2019.03.20 09:36:32] [40m[32minfo[39m[22m[49m: ControllerActionInvoker[2] Executed action MyProject.Controllers.OAuthTokenController.Post (MyProject) in 8564.2121ms
Loaded '/usr/share/dotnet/shared/Microsoft.NETCore.App/2.0.9/System.Diagnostics.StackTrace.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Loaded '/usr/share/dotnet/shared/Microsoft.NETCore.App/2.0.9/System.Reflection.Metadata.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
[2019.03.20 09:36:32] [41m[30mfail[39m[22m[49m: DeveloperExceptionPageMiddleware An unhandled exception has occurred while executing the request
System.InvalidOperationException: An authorization or token response cannot be returned from this endpoint.
...
如您所见,没有关于 OpenIddictHandler 的消息。我不知道为什么会这样,非常感谢您的帮助。
这是我的 OpenIdDict 配置。
services.Configure<IdentityOptions>(options =>
{
options.ClaimsIdentity.UserNameClaimType = OpenIdConnectConstants.Claims.Name;
options.ClaimsIdentity.UserIdClaimType = OpenIdConnectConstants.Claims.Subject;
options.ClaimsIdentity.RoleClaimType = OpenIdConnectConstants.Claims.Role;
});
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(settings.TokenSigningKey));
services.AddOpenIddict<OpenIddictApplication, Authorization, OpenIddictScope, Token>(options =>
{
options.AddAuthorizationStore<OpenIddictAuthorizationStore>();
options.AddTokenStore<OpenIddictTokenStore>();
options.AddApplicationStore<OpenIddictApplicationStore<MyDbContext>>();
options.AddScopeStore<OpenIddictScopeStore<MyDbContext>>();
options.AddMvcBinders();
options.EnableTokenEndpoint("/api/v1/oauth/token");
options.AllowPasswordFlow();
options.AllowRefreshTokenFlow();
options.UseJsonWebTokens();
options.AddSigningKey(signingKey);
options.SetAccessTokenLifetime(settings.AccessTokenLifetime);
options.SetRefreshTokenLifetime(settings.RefreshTokenLifetime);
if (!settings.EnableTokenAuthHttpsRequirement)
{
options.DisableHttpsRequirement();
}
});
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = settings.JwtAuthority;
options.Audience = settings.JwtAudience;
options.MetadataAddress = settings.JwtMetadataAddress;
options.RequireHttpsMetadata = settings.EnableTokenAuthHttpsRequirement;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
ValidIssuers = settings.JwtIssuers,
NameClaimType = OpenIdConnectConstants.Claims.Subject,
RoleClaimType = OpenIdConnectConstants.Claims.Role
};
options.IncludeErrorDetails = hostingEnvironment.IsDevelopment();
});
services.AddScoped<IOpenIddictAuthorizationStore<Authorization>, OpenIddictAuthorizationStore>();
services.AddScoped<IOpenIddictTokenStore<Token>, OpenIddictTokenStore>();
非常感谢!
我发现错误,我的错。我在 app.UseAuthentication() 之前注册了 app.UseMvc();在 Startup.cs 等 OpenIdDict 中间件在 Mvc 操作之后调用。
我对 OpenIdDict 身份验证服务器有一些问题。我为密码流设置它,我也使用自定义实体进行授权和令牌实体。当我第一次尝试登录令牌端点时,在我的应用程序启动后它工作正常。在调试日志中我看到这条消息。
[2019.03.20 09:35:58] [40m[32minfo[39m[22m[49m: WebHost[1] Request starting HTTP/1.1 POST http://localhost:32791/api/v1/oauth/token application/x-www-form-urlencoded 152
Loaded '/root/.nuget/packages/aspnet.security.openidconnect.extensions/2.0.0-rc1-final/lib/netstandard2.0/AspNet.Security.OpenIdConnect.Extensions.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
[2019.03.20 09:35:59] [40m[32minfo[39m[22m[49m: OpenIddictHandler The token request was successfully extracted from the HTTP request: {
"username": "oleg@gmail.com",
"password": "[removed for security reasons]",
"BusinessType": "HairSalon",
"TimeZone": "PacificPagoPago",
"Currency": "AED",
"Country": "ABW",
"grant_type": "password",
"SignUp": "false"
}.
[2019.03.20 09:35:59] [40m[37mdbug[39m[22m[49m: OpenIddictProvider The token request validation process was partially skipped because the 'client_id' parameter was missing or empty.
[2019.03.20 09:35:59] [40m[32minfo[39m[22m[49m: OpenIddictHandler The token request was successfully validated.
[2019.03.20 09:35:59] [40m[37mdbug[39m[22m[49m: OpenIddictHandler The default token request handling was skipped from user code.
[2019.03.20 09:35:59] [40m[32minfo[39m[22m[49m: ControllerActionInvoker[1] Executing action method MyProject.Controllers.OAuthTokenController.Post (MyProject) with arguments (MyProject.Models.UserModel) - ModelState is Valid
...
但是所有其他未来请求(在重新启动项目之前)都会抛出 InvalidOperationException:InvalidOperationException:无法从此端点返回授权或令牌响应。 找到此错误的描述后,我再次看到调试输出日志,发现除第一个请求外,所有请求中都没有来自 OpenIddictHandler 的消息。调试输出为:
[2019.03.20 09:36:24] [40m[32minfo[39m[22m[49m: WebHost[1] Request starting HTTP/1.1 POST http://localhost:32791/api/v1/oauth/token application/x-www-form-urlencoded 151
[2019.03.20 09:36:24] [40m[32minfo[39m[22m[49m: ObjectResultExecutor[1] Executing ObjectResult, writing value Microsoft.AspNetCore.Mvc.ControllerContext.
[2019.03.20 09:36:24] [40m[32minfo[39m[22m[49m: ControllerActionInvoker[1] Executing action method MyProject.Controllers.OAuthTokenController.Post (MyProject) with arguments (MyProject.Models.UserModel) - ModelState is Valid
[2019.03.20 09:36:27] [40m[32minfo[39m[22m[49m: Infrastructure[10403] Entity Framework Core 2.2.0-rtm-35687 initialized 'MyDbContext' using provider 'Pomelo.EntityFrameworkCore.MySql' with options: None
[2019.03.20 09:36:27] [40m[32minfo[39m[22m[49m: ControllerActionInvoker[2] Executed action MyProject.Controllers.OAuthTokenController.Post (MyProject) in 28329.7586ms
[2019.03.20 09:36:27] [40m[32minfo[39m[22m[49m: WebHost[2] Request finished in 28835.2212ms 400 application/json; charset=utf-8
[2019.03.20 09:36:27] [40m[32minfo[39m[22m[49m: Command[20101] Executed DbCommand (13ms) [Parameters=[@__normalizedUserName_0='?' (Size = 256)], CommandType='Text', CommandTimeout='30']
SELECT `u`.`Id`, `u`.`ConfirmationToken`, `u`.`CreatedAt`, `u`.`Email`, `u`.`FirstName`, `u`.`LastName`, `u`.`Login`, `u`.`Mobile`, `u`.`NormalizedLogin`, `u`.`Password`, `u`.`RoleId`, `u`.`SecurityStamp`, `u`.`TokenSecurityStamp`, `u`.`UpdatedAt`
FROM `Users` AS `u`
WHERE `u`.`NormalizedLogin` = @__normalizedUserName_0
LIMIT 1
[2019.03.20 09:36:27] [40m[32minfo[39m[22m[49m: Command[20101] Executed DbCommand (21ms) [Parameters=[@__normalizedUserName_0='?' (Size = 256)], CommandType='Text', CommandTimeout='30']
SELECT `u`.`Id`, `u`.`ConfirmationToken`, `u`.`CreatedAt`, `u`.`Email`, `u`.`FirstName`, `u`.`LastName`, `u`.`Login`, `u`.`Mobile`, `u`.`NormalizedLogin`, `u`.`Password`, `u`.`RoleId`, `u`.`SecurityStamp`, `u`.`TokenSecurityStamp`, `u`.`UpdatedAt`
FROM `Users` AS `u`
WHERE `u`.`NormalizedLogin` = @__normalizedUserName_0
LIMIT 1
[2019.03.20 09:36:27] [40m[32minfo[39m[22m[49m: Command[20101] Executed DbCommand (70ms) [Parameters=[@__user_RoleId_0='?' (DbType = Guid)], CommandType='Text', CommandTimeout='30']
SELECT `r`.`Name`
FROM `Roles` AS `r`
WHERE `r`.`Id` = @__user_RoleId_0
[2019.03.20 09:36:32] [40m[32minfo[39m[22m[49m: SignInResult[1] Executing SignInResult with authentication scheme (ASOS) and the following principal: System.Security.Claims.ClaimsPrincipal.
[2019.03.20 09:36:32] [40m[32minfo[39m[22m[49m: ControllerActionInvoker[2] Executed action MyProject.Controllers.OAuthTokenController.Post (MyProject) in 8564.2121ms
Loaded '/usr/share/dotnet/shared/Microsoft.NETCore.App/2.0.9/System.Diagnostics.StackTrace.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Loaded '/usr/share/dotnet/shared/Microsoft.NETCore.App/2.0.9/System.Reflection.Metadata.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
[2019.03.20 09:36:32] [41m[30mfail[39m[22m[49m: DeveloperExceptionPageMiddleware An unhandled exception has occurred while executing the request
System.InvalidOperationException: An authorization or token response cannot be returned from this endpoint.
...
如您所见,没有关于 OpenIddictHandler 的消息。我不知道为什么会这样,非常感谢您的帮助。
这是我的 OpenIdDict 配置。
services.Configure<IdentityOptions>(options =>
{
options.ClaimsIdentity.UserNameClaimType = OpenIdConnectConstants.Claims.Name;
options.ClaimsIdentity.UserIdClaimType = OpenIdConnectConstants.Claims.Subject;
options.ClaimsIdentity.RoleClaimType = OpenIdConnectConstants.Claims.Role;
});
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(settings.TokenSigningKey));
services.AddOpenIddict<OpenIddictApplication, Authorization, OpenIddictScope, Token>(options =>
{
options.AddAuthorizationStore<OpenIddictAuthorizationStore>();
options.AddTokenStore<OpenIddictTokenStore>();
options.AddApplicationStore<OpenIddictApplicationStore<MyDbContext>>();
options.AddScopeStore<OpenIddictScopeStore<MyDbContext>>();
options.AddMvcBinders();
options.EnableTokenEndpoint("/api/v1/oauth/token");
options.AllowPasswordFlow();
options.AllowRefreshTokenFlow();
options.UseJsonWebTokens();
options.AddSigningKey(signingKey);
options.SetAccessTokenLifetime(settings.AccessTokenLifetime);
options.SetRefreshTokenLifetime(settings.RefreshTokenLifetime);
if (!settings.EnableTokenAuthHttpsRequirement)
{
options.DisableHttpsRequirement();
}
});
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = settings.JwtAuthority;
options.Audience = settings.JwtAudience;
options.MetadataAddress = settings.JwtMetadataAddress;
options.RequireHttpsMetadata = settings.EnableTokenAuthHttpsRequirement;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
ValidIssuers = settings.JwtIssuers,
NameClaimType = OpenIdConnectConstants.Claims.Subject,
RoleClaimType = OpenIdConnectConstants.Claims.Role
};
options.IncludeErrorDetails = hostingEnvironment.IsDevelopment();
});
services.AddScoped<IOpenIddictAuthorizationStore<Authorization>, OpenIddictAuthorizationStore>();
services.AddScoped<IOpenIddictTokenStore<Token>, OpenIddictTokenStore>();
非常感谢!
我发现错误,我的错。我在 app.UseAuthentication() 之前注册了 app.UseMvc();在 Startup.cs 等 OpenIdDict 中间件在 Mvc 操作之后调用。