Проблемы с путями обратного вызова OpenID Connect в приложении .NET Core на EKSC#

Место общения программистов C#
Ответить
Anonymous
 Проблемы с путями обратного вызова OpenID Connect в приложении .NET Core на EKS

Сообщение Anonymous »

Я столкнулся с проблемами аутентификации OpenID Connect в моем приложении .NET Core после его развертывания в AWS EKS. Аутентификация работает правильно локально, но не выполняется при развертывании. Вот подробности настройки и проблемы, с которыми я столкнулся:
Настройка:
.NET Core версия: .NET 6
Аутентификация: OpenID Connect с OAM
Среда развертывания: AWS EKS
Redirecturl: https://admin.aws.xxx.com/test
Путь обратного вызова:/
Я пробовал изменить путь обратного вызова к /test вместо /, но я перенаправляюсь на домашнюю страницу, но на самом деле не проходит поток аутентификации.
Соответствующий код:
#region Аутентификация

Код: Выделить всё

builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromHours(1);
options.Cookie.SameSite = SameSiteMode.None;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;

})
#region OAM
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.Configuration = GetOpenIdConnectConfigurations(configuration).Result;
options.ResponseType = OpenIdConnectResponseType.Code;
options.ClientId = configuration.GetValue("Authentication:OAM:ClientId");
options.UseTokenLifetime = true;
options.ClientSecret = configuration.GetValue("Authentication:OAM:ClientSecret");
options.CallbackPath = "/";

options.SkipUnrecognizedRequests = true;
options.UsePkce = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.TokenValidationParameters.AuthenticationType = IdentityConstants.ApplicationScheme;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
};

options.Events.OnRedirectToIdentityProvider = async context =>
{
Log.Information("Redirecting to Identity Provider for sign in.");
await OnRedirectToIdentityProviderForSignIn(context, configuration);
};
options.Events.OnAuthorizationCodeReceived = async context =>
{
Log.Information("Authorization code received.");
await OnAuthorizationCodeReceived(context, configuration);
};
options.Events.OnTokenValidated = context =>
{
Log.Information("Token validated.");
return OnTokenValidated(context);
};
options.Events.OnRedirectToIdentityProviderForSignOut = async context =>
{
Log.Information("Redirecting to Identity Provider for sign out.");
await OnRedirectToIdentityProviderForSignOut(context, configuration);
};
options.Events.OnAccessDenied = context =>
{
Log.Warning("Access denied.");
return OnAccessDenied(context);
};
options.Events.OnRemoteFailure = context =>
{
Log.Error("Remote failure:  {ErrorMessage}", context.Failure.Message);
return OnRemoteFailure(context);
};

options.Scope.Clear();
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add(configuration.GetValue("Authentication:OAM:Scope"));
options.SaveTokens = true;
});
#endregion
#endregion

builder.Services.AddRazorPages();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});

app.Run();

#region Methods

Task OnRedirectToIdentityProviderForSignIn(RedirectContext context, IConfiguration configuration)
{
Log.Information("OnRedirectToIdentityProviderForSignIn called.");
context.ProtocolMessage.Parameters.Add("domain", configuration.GetValue("Authentication:OAM:DomainName"));
var hostName = context.Request.Host.Value.ToLowerInvariant();
context.ProtocolMessage.RedirectUri = GetRedirectURL(configuration, hostName);
Log.Information("Redirect URI: {RedirectUri}", context.ProtocolMessage.RedirectUri);
return Task.CompletedTask;
}

