@PreAuthorize в Spring Security на уровне типа не может быть переопределен на уровне метода - PullRequest
14 голосов
/ 03 октября 2011

Я пытаюсь защитить контроллер с помощью аннотации @PreAuthorize на уровне типа и пытаюсь переопределить это поведение, комментируя некоторые методы с другим @PreAuthorize.Проблема, однако, в том, что Spring сначала оценивает аннотацию метода (предоставляет доступ), а затем оценивает аннотацию класса (запрещает доступ).

Есть ли способ отменить этот порядок?Пока не могу понять.

Редактировать:

На уровне метода я хочу предоставить доступ только незарегистрированным пользователям:

@PreAuthorize("isAnonymous()")
@RequestMapping(value = "/create", method = RequestMethod.GET)
public String renderCreateEntity(ModelMap model) {
    return userService.renderCreateEntity(model);
}

стандарт для этого контроллера, однако, должен позволять только полностью аутентифицированным пользователям:

@Controller
@RequestMapping(value = "/user")
@PreAuthorize("isFullyAuthenticated()")
public class UserController { [...] }

При пошаговом отладке через приложение, я вижу, что isAnonymous() сначала оценивается, а затем isFullyAuthenticated(), что приводитпредоставление права доступа и немедленное повторное запрещение доступа.

Ответы [ 2 ]

14 голосов
/ 04 октября 2011

Спасибо за все ваши ответы. Ответ, однако, был совсем другим:)

Я помещу это здесь на случай, если у кого-то еще возникнут такие же проблемы.

Я зарегистрировал пользовательский валидатор в аннотированном методе @InitBinder. Этот метод привязки называется ПОСЛЕ вызова метода, запрошенного на контроллере. И поскольку этот метод привязки не был помечен @PreAuthorize, запрос был отклонен.

Решением было аннотировать метод привязки следующим образом:

@InitBinder
@PreAuthorize("permitAll")
public void initBinder(WebDataBinder binder) {
    binder.setValidator(validator);
}

А затем вызовы методов из моего OP оцениваются как ожидалось.

5 голосов
/ 04 октября 2011

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

PrePostAnnotationSecurityMetadataSource Java Doc:

Аннотации могутбыть указанным в классах или методах, и аннотации для конкретных методов будут иметь приоритет.

Конкретная реализация этой логики выполняется в методе findAnnotation класса PrePostAnnotationSecurityMetadataSource.(К сожалению, этот метод является закрытым.)

Так что вы можете написать свой собственный MethodSecurityMetadataSource, если вы посмотрите на код PrePostAnnotationSecurityMetadataSource, вы увидите, насколько это просто.

Но одно предупреждение в конце: конец: трудная задача не переписывает метод, трудная задача - «вставить» новый MethodSecurityMetadataSource в систему безопасности.Я верю, что вы не можете сделать это с конфигурацией пространства имен Spring Security, поэтому вам нужно заменить пространство имен Spring Security явным объявлением компонента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...