Создание куки аутентификации для другого сайта (через аутентификацию Windows)

Вопрос или проблема

Я использую ASP.net core 8 (планирую обновить до 9, когда он будет выпущен).

У меня есть 2 веб-сайта: первый доступен внутри корпоративной сети, использует аутентификацию Windows.
Вторая копия того же сайта находится на внешнем веб-сервере и использует аутентификацию по кукам.

Одна из ключевых проблем заключается в том, что когда веб-сайт обновляется, мне нужно публиковать код в двух местах (один и тот же код, просто разные файлы AppSettings.Production.json).

Что я пытаюсь достичь, так это вместо того, чтобы иметь 2 копии одного и того же веб-сайта с разными схемами аутентификации, иметь только 1 копию, использующую куки, но с другим веб-сайтом, который использует аутентификацию Windows и автоматически создает куки для основного сайта на основе текущего пользователя.

Это позволяет пользователю войти в систему, используя куки, установленные через стандартную страницу входа (внешняя сеть) или через другой веб-сайт с аутентификацией Windows (внутренний доступ).

Чтобы попытаться реализовать это, я создал тестовое решение, содержащее 2 веб-сайта:

  1. Asp.Net Core (MVC) с аутентификацией Windows
  2. Asp.net Razor page (использует опцию аутентификации отдельных учетных записей)

На сайте с аутентификацией Windows я добавил следующий код в Program.cs

builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)

.AddCookie("CookieAuthenticationScheme") // Новое ************

   .AddNegotiate();

и

builder.Services.AddDataProtection() // Новое (добавлено перед var app = builder.Build())
    .PersistKeysToFileSystem(new DirectoryInfo(@"c:\KeyLocation"))
    .SetApplicationName("SharedCookieApp");

builder.Services.ConfigureApplicationCookie(options => {
    options.Cookie.Name = ".AspNet.SharedCookie";
});

Затем в Home/Index я добавил

public class HomeController : Controller
{
    public async Task<IActionResult> Index()
    {
        var c = HttpContext;
        var userName = c.User.Identity?.Name;
        if (userName != null)
        {
            userName = "[email protected]"; // Имя соответствует пользователю, созданному в asp.net identity на другом сайте
            IEnumerable<Claim> claims = [new(ClaimTypes.Name, userName)];            
            await c.SignInAsync("CookieAuthenticationScheme", new ClaimsPrincipal(new ClaimsIdentity(claims, "CookieAuthenticationScheme")));
        }

        var Referer = Redirect("https://localhost:7207");  
        return Referer;
    }

Затем на основном веб-сайте, использующем куки, я добавил следующее в Program.cs

builder.Services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo(@"c:\KeyLocation"))
    .SetApplicationName("SharedCookieApp");

builder.Services.ConfigureApplicationCookie(options => {
    options.Cookie.Name = ".AspNet.SharedCookie";
});

Однако кука, созданная на сайте с аутентификацией Windows, не позволяет войти на основной веб-сайт.
Буду признателен за любую помощь.

Ответ или решение

Для реализации вашей задачи по единой аутентификации между двумя веб-сайтами с использованием Windows аутентификации и куки аутентификации, вам потребуется следовать нескольким шагам. Вы уже на верном пути, но давайте рассмотрим некоторые важные моменты и возможные улучшения в вашем коде.

Основные шаги:

  1. Общие настройки Data Protection:
    Убедитесь, что на обоих сайтах используется одна и та же конфигурация для Data Protection. Это включает в себя использование одного и того же PersistKeysToFileSystem и SetApplicationName. Вы уже сделали это, добавив код в каждый из сайтов. Убедитесь, что путь @"c:\KeyLocation" доступен для записи и чтения для обоих приложений.

  2. Настройка схемы аутентификации:
    Обратите внимание, что вам нужно установить одно и то же имя куки для аутентификации на обоих сайтах. Это вы правильно указали как .AspNet.SharedCookie. Убедитесь, что конфигурации аутентификации в обоих проектах совпадают.

  3. Создание и передача куки:
    В коде контроллера вашего сайта с Windows аутентификацией убедитесь, что изначально вы создаете куки с правильными параметрами. Также убедитесь, что имя пользователя, используемое для создания Claim, точно соответствует тому, как оно настроено в ASP.NET Identity вашего другого сайта. Вот пример:

    public class HomeController : Controller
    {
       public async Task<IActionResult> Index()
       {
           var c = HttpContext;
           var userName = c.User.Identity?.Name;
    
           if (!string.IsNullOrEmpty(userName))
           {
               var claims = new List<Claim>
               {
                   new Claim(ClaimTypes.Name, userName),
                   new Claim(ClaimTypes.Role, "User") // Добавьте другие роли при необходимости
               };
    
               var claimsIdentity = new ClaimsIdentity(claims, "CookieAuthenticationScheme");
               var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
    
               // Убедитесь, что вы используете корректную схему аутентификации
               await c.SignInAsync("CookieAuthenticationScheme", claimsPrincipal);
           }
    
           return Redirect("https://localhost:7207");
       }
    }
  4. Настройка кросс-доменных куки:
    Если ваши сайты развернуты на разных доменах (например, test.local и example.com), вам нужно будет убедиться, что браузер позволяет устанавливать куки для разных доменов. Это может потребовать настройки CORS и возможно применения метода с SameSite=None для куки, если они кросс-доменные.

    builder.Services.ConfigureApplicationCookie(options =>
    {
       options.Cookie.Name = ".AspNet.SharedCookie";
       options.Cookie.SameSite = SameSiteMode.None; // Не забудьте это установить, если используются разные домены
       options.Cookie.SecurePolicy = CookieSecurePolicy.Always; // Используйте Secure только при HTTPS
    });

Заключение

Обобщая, убедитесь, что:

  • Общая путь для Data Protection на обоих сайтах совпадает.
  • Используется одно и то же имя куки и схема аутентификации.
  • Пользовательские роли и идентификация точно соответствуют вашему ASP.NET Identity.
  • Если предполагается работа через разные домены, пройдите этап настройки заголовков и обеспечьте кросс-доменные куки.

После выполнения всех этих шагов ваша система аутентификации должна работать, позволяя пользователям одновременно входить как через Windows аутентификацию, так и через куки на вашем внешнем сайте.

Оцените материал
Добавить комментарий

Капча загружается...