Я пытаюсь использовать Apache Shiro для сервера RMI с подключением нескольких клиентов.Apache Shiro Annotation AOP и RMI
Архитектура, которую я хочу иметь, представляет собой несколько однопользовательских сервисов, зарегистрированных в реестре RMI. Каждый из них имеет метод входа, который возвращает новую экспортированную услугу клиентом. Поэтому я могу в сервисе каждого клиента сохранить окончательную ссылку на объект-клиент.
С Shiro я буду использовать аннотацию @RequireRoles и т. Д. На услуги клиентов.
Мой вопрос заключается в том, как перехватить Аспект всех аннотаций @RequireRoles и просто установить тему со ссылкой в сервисе?
Я мог бы написать свои собственные аннотации @AllowRoles (String []) и мой собственный Аспект, чтобы получить совместное действие (услугу) с «этим» и получить ссылку на клиента и проверить, имеет ли клиент эти роли. Но я бы предпочел использовать хороший фрейм и не кодировать все с начала ...
То же самое относится к @Transactional, но я не использую SpringAOP.
How to organize RMI Client-Server architecture
Correct way to use Apache Shiro on distributed system using RMI?
EDIT: я мог бы найти решение, но не уверен, что это хороший: Без приоритета он не будет работать должным образом или не работать вообще, если объект является недействительным.
public aspect TestIntercept {
private static final Logger log = LoggerFactory.getLogger(TestIntercept.class);
declare precedence : TestIntercept, org.apache.shiro.aspectj.ShiroAnnotationAuthorizingAspect;
pointcut allow(): execution(@org.apache.shiro.authz.annotation.RequiresPermissions * *(..)) || execution(@org.apache.shiro.authz.annotation.RequiresRoles * *(..));
before(): allow(){
log.info("Before, in log2");
Signature sig = thisJoinPointStaticPart.getSignature();
String line = String.valueOf(thisJoinPointStaticPart.getSourceLocation().getLine());
String sourceName = thisJoinPointStaticPart.getSourceLocation()
.getWithinType().getCanonicalName();
System.out.println("Call2 from " + sourceName + " line " + line + "\n to "
+ sig.getDeclaringTypeName() + "." + sig.getName() + "\n");
log.info("Got subject from service: " + ((Service) thisJoinPoint.getThis()).getSubject().isAuthenticated());
log.info("Got subject from service: " + ((Service) thisJoinPoint.getThis()).getSubject().getPrincipal());
// Subject subject = ((Service) thisJoinPoint.getThis()).getSubject();
/*
Subject subject = new Subject.Builder()
.authenticated(true)
.principals(new SimplePrincipalCollection("fake", "realmm"))
.buildSubject();
//*/
//*
Subject subject = SecurityUtils.getSubject();
subject.logout();
subject.login(new UsernamePasswordToken("fake2", "11"));
//*/
ThreadState threadState = new SubjectThreadState(subject);
threadState.bind();
}
}
Я не отвязать предмет из контекста потока, потому что любой вызов метода службы будет убедиться, что пользователь сервиса связан с запущенным потоком.
Я мог бы использовать вместо bind, use: subject.execute (() -> {return continue()}); в совете «вокруг», чтобы автоматически очистить threadConext, но действительно ли это необходимо?
Спасибо за любую помощь