ASP.NET Core проверяет подлинность с помощью существующего билета проверки подлинности в обратном вызове события OnCreatC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 ASP.NET Core проверяет подлинность с помощью существующего билета проверки подлинности в обратном вызове события OnCreat

Сообщение Anonymous »

У меня настроена аутентификация с помощью файлов cookie с двумя поставщиками OAuth2. Это работает так: пользователь создает учетную запись на моем веб-сайте с Discord OAuth2, а затем может также связать свою учетную запись SampleSite с OAuth2.
Это моя настройка аутентификации

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

builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;

options.DefaultChallengeScheme = OAuthAuthenticationDefaults.DiscordAuthenticationScheme;
})
.AddCookie(options =>
{
options.Cookie = new()
{
Name = "auth",
SameSite = SameSiteMode.Lax,
Path = "/",
HttpOnly = true,
IsEssential = true,
MaxAge = TimeSpan.FromDays(6 * 30)
};

options.ExpireTimeSpan = TimeSpan.FromDays(6 * 30);
})
.AddOAuth(OAuthAuthenticationDefaults.DiscordAuthenticationScheme, options =>
{
options.ClientId = configuration["Credentials:Discord:ClientId"] ??
throw new ArgumentNullException(null, "Discord client ID was null");
options.ClientSecret = configuration["Credentials:Discord:ClientSecret"] ??
throw new ArgumentNullException(null, "Discord client secret was null");

options.AuthorizationEndpoint = "https://discord.com/oauth2/authorize";
options.CallbackPath = configuration["OAuth2:Discord:RedirectUri"] ??
throw new ArgumentNullException(null, "Discord OAuth2 redirect URI was null");
options.TokenEndpoint = "https://discord.com/api/oauth2/token";
options.UserInformationEndpoint = "https://discord.com/api/users/@me";

options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "id");
options.ClaimActions.MapJsonKey(ClaimTypes.Name, "username");

options.Scope.Add("identify");

options.CorrelationCookie = new()
{
Name = "correlation.discord."
};

options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;

options.Events.OnCreatingTicket = async context =>
{
HttpRequestMessage req = new(HttpMethod.Get, context.Options.UserInformationEndpoint);
req.Headers.Authorization = new("Bearer", context.AccessToken);

HttpResponseMessage res = await context.Backchannel.SendAsync(req);
res.EnsureSuccessStatusCode();

string userData = await res.Content.ReadAsStringAsync();
DiscordUserInformation? discordUser = JsonSerializer.Deserialize(userData) ??
throw new NullReferenceException(nameof(discordUser));

context.RunClaimActions(JsonDocument.Parse(userData).RootElement);

// Check if user already exists

IUserManager userManager = context.HttpContext.RequestServices.GetRequiredService();
ApplicationUser? user = await userManager.GetApplicationUserAsync(ulong.Parse(discordUser.Id));

if (user != null) return;

// Save user to database

await userManager.CreateAsync(ulong.Parse(discordUser.Id), []);
};
})
.AddOAuth(OAuthAuthenticationDefaults.ExampleSiteAuthenticationScheme, options =>
{
options.ClientId = configuration["Credentials:ExampleSite:ClientId"] ??
throw new ArgumentNullException(null, "ExampleSite client ID was null");
options.ClientSecret = configuration["Credentials:ExampleSite:ClientSecret"] ??
throw new ArgumentNullException(null, "ExampleSite client secret was null");

options.AuthorizationEndpoint = "https://apis.ExampleSite.com/oauth/v1/authorize";
options.CallbackPath = configuration["OAuth2:ExampleSite:RedirectUri"] ??
throw new ArgumentNullException(null, "ExampleSite OAuth2 redirect URI was null");
options.TokenEndpoint = "https://apis.ExampleSite.com/oauth/v1/token";
options.UserInformationEndpoint = "https://apis.ExampleSite.com/oauth/v1/userinfo";

options.ClaimActions.MapJsonKey("urn:ExampleSite:id", "sub");
options.ClaimActions.MapJsonKey("urn:ExampleSite:username",  "preferred_username");

options.Scope.Add("openid");
options.Scope.Add("profile");

options.CorrelationCookie = new()
{
Name = "correlation.ExampleSite."
};

options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;

options.Events.OnCreatingTicket = async context =>
{
HttpRequestMessage req = new(HttpMethod.Get, context.Options.UserInformationEndpoint);
req.Headers.Authorization = new("Bearer", context.AccessToken);

HttpResponseMessage res = await context.Backchannel.SendAsync(req);
res.EnsureSuccessStatusCode();

string userData = await res.Content.ReadAsStringAsync();
ExampleSiteUserInformation ExampleSiteUser = JsonSerializer.Deserialize(userData) ??
throw new NullReferenceException(nameof(ExampleSiteUser));

IUserManager userManager = context.HttpContext.RequestServices.GetRequiredService();

// context.HttpContext.User.Identity.IsAuthenticated is false while it is true if I access the User object from a controller
ApplicationUser user = await userManager.GetApplicationUserAsync(ulong.Parse(context.HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value)) ??
throw new NullReferenceException(nameof(user));

// Check if the user already verified this account

ulong ExampleSiteUserId = ulong.Parse(ExampleSiteUser.Id);

if (await userManager.GetUserExampleSiteVerificationAsync(ExampleSiteUserId) != null) return;

context.RunClaimActions(JsonDocument.Parse(userData).RootElement);
await userManager.VerifyExampleSiteUserAsync(user.Id, ExampleSiteUserId);
};
});
Проблема здесь

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

ulong.Parse(context.HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value)

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

context.HttpContext.User.Identity.IsAuthenticated
имеет значение false, хотя пользователь ранее прошел аутентификацию с помощью Discord, и значение true при доступе с контроллера.
Я попробовал явно настроить OAuthOptions.SignInScheme, чтобы аутентификация выполняется с использованием данных, хранящихся в файле cookie, но это не имеет никакого значения.

Подробнее здесь: https://stackoverflow.com/questions/790 ... h-provider
Реклама
Ответить Пред. темаСлед. тема

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

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

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

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

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

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