Disclamer - я работал с весенней загрузкой 2, поэтому не все может быть применимо для вас
Это урезанная версия того, что я реализовал некоторое время назад.Я предлагаю реализовать перечисления для ролей и значений.
Вы не можете делать перенаправления из аннотаций @before, поэтому вам нужно вызвать исключение и перехватить его с помощью глобального обработчика ex, перенаправление оттуда.
Также рассмотрите возможность добавления к аннотации необязательных полей - в случае нескольких ролей, сопоставьте все или одно, путь перенаправления, тип исключения для вызова в случае отсутствия доступа.Затем в обработчике исключений вы можете делать перенаправления в зависимости от того, какое исключение было вызвано.Поскольку вы выполняете перенаправления из обработчика gloabl ex, если вы добавите путь перенаправления, вам придется связать его с исключением, которое вы выбрасываете, то есть вам понадобятся пользовательские исключения.
Аннотация
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidateHeaders {
Roles[] roles();
String[] values();
}
Aspect Class
@Aspect
@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired)) //Autowired annotated lombok generated constructor
public class ValidateHeadersAspect {
private final @NonNull HttpServletRequest request; //Inject request to have header access
private final @NonNull UserService userService;//Your user service here
//Aspect can be placed on clas or method
@Before("within(@com.org.package.ValidateHeaders *) || @annotation(com.org.package.ValidateHeaders)")
public void validateAspect(JoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
HasAccess validateHeaders = method.getAnnotation(ValidateHeaders.class);
if(validateHeaders == null) { //If null it was a class level annotation
Class annotatedClass = joinPoint.getSignature().getDeclaringType();
validateHeaders = (ValidateHeaders)annotatedClass.getAnnotation(ValidateHeaders.class);
}
Roles[] roles = validateHeaders.roles(); //Roles listed in annotation
String[] values = validateHeaders.values(); //Values listed in
//Validate request here ... determine isAuthorised
if( !isAuthorized ){
throw new HeaderAuthrizationException()
}
}
}
Обработчик исключений
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(HeaderAuthrizationException.class)
public RedirectView HeaderAuthrizationException(HeaderAuthrizationException ex) {
return new RedirectView("/redirect");
}
}