Ответ 1
Я предполагаю, что @Restricted
- ваша аннотация. Если это так, убедитесь, что у вас есть:
@Retention(RetentionPolicy.RUNTIME)
в определении аннотации. Это означает, что аннотация сохраняется во время выполнения.
Я хотел бы реализовать декларативную безопасность с помощью Spring/AOP и аннотаций. Как вы видите в следующем примере кода, у меня есть Ограниченные аннотации с параметром "allowedRoles" для определения того, кому разрешено выполнять рекомендуемый метод.
@Restricted(allowedRoles="jira-administrators")
public void setPassword(...) throws UserMgmtException {
// set password code
...
}
Теперь проблема заключается в том, что в моем совете у меня нет доступа к определенным аннотациям:
public Object checkPermission(ProceedingJoinPoint pjp) throws Throwable {
Signature signature = pjp.getSignature();
System.out.println("Allowed:" + rolesAllowedForJoinPoint(pjp));
...
}
private Restricted rolesAllowedForJoinPoint(ProceedingJoinPoint thisJoinPoint)
{
MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature();
Method targetMethod = methodSignature.getMethod();
return targetMethod.getAnnotation(Restricted.class);
}
Метод выше всегда возвращает значение null (вообще не существует аннотаций). Есть ли простое решение?
Я прочитал что-то об использовании агента AspectJ, но я бы предпочел не использовать этот агент.
Я предполагаю, что @Restricted
- ваша аннотация. Если это так, убедитесь, что у вас есть:
@Retention(RetentionPolicy.RUNTIME)
в определении аннотации. Это означает, что аннотация сохраняется во время выполнения.
Для тех, у кого еще есть проблема после изменения аннотации к Runtime, у вас может быть такая же проблема: getMethod() возвращает метод интерфейса вместо класса реализации. Итак, если у вас есть аннотации в классе, то, естественно, метод getAnnotations() в методе интерфейса возвращает null.
Следующее решение решило эту проблему:
final String methodName = pjp.getSignature().getName();
final MethodSignature methodSignature = (MethodSignature)pjp.getSignature();
Method method = methodSignature.getMethod();
if (method.getDeclaringClass().isInterface()) {
method = pjp.getTarget().getClass().getDeclaredMethod(methodName, method.getParameterTypes());
}
и если вам нравится, у вас есть возможность обрабатывать аннотации интерфейса здесь тоже.
Еще несколько комментариев доступны здесь: Получение экземпляра метода шаблона из ProceedingJoinPoint
Олег
Даже после изменения политики хранения, как сказал Божо, этот вызов для получения аннотации возвращает null:
targetMethod.getAnnotation(Restricted.class);
Что я нашел, вам нужно связать аннотацию. Учитывая, что интерфейс объявлен следующим образом:
@Retention(RetentionPolicy.RUNTIME)
public @interface Restricted {
String[] allowedRoles();
}
Совет должен быть объявлен следующим образом:
@Before("@annotation( restrictedAnnotation )")
public Object processRequest(final ProceedingJoinPoint pjp, Restricted restrictedAnnotation) throws Throwable {
String[] roles = restrictedAnnotation.allowedRoles();
System.out.println("Allowed:" + roles);
}
То, что это делает, - привязать аннотацию к параметру в сигнатуре метода, limitedAnnotation. Часть, о которой я не уверен, это то, как она получает тип аннотации, она, по-видимому, основана на параметре. И как только вы получите аннотацию, вы можете получить значения.
Почему бы вам просто не использовать Spring Безопасность? Это краткое введение и использование, я действительно не вижу смысла тратить время на создание колеса.
С Spring AOP, если у вас есть такая ситуация, как MyManagerImpl implements MyManager
, метод pointcut применяется к методу interface
, поэтому MethodSignature
описывает метод, определенный в MyManager
, который не имеет никакой аннотации. единственный способ найти это - проверить класс объекта jp.getTarget()
и получить соответствующий метод.