1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/ainilili-defender

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
DOC_EN.md 11 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 29.11.2024 10:43 f97d51b

Defender & Guarder

Defender можно представить как формирование охраны замка. Если вы хотите охранять замок, вам потребуется участие guarder, и guarder — это так называемый охранник.

В сервисе существует только один defender, и guarder, тесно связанный с guarder, будет формировать отношение «многие к одному» с defender. Каждый guarder может задавать различные режимы и стратегии для противодействия или фильтрации посетителей и внешних врагов. При одновременном запуске нескольких guarder они будут сотрудничать друг с другом и усердно работать над безопасностью сервиса!

Defender

Defender — это синглтон, и мы можем получить его следующим образом:

Defender.getInstance()

Defender больше похож на контейнер, который загружает определённый нами guarder, чтобы помочь нам управлять разрешениями. Мы можем зарегистрировать guarder, вызвав метод реестра:

Defender.getInstance()
        .registry(guarder)
        .ready()

Видно, что после регистрации guarder мы вызвали метод ready, который является важным. Это сигнал о том, что мы уведомляем defender обо всём готовом. Как только этот метод будет выполнен, defender выполнит работу по инициализации вместе.

Guarder

Получить Guarder просто, его конструкция является частной, чтобы сделать процесс инициализации более элегантным, а ниже приведён полный экземпляр Guarder:

Guarder.builder(GuarderType.URI)
        .pattern("POST /user")
        .order(1)
        .preventer(caller -> {
            return Result.pass();
        })

Порядок является значением по умолчанию, с помощью которого можно настроить порядок защиты нескольких guarder, первый из которых можно назвать отрядом смертников. Когда мы вызываем метод builder, нам нужно передать значение перечисления, чтобы указать используемый нами шаблон защиты, который мы рассмотрим позже. Как видите, получить объект guarder так же просто.

Несколько режимов защиты Defender

Defender предлагает три режима защиты, с разными стилями для разных режимов защитника:

  • модель аннотаций;
  • модель выражений;
  • URI (стиль Ant).

Несмотря на различия, их можно использовать в сочетании с проектом, и мы подробнее рассмотрим каждый шаблон ниже.

Модель аннотаций

Используя шаблон аннотаций, мы должны создать соответствующий экземпляр guarder:

Guarder.builder(GuarderType.ANNOTATION)
        .pattern("org.nico.trap.controller")
        .preventer(caller -> {
            return Result.pass();
        })

Далее нам нужно добавить аннотации @access к методам, которые нам нужно защитить:

@Access(AuthConst.LOGIN)
@PostMapping("/")
public ResponseVo<GameFullVo> publishGame(@RequestBody GamePublishVo gameVo) throws TrapException{
    GameFullVo gameFullVo = gameService.publishGame(gameVo);
    return new ResponseVo<GameFullVo>(ResponseCode.SUCCESS, gameFullVo);
}

Значение, переданное в аннотацию @access, может быть определено как одна константа на основе текущего состояния системы, defender не сделал строгого определения! Формат шаблона под каждым режимом отличается. Для режима аннотаций значение шаблона представляет собой имя пакета, и все шаблоны с @access в этом пакете будут защищены.

Модель выражений

Модель выражений более детализирована, чем модель аннотаций, но также более общая. Мы можем получить guarder модели выражения следующими способами:

Guarder.builder(GuarderType.EXPRESSION)
        .pattern("* org.nico.trap.controller.UserController.*(..)")
        .prevener(caller -> {
            return Result.pass();
        })

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

URI (стиль Ant)

Шаблоны URI более интуитивно понятны:

Guarder.builder(GuarderType.URI)
        .pattern("POST /user")
        .preventer(caller -> {
            return Result.pass();
        })

Первый абзац — это тип запроса, а второй абзац — адрес запрошенного ресурса. Используется сопоставление в стиле ANT. В целом модель выражения похожа на модель выражения.

Объяснение Guarder Guarder: методы и принципы работы

В предыдущей дискуссии мы узнали о связи и роли defender и guarder, а также о различных режимах защиты guarder. Теперь мы проведём более глубокий анализ guarder, чтобы лучше и гибче использовать его возможности.

Метод Guarder's builder

Этот метод требует передачи перечисляемого значения GuarderType для определения режима защиты guarder, и возвращаемое значение будет объектом guarder и единственной инстанцированной записью!

Метод Guarder's pattern

Значение pattern зависит от различных шаблонов защиты. Для одного и того же guarder может быть несколько шаблонов, таких как шаблон URI.

Guarder.builder(GuarderType.URI)
        .pattern("POST /user")
        .pattern("DELETE /user")
        .pattern("* /game")
        .preventer(caller -> {
            return Result.pass();
        })

Метод Guarder's order

Метод order определяет значение int, указывающее порядок защиты всех guarder под defender. Чем меньше значение порядка, тем выше приоритет. Значение по умолчанию равно 0.

Методы превентора Guarder

Метод представлен в объекте интерфейса AbstractPreventer, нам нужно реализовать внутренний метод обнаружения интерфейса для пользовательских правил.

public interface AbstractPreventer {
    public Result detection(Caller caller);
}

Далее рассмотрим сценарий, где нам нужно получить токен в заголовке запроса, чтобы определить, защищён ли пользователь от входа, и мы используем режим аннотации для создания объекта guarder.

Guarder.builder(GuarderType.ANNOTATION)
        .pattern("org.nico.trap.controller")
        .preventer(new AbstractPrevener() {
            
            @Autowired
            private AuthComponent authComponent;
            
            @Override
            public Result detection(Caller caller) {
                String identity = caller.getAccess().value();
                if(! identity.equals(AuthConst.VISITOR)) {
                    UserBo user = authComponent.getUser();
                    if(user != null) {
                        if(identity.equals(AuthConst.ADMIN)){
                            if(user.getRuleType() == null) {
                                return Result.notpass(new ResponseVo<>(ResponseCode.ERROR_ON_USER_IDENTITY_MISMATCH));
                            }
                        }
        ```
```}else {
                    return Result.notpass(new ResponseVo<>(ResponseCode.ERROR_ON_LOGIN_INVALID));
                }
            }
            return Result.pass();
        })

В приведённом выше классе реализации AbstractPreventer мы используем @autowired, это функция, которую должен поддерживать защитник. Для простой защиты мы можем использовать более лаконичную реализацию лямбда, например, запрос на токен существует.

Guarder.builder(GuarderType.ANNOTATION)
        .pattern("org.nico.trap.controller")
        .preventer(caller -> {
            return caller.getRequest().getHeader("token") == null 
                    ? Result.notpass("Token not exist") 
                    : Result.pass();
        })

Как видно из приведённого примера, метод защитника возвращает два типа: pass и notpass, и соответствующий экземпляр получается через статический метод Result.

  • Result.notpass(Object o) указывает, что защита не нарушена. Этот запрос является незаконным. Переданный параметр o представляет собой сообщение с подсказкой, возвращаемое запрашивающему.
  • Result.pass() представляет законный запрос.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/ainilili-defender.git
git@api.gitlife.ru:oschina-mirror/ainilili-defender.git
oschina-mirror
ainilili-defender
ainilili-defender
master