Apache Shiro 注解 AOP 和 RMI

Apache Shiro Annotation AOP and RMI

我正在尝试将 Apache Shiro 用于连接多个客户端的 RMI 服务器。

我想要的架构是在RMI 的寄存器中注册的一些单例服务。他们每个人都有一个登录方法,即 return 客户端新导出的服务。 所以我可以在每个客户的服务中保留对客户对象的最终引用。

对于 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(()->{return proceed()});在建议 "around" 中自动清除 threadConext 但真的有必要吗?

感谢您的帮助

+1 代表 around

请在 nabble 上跟进 post: http://shiro-user.582556.n2.nabble.com/How-to-make-RMI-work-with-Apache-Shiro-td7581467.html