async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context, IConfiguration configuration)
{
Log.Information("OnAuthorizationCodeReceived called.");
try
{
var oamConfiguration = await context.Options.ConfigurationManager.GetConfigurationAsync(CancellationToken.None);
var requestMessage = new HttpRequestMessage(HttpMethod.Post, oamConfiguration.TokenEndpoint);

var hostName = context.Request.Host.Value.ToLowerInvariant();
var redirectUrl = GetRedirectURL(configuration, hostName);
Log.Information("Authorization Code Redirect URL: {RedirectUrl}", redirectUrl);

context.TokenEndpointRequest.RedirectUri = redirectUrl;

using var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("X-OAUTH-IDENTITY-DOMAIN-NAME", configuration.GetValue("Authentication:OAM:DomainName"));
string codeVerifier = context.TokenEndpointRequest.Parameters.Where(x => x.Key == "code_verifier").FirstOrDefault().Value;
var tokenClientOptions = new TokenClientOptions()
{
ClientId = context.TokenEndpointRequest.ClientId,
ClientSecret = context.TokenEndpointRequest.ClientSecret,
Address = oamConfiguration.TokenEndpoint,
Parameters = {
new KeyValuePair("Content-Type", "application/x-www-form-urlencoded")
}
};

var tokenClient = new TokenClient(httpClient, tokenClientOptions);
var tokenResponse = await tokenClient.RequestAuthorizationCodeTokenAsync(context.TokenEndpointRequest.Code, redirectUrl, codeVerifier);
if (tokenResponse.HttpStatusCode == System.Net.HttpStatusCode.OK)
{
context.HandleCodeRedemption(tokenResponse.AccessToken, tokenResponse.IdentityToken);
Log.Information("Token response received and handled successfully.");
Log.Information("Access Token: {AccessToken},Identity Token: {IdentityToken}", tokenResponse.AccessToken, tokenResponse.IdentityToken);
}
else
{
Log.Error("Failed to get response from token endpoint: {TokenResponse}", tokenResponse);
throw new Exception($"Unable to get response from token endpoint...  {tokenResponse}");
}
}
catch (Exception ex)
{
Log.Error(ex, "Exception occurred during authorization code received.");
throw new Exception(ex.Message, ex);
}

await Task.FromResult(0);
}

string GetRedirectURL(IConfiguration configuration, string hostName)
{
Log.Information("GetRedirectURL called for host: {HostName}", hostName);
var redirectUrl = configuration.GetValue("Authentication:OAM:RedirectUrl");
return redirectUrl;
}

async Task GetOpenIdConnectConfigurations(IConfiguration configuration)
{
Log.Information("Getting OpenIdConnect configurations.");
try
{
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-OAUTH-IDENTITY-DOMAIN-NAME", configuration.GetValue("Authentication:OAM:DomainName"));
var configManager = new ConfigurationManager(configuration.GetValue("Authentication:OAM:MetadataAddress"), new OpenIdConnectConfigurationRetriever(), client);
var openIdConnectConfiguration = await configManager.GetConfigurationAsync();
Log.Information("OpenIdConnect configurations retrieved successfully.");
return openIdConnectConfiguration;
}
catch (Exception ex)
{
Log.Error(ex, "Unable to get configurations from OAM.");
throw new Exception($"Unable to get configurations from OAM: {ex}");
}
}

async Task OnRedirectToIdentityProviderForSignOut(RedirectContext context, IConfiguration configuration)
{
Log.Information("OnRedirectToIdentityProviderForSignOut called.");
var oamConfiguration = await context.Options.ConfigurationManager.GetConfigurationAsync(CancellationToken.None);
var logoutUrl = configuration.GetValue("Authentication:OAM:AppSignOutUrl");
context.ProtocolMessage.IssuerAddress = oamConfiguration.Issuer;
context.ProtocolMessage.PostLogoutRedirectUri = logoutUrl;
Log.Information("Sign out redirect URL: {LogoutUrl}", logoutUrl);
context.Response.Redirect(logoutUrl, true);
context.HandleResponse();
}

Task OnRemoteFailure(RemoteFailureContext context)
{
Log.Error("Remote failure occurred: {ErrorMessage}", context.Failure.Message);
context.HandleResponse();
string errorMessage = $"Single sign-on Remote Failure - {context.Failure.Message}. Please Retry";
context.Response.Redirect($"/Error?message={Uri.EscapeDataString(errorMessage)}");
return Task.FromResult(0);
}

Task OnAccessDenied(AccessDeniedContext context)
{
Log.Warning("Access denied.");
context.HandleResponse();
string errorMessage = "Single sign-on AccessDenied";
context.Response.Redirect($"/Home/Forbidden?message={Uri.EscapeDataString(errorMessage)}");
return Task.FromResult(0);
}

Task OnTokenValidated(TokenValidatedContext context)
{
Log.Information("Token validated successfully.");
context.Properties.StoreTokens(new[] {
new AuthenticationToken
{
Name = OpenIdConnectResponseType.IdToken,
Value = context.TokenEndpointResponse.IdToken,
}
});

var claimsIdentity = context.Principal.Identity as ClaimsIdentity;
var userIdClaim = claimsIdentity.FindFirst(ClaimTypes.NameIdentifier);
Log.Information("User ID claim: {UserIdClaim}", userIdClaim.Value);

claimsIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, userIdClaim.Value));

return Task.FromResult(0);
}
#endregion

Подробнее здесь: https://stackoverflow.com/questions/788 ... ion-on-eks
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»