.net-core - IdentityServer4 + Blazor
问题描述
我正在尝试构建一个小型微服务架构: - IdentityServer 4 服务 - 应用 API 服务 - Web 应用程序,作为另一项服务
我的客户端代码主要受@McGuireV10 代码启发: https ://mcguirev10.com/2019/12/15/blazor-authentication-with-openid-connect.html
问题是我遇到了问题,找不到解决方法:
System.Security.Cryptography.CryptographicException: 'The payload was invalid.'
使用此堆栈跟踪:
Microsoft.AspNetCore.DataProtection.dll!Microsoft.AspNetCore.DataProtection.Cng.CbcAuthenticatedEncryptor.DecryptImpl(byte* pbCiphertext, uint cbCiphertext, byte* pbAdditionalAuthenticatedData, uint cbAdditionalAuthenticatedData) Unknown
Microsoft.AspNetCore.DataProtection.dll!Microsoft.AspNetCore.DataProtection.Cng.Internal.CngAuthenticatedEncryptorBase.Decrypt(System.ArraySegment<byte> ciphertext, System.ArraySegment<byte> additionalAuthenticatedData) Unknown
Microsoft.AspNetCore.DataProtection.dll!Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(byte[] protectedData, bool allowOperationsOnRevokedKeys, out Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectStatus status) Unknown
Microsoft.AspNetCore.DataProtection.dll!Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.DangerousUnprotect(byte[] protectedData, bool ignoreRevocationErrors, out bool requiresMigration, out bool wasRevoked) Unknown
Microsoft.AspNetCore.DataProtection.dll!Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(byte[] protectedData) Unknown
Microsoft.AspNetCore.Authentication.dll!Microsoft.AspNetCore.Authentication.SecureDataFormat<Microsoft.AspNetCore.Authentication.AuthenticationTicket>.Unprotect(string protectedText, string purpose) Unknown
Microsoft.AspNetCore.Authentication.Cookies.dll!Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler.ReadCookieTicket() Unknown
Microsoft.AspNetCore.Authentication.Cookies.dll!Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler.HandleAuthenticateAsync() Unknown
Microsoft.AspNetCore.Authentication.dll!Microsoft.AspNetCore.Authentication.AuthenticationHandler<Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions>.AuthenticateAsync() Unknown
Microsoft.AspNetCore.Authentication.Core.dll!Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(Microsoft.AspNetCore.Http.HttpContext context, string scheme) Unknown
Microsoft.AspNetCore.Authentication.Abstractions.dll!Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions.AuthenticateAsync(Microsoft.AspNetCore.Http.HttpContext context, string scheme) Unknown
Microsoft.AspNetCore.Authentication.dll!Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext context) Unknown
Microsoft.AspNetCore.Routing.dll!Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.SetRoutingAndContinue(Microsoft.AspNetCore.Http.HttpContext httpContext) Unknown
Microsoft.AspNetCore.Routing.dll!Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext httpContext) Unknown
Microsoft.AspNetCore.StaticFiles.dll!Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext context) Unknown
Microsoft.AspNetCore.StaticFiles.dll!Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext context) Unknown
Microsoft.AspNetCore.StaticFiles.dll!Microsoft.AspNetCore.StaticFiles.DefaultFilesMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext context) Unknown
Microsoft.AspNetCore.HttpsPolicy.dll!Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext context) Unknown
Microsoft.AspNetCore.Diagnostics.dll!Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext context) Unknown
Volo.Abp.AspNetCore.dll!Volo.Abp.AspNetCore.Tracing.AbpCorrelationIdMiddleware.InvokeAsync(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Http.RequestDelegate next) Unknown
Microsoft.AspNetCore.Http.Abstractions.dll!Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.UseMiddlewareInterface.AnonymousMethod__1(Microsoft.AspNetCore.Http.HttpContext context) Unknown
Microsoft.AspNetCore.HostFiltering.dll!Microsoft.AspNetCore.HostFiltering.HostFilteringMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext context) Unknown
Microsoft.AspNetCore.Hosting.dll!Microsoft.AspNetCore.Hosting.HostingApplication.ProcessRequestAsync(Microsoft.AspNetCore.Hosting.HostingApplication.Context context) Unknown
Microsoft.AspNetCore.Server.IIS.dll!Microsoft.AspNetCore.Server.IIS.Core.IISHttpContextOfT<Microsoft.AspNetCore.Hosting.HostingApplication.Context>.ProcessRequestAsync() Unknown
Microsoft.AspNetCore.Server.IIS.dll!Microsoft.AspNetCore.Server.IIS.Core.IISHttpContext.HandleRequest() Unknown
Microsoft.AspNetCore.Server.IIS.dll!Microsoft.AspNetCore.Server.IIS.Core.IISHttpContext.Execute() Unknown
这是应用程序服务的概述。
因此,一方面,我使用以下启动代码启动了身份服务器:
context.Services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies", options =>
{
options.ExpireTimeSpan = TimeSpan.FromDays(365);
})
.AddOpenIdConnect("oidc", options =>
{
options.Authority = configuration["App:SelfUrl"];//configuration["AuthServer:Authority"];
options.RequireHttpsMetadata = true;
options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
options.ClientId = configuration["AuthServer:ClientId"];
options.ClientSecret = configuration["AuthServer:ClientSecret"];
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("role");
options.Scope.Add("email");
options.Scope.Add("phone");
options.Scope.Add("ProductFly");
options.ClaimActions.MapAbpClaimTypes();
options.Events = new Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectEvents
{
// called if user clicks Cancel during login
OnAccessDenied = context =>
{
context.HandleResponse();
context.Response.Redirect("/");
return System.Threading.Tasks.Task.CompletedTask;
}
};
});
然后,web 应用启动代码:
context.Services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies", options =>
{
options.ExpireTimeSpan = TimeSpan.FromDays(365);
})
.AddOpenIdConnect("oidc", options =>
{
options.Authority = configuration["AuthServer:Authority"];
options.RequireHttpsMetadata = true;
options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
options.ClientId = configuration["AuthServer:ClientId"];
options.ClientSecret = configuration["AuthServer:ClientSecret"];
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("role");
options.Scope.Add("email");
options.Scope.Add("phone");
options.Scope.Add("ProductFly");
options.ClaimActions.MapAbpClaimTypes();
options.Events = new Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectEvents
{
// called if user clicks Cancel during login
OnAccessDenied = context =>
{
context.HandleResponse();
context.Response.Redirect("/");
return System.Threading.Tasks.Task.CompletedTask;
}
};
});
另外,注意到我有自己的登录页面,我用它来保存我的主体:
SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authProperties);
这是 IdentityServer 设置代码:
私有静态无效 AddIdentityServer(IServiceCollection 服务) { var configuration = services.GetConfiguration(); var builderOptions = services.ExecutePreConfiguredActions();
var identityServerBuilder = services.AddIdentityServer(options =>
{
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = true;
});
if (builderOptions.AddDeveloperSigningCredential)
{
identityServerBuilder = identityServerBuilder.AddDeveloperSigningCredential();
}
identityServerBuilder.AddInMemoryClients(configuration.GetSection("IdentityServer:Clients"));
services.ExecutePreConfiguredActions(identityServerBuilder);
if (!services.IsAdded<IPersistedGrantService>())
{
identityServerBuilder.AddInMemoryPersistedGrants();
}
if (!services.IsAdded<IClientStore>())
{
identityServerBuilder.AddInMemoryClients(configuration.GetSection("IdentityServer:Clients"));
}
if (!services.IsAdded<IResourceStore>())
{
identityServerBuilder.AddInMemoryApiResources(configuration.GetSection("IdentityServer:ApiResources"));
identityServerBuilder.AddInMemoryIdentityResources(configuration.GetSection("IdentityServer:IdentityResources"));
}
}
它使用以下记录进行设置:
"GrantType":"client_credentials" "ClientId":"Product_App" "ClientName":"Product_App" "Description":"Product_App" "ClientUri":null, "LogoUri":null, "Enabled":true, "ProtocolType": “oidc”、“RequireClientSecret”:真、“RequireConsent”:假、“AllowRememberConsent”:真、“AlwaysIncludeUserClaimsInIdToken”:真、“RequirePkce”:假、“AllowPlainTextPkce”:假、“AllowAccessTokensViaBrowser”:假、“FrontChannelLogoutUri”:空,“FrontChannelLogoutSessionRequired”:真,“BackChannelLogoutUri”:空,“BackChannelLogoutSessionRequired”:真,“AllowOfflineAccess”:真,“IdentityTokenLifetime":{"$numberInt":"300"}, "AccessTokenLifetime":{"$numberInt":"31536000"}, "AuthorizationCodeLifetime":{"$numberInt":"300"}, "ConsentLifetime":null, "AbsoluteRefreshTokenLifetime":{"$numberInt":"31536000"}, "SlidingRefreshTokenLifetime":{"$numberInt":"1296000"}, "RefreshTokenUsage":{"$numberInt":"1"}, "UpdateAccessTokenClaimsOnRefresh":false , "RefreshTokenExpiration":{"$numberInt":"1"}, "AccessTokenType":{"$numberInt":"0"}, "EnableLocalLogin":true, "IncludeJwtId":false, "AlwaysSendClientClaims":false, "ClientClaimsPrefix":"client_", "PairWiseSubjectSalt":null, "UserSsoLifetime":null, "UserCodeType":null, "DeviceCodeLifetime":{"$numberInt":"300"},
有人有解决这个问题的想法吗?或者至少要调试它?
PS:我搜索了几天没有成功!
解决方案
推荐阅读
- javascript - 打开一个新窗口并关闭另一个
- python - 在特定时间内完成画圆
- python - Python:更新字典的语法
- html - 调整窗口大小时Div消失
- magento2 - 如何覆盖 module-catalog-search/view/frontend/templates/searchlist.phtml
- react-native - React Native Navigation Wix V2 顶部栏按钮操作
- facebook - 在 html 中预先创建一个 facebook 帖子并提交
- python - 在哪里保存长硬编码数据以在 Django 中进行初始迁移?
- python - SUMO 和 TraCI,多个客户端 - 一个连接
- javascript - Vue js在编译时正在删除脚本标签