首页 > 解决方案 > 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:我搜索了几天没有成功!

标签: .net-coreidentityserver4blazor

解决方案


推荐阅读