複数のクライアントが接続しているRMIサーバーにApache Shiroを使用しようとしています。Apache Shiro注釈AOPとRMI
私が持っているアーキテクチャは、RMIの登録簿に登録されているシングルトンサービスです。それぞれには、クライアントによって新しいエクスポートされたサービスを返すログインメソッドがあります。 各クライアントのサービスで、クライアントオブジェクトへの最終参照を保持できます。
私は、クライアントのサービスで注釈@RequireRolesなどを使用します。
私の質問は、すべての注釈@RequireRolesのアスペクトをインターセプトして、サービス内の参照で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?
EDIT: 私は解決策を発見したかもしれないがわからない、それは良いものです:それは正常に動作しないか、被写体がnullの場合、まったく動作しないでしょう 優先しないと。
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の代わりに使うことができます:subject.execute(() - > {return proceed()}); "around"というアドバイスの中で自動的にthreadConextがクリアされますが、本当に必要ですか? around
ため