/ signin-oidc多个客户端实例上的404(数据保护问题)

问题描述 投票:0回答:1

问题

我正在使用.NET Framework 4.7.2 MVC应用程序,它始终位于负载平衡器的后面,并且除非添加第二个MVC App实例,否则效果很好。

IdentityServer4本身正在使用数据保护,但是非核心客户端遇到此问题。

我找不到.NET框架的等效数据保护。有没有,或者我看到不同的东西?

如果我从负载均衡器中删除一个实例,它将再次起作用。

最小工作示例

app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = CookieAuthenticationDefaults.AuthenticationType, SlidingExpiration = true }); app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions { ClientId = clientId, Authority = identityServerUrl, //Get this dynamically, register all possible values in IDS. //https://github.com/IdentityServer/IdentityServer3/issues/1458 RedirectUri = redirectUrl, PostLogoutRedirectUri = postLogoutRedirectUrl, ResponseType = "code id_token", Scope = scope, SaveTokens = true, TokenValidationParameters = new TokenValidationParameters { NameClaimType = "name", RoleClaimType = "role" }, RequireHttpsMetadata = false, SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType, UseTokenLifetime = false, AuthenticationType = "OIDC", Notifications = new OpenIdConnectAuthenticationNotifications { SecurityTokenValidated = async tokenValidatedNotification => { try { logger.LogTrace("Entering AuthorizationCodeReceived {authTicketIdentity} {response}", tokenValidatedNotification.AuthenticationTicket.Identity, tokenValidatedNotification.Response.StatusCode); var claimsToKeep = tokenValidatedNotification.AuthenticationTicket.Identity.Claims.ToList(); claimsToKeep.Add(new Claim("id_token", tokenValidatedNotification.ProtocolMessage.IdToken)); // use the code to get the access and refresh token #pragma warning disable CS0618 // Type or member is obsolete var tokenClient = new TokenClient($"{identityServerUrl}/connect/token", clientId, clientSecret); #pragma warning restore CS0618 // Type or member is obsolete TokenResponse tokenResponse = await tokenClient.RequestAuthorizationCodeAsync( tokenValidatedNotification.ProtocolMessage.Code, redirectUrl); if (tokenResponse.IsError) { throw new Exception($"Error authorizing user {tokenResponse.Error}, {tokenResponse.ErrorDescription}", tokenResponse.Exception); } // use the access token to retrieve claims from userinfo #pragma warning disable CS0618 // Type or member is obsolete var userInfoClient = new UserInfoClient($"{identityServerUrl}/connect/userinfo"); #pragma warning restore CS0618 // Type or member is obsolete UserInfoResponse userInfoResponse = await userInfoClient.GetAsync(tokenResponse.AccessToken) .ConfigureAwait(false); if (userInfoResponse.IsError) { throw new Exception(userInfoResponse.Error, userInfoResponse.Exception); } claimsToKeep.AddRange(userInfoResponse.Claims); // create new identity var claimsIdentity = new ClaimsIdentity(tokenValidatedNotification.AuthenticationTicket .Identity .AuthenticationType, "name", "role"); claimsIdentity.AddClaims(userInfoResponse.Claims); claimsIdentity.AddClaims(claimsToKeep); var user = claimsIdentity.Claims.FirstOrDefault(x => x.Type == "sub"); if (user != null && user.Value.Contains('@')) { var username = user.Value.Split('@')[0]; if (!string.IsNullOrEmpty(username)) { //remove existing name claim var removeClaim = claimsIdentity.Claims.ToList().FirstOrDefault(x => x.Type == "name"); if (removeClaim != null) { claimsIdentity.RemoveClaim(removeClaim); } //add username as name claim claimsIdentity.AddClaim(new Claim("name", username.ToLower())); } } tokenValidatedNotification.AuthenticationTicket = new AuthenticationTicket( claimsIdentity, tokenValidatedNotification.AuthenticationTicket.Properties); await Task.FromResult(0); } catch (Exception ex) { logger.LogError(ex, "SecurityTokenValidated error {authTicketIdentity}, {responseStatus} (failure)", tokenValidatedNotification.AuthenticationTicket.Identity, tokenValidatedNotification.Response.StatusCode); throw; } }, RedirectToIdentityProvider = async redirectToIdpNotification => { try { if (!BrowserSupportService.isBrowserSupported()) { redirectToIdpNotification.Response.Redirect("/browserNotSupported"); redirectToIdpNotification.HandleResponse(); } else { // if signing out, add the id_token_hint if (redirectToIdpNotification.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout) { Claim idTokenHint = redirectToIdpNotification.OwinContext.Authentication.User.FindFirst("id_token"); if (idTokenHint != null) { redirectToIdpNotification.ProtocolMessage.IdTokenHint = idTokenHint.Value; } redirectToIdpNotification.ProtocolMessage.PostLogoutRedirectUri = postLogoutRedirectUrl; redirectToIdpNotification.Options.PostLogoutRedirectUri = postLogoutRedirectUrl; } if (redirectToIdpNotification.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication && IsAjaxRequest(redirectToIdpNotification.Request) && redirectToIdpNotification.Response.StatusCode == (int) HttpStatusCode.Unauthorized) { redirectToIdpNotification.Response.StatusCode = (int) HttpStatusCode.Unauthorized; redirectToIdpNotification.HandleResponse(); } } await Task.FromResult(0); } catch (Exception ex) { logger.LogError(ex, "RedirectToIdentityProvider error"); throw; } } } });

日志文件的相关部分

IdentityServer logs are successful, no errors/warnings during this.

问题,我正在使用.NET Framework 4.7.2 MVC应用程序,它始终位于负载平衡器的后面,并且除非我添加第二个MVC App实例,否则效果很好。 IdentityServer4本身正在使用数据...
.net asp.net-mvc cookies identityserver4 openid-connect
1个回答
0
投票
几年前,我在我工作的公司解决了这个问题。原因是默认的ASP.Net身份验证cookie解密仅在创建/加密cookie的服务器上起作用。
© www.soinside.com 2019 - 2024. All rights reserved.