Home » Добавление управления CORS в Optimizely CMS 12

Добавление управления CORS в Optimizely CMS 12

В декабре 2021 года я начал работу над новым дополнением для Optimizely CMS 12. Это дополнение представило новый способ управления политикой безопасности контента в CMS, который был разработан, чтобы быть более доступным для нетехнических людей. Это дополнение позволяло администратору CMS определять для каждого источника, какому источнику разрешено выполнять какие действия с веб-сайтом, при этом каждое изменение подвергалось полной проверке. Это дополнение теперь доступно на ряде веб-сайтов Optimizely CMS и прошло ряд тестов на проникновение.

Я планировал, что следующая эволюция этого дополнения будет включать возможность управления заголовками совместного использования ресурсов между источниками (CORS) из интерфейса администрирования CMS. CORS позволяет API или веб-сайту определять, какие третьи стороны могут использовать ресурс, а также как они могут использовать этот ресурс. Это может быть важным требованием безопасности, если вы создаете управляемую или гибридную CMS, которая предоставляет конечные точки для использования другим веб-сайтом.

Цель этого обновления надстройки Stott Security заключалась в том, чтобы позволить редактору CMS устанавливать все следующие заголовки в удобном для управления интерфейсе:

Я добавил в надстройку Stott Security новую вкладку под названием «CORS», которая позволяет редактировать и сохранять все эти заголовки вместе.

Если опция «Включить совместное использование ресурсов между источниками (CORS)» отключена, при запросе на веб-сайт от третьей стороны ответ будет обрабатываться так, как будто CORS полностью запрещен. Если эта опция включена, по умолчанию разрешены все источники; Только после добавления записи в «Разрешенные источники» другим источникам снова будет отказано в доступе. То же самое поведение применимо к заголовкам и методам HTTP: все они считаются разрешенными до тех пор, пока определенные методы или заголовки не будут определены как разрешенные.

Read more:  в Париже 18 000 демонстрантов по данным полицейского управления, 50 000 по данным профсоюзов

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

Внедрение CORS

Когда у меня появился пользовательский интерфейс для управления CORS и таблицы, отсортированные для хранения конфигурации, я смог приступить к поиску способа реализации такого поведения. Сначала я попытался создать собственное промежуточное программное обеспечение для управления этим, и меня быстро осенило, что добиться этого будет очень сложно. Access-Control-Allow-Origin заголовок, например, может содержать только *, происхождение сайта, сделавшего запрос, или его полное отсутствие. Это не позволяет веб-сайту раскрывать третьим лицам, которые могут их использовать, а только то, разрешено ли стороннему веб-сайту использовать их или нет.

Пытаясь понять, как лучше с этим справиться, я добавил CORS на свой образец веб-сайта, используя стандартные библиотеки Microsoft, вызвав метод AddCors() и UseCors() методы внутри моего startup.cs.

Перейдя к декомпилированной версии UseCors() Я смог увидеть CorsПромежуточное ПО который был реализован Microsoft, и увидеть, что он использовал реализацию ICorsPolicyProvider чтобы получить CorsPolicy объект и реализация ICorsService оценить CorsPolicy сам. Глядя на декомпилированный код для AddCors() Я видел, что внедрение зависимостей требует ICorsPolicyProvider и ICorsService мы использовали TryAdd, который добавляет реализации этих интерфейсов по умолчанию, только если они еще не были объявлены.

/// 
/// Adds cross-origin resource sharing services to the specified .
/// 
/// The  to add services to.
/// The  so that additional calls can be chained.
public static IServiceCollection AddCors(this IServiceCollection services)
{
    if (services == null)
    {
        throw new ArgumentNullException(nameof(services));
    }

    services.AddOptions();

    services.TryAdd(ServiceDescriptor.Transient());
    services.TryAdd(ServiceDescriptor.Transient());

    return services;
}

Тогда реализация оказалась относительно простой. Создайте собственную реализацию ICorsPolicyProvider который использовал данные, сохраненные моей надстройкой, для создания экземпляра CorsPolicy для использования реализациями по умолчанию ICorsService. Интерфейс ICorsPolicyProvider содержал только один метод, который я мог реализовать.

/// 
/// A type which can provide a  for a particular .
/// 
public interface ICorsPolicyProvider
{
    /// 
    /// Gets a  from the given 
    /// 
    /// The  associated with this call.
    /// An optional policy name to look for.
    /// A 
    Task GetPolicyAsync(HttpContext context, string? policyName);
}

Чтобы свести к минимуму проблемы с производительностью, мое хранилище данных представляет собой одну таблицу с очень плоской записью, которая преобразуется в объект домена с несколькими свойствами и коллекциями. Чтобы сократить дальнейшие обращения к SQL-серверу и создание объекта домена, а затем его сопоставление с CorsPolicy объект, я также сохранил скомпилированный CorsPolicy объект в Optimizely ISynchronizedObjectInstanceCache который затем будет признан недействительным при любом последующем обновлении политики CORS.

public async Task GetPolicyAsync(HttpContext context, string? policyName)
{
    var policy = _cache.Get(CacheKey);
    if (policy == null)
    {
        policy = await LoadPolicy();
        _cache.Add(CacheKey, policy);
    }

    return policy;
}

Конечным результатом является полностью функционирующая редактируемая политика CORS CMS, которую можно обновлять и которая может немедленно вступить в силу, не требуя каких-либо изменений кода или развертывания. Чтобы узнать больше о том, как CORS реализован в .NET Core, вы можете прочитать Глубокое погружение в библиотеку ASP.NET Core CORS. написано Эндрю Лок и просмотреть открытый исходный код для CorsПромежуточное ПО на Гитхабе.

В бета-версии

Я классифицирую версию 2.0.0 этого дополнения как находящуюся в стадии бета-тестирования до тех пор, пока один или несколько веб-сайтов CMS не будут запущены и не будут использовать конфигурацию CORS, а любые возникшие проблемы будут либо расставлены по приоритету, либо исправлены. Если вы хотите использовать бета-версию 2.0.0, не стесняйтесь установить ее на свой веб-сайт Optimizely CMS 12 и присоединиться к обсуждение страница на Репозиторий GitHub.

09 октября 2023 г.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.