Контроллер валидации ролей Spring Boot с использованием аспекта - PullRequest
0 голосов
/ 25 апреля 2020

У меня есть несколько функций контроллера, разделенных по ролям, и вместо того, чтобы выполнять проверку роли в каждом методе контроллера, я обнаружил, что кажется, что он может быть выполнен с помощью Aspect, однако что-то не так в моей реализации как код в аспекте никогда не запускается

Аннотация:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ForMerchantOnly {}

Формат:

@Aspect
@Configuration
public class ForMerchantOnlyAspect {
    private static final Logger logger = LogManager.getLogger(ForMerchantOnlyAspect.class);

    @Before("@annotation(com.example.api.annotation.ForMerchantOnly) && args(request)")
    public void before(HttpServletRequest request) throws ServiceException {
        if (!(request instanceof HttpServletRequest)) {
            throw new RuntimeException("request should be HttpServletRequesttype");
        }

        String domain = request.getServerName();
        System.out.println("Aspect showing domain " + domain);
        // -- other code
    }
}

Контроллер

@ForMerchantOnly
@GetMapping("/list")
public ResponseEntity<ApiResp> list() {
    System.out.println("Show something");
    return ResponseEntity.ok().body();
}

Я предполагаю, когда я вызываю контроллер / list метод через chrome браузер, он попадет в код в ForMerchantOnlyAspect, но он просто войдет в метод контроллера напрямую. Я что-то упустил?

1 Ответ

1 голос
/ 26 апреля 2020

Аспект не работал, так как не смог найти подходящую точку соединения. Нет методов контроллера с аннотацией @ForMerchantOnly и аргументом типа HttpServletRequest

Из документации :

args: Пределы, соответствующие точки соединения (выполнение методов при использовании Spring AOP), где аргументы являются экземплярами заданных типов.

Следующий аспект может быть использован для требования. Обозначение области видимости within устанавливает область действия для совета.

@Before("@annotation(com.example.api.annotation.ForMerchantOnly) && within(com.example.api..*)")
  public void before() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
                .getRequest();

        System.out.println("Aspect showing domain " + request.getServerName());
    }

Также обратите внимание, что Аспект лучше аннотировать с помощью @Component и @Configuration, которые будут использоваться для конфигураций.

Вы можете Также взгляните на Метод безопасности среды безопасности Spring, которая позволяет защитить метод с аннотациями.

Из документации

Начиная с версии 2.0 Spring Безопасность значительно улучшила поддержку для повышения безопасности методов уровня обслуживания. Он обеспечивает поддержку безопасности аннотаций JSR-250, а также оригинальную аннотацию @Secured. Начиная с версии 3.0 вы также можете использовать новые аннотации на основе выражений. Вы можете применить защиту к одному bean-компоненту, используя элемент intercept-Methods для декорирования объявления bean-компонента, или вы можете защитить несколько bean-компонентов по всему сервисному слою, используя точки в стиле AspectJ.

...