【发布时间】:2017-06-10 12:09:07
【问题描述】:
我正在尝试将 Apache Shiro 用于连接多个客户端的 RMI 服务器。
我想要的架构是在 RMI 的寄存器中注册的一些单例服务。他们每个人都有一个登录方法,该方法由客户端返回一个新的导出服务。 所以我可以在每个客户端的服务中保留对客户端对象的最终引用。
对于 Shiro,我将在客户服务上使用注解 @RequireRoles 等。
我的问题是如何截取所有注解@RequireRoles 的Aspect 并在服务中使用引用设置Subject?
我可以编写自己的注释@AllowRoles(String[]) 和我自己的Aspect 来获取带有“this”的jointPoint(服务)并获取对客户端的引用并检查客户端是否具有这些角色。 但我宁愿使用一个好的框架,而不是从头开始编写所有代码......
这同样适用于@Transactional,但我不使用 SpringAOP。
How to organize RMI Client-Server architecture
Correct way to use Apache Shiro on distributed system using RMI?
编辑: 我可能已经找到了一个解决方案,但不确定它是否是好的解决方案: 如果没有优先级,如果主题为空,它将无法正常工作或根本无法工作。
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();
}
}
我没有将主题与线程上下文解除绑定,因为对服务方法的任何调用都会确保服务的用户绑定到正在执行的线程。
我可以使用而不是绑定,使用:subject.execute(()->{returnproceed()});在“周围”的建议中自动清除 threadConext,但真的有必要吗?
感谢您的帮助
【问题讨论】:
标签: java rmi spring-aop interceptor shiro