に、私は増加アクセス粒度別にセキュリティロールを追加するためのあなたの条件を理解していません。コードが静的でないモジュラー環境でこの要件を確認できました。この場合、後で展開することで宣言された追加のセキュリティロールをサポートする必要があります。
私は、似たような実装にサポートするセキュリティシステム持っていた、言った:
- を再デプロイすることなく、役割を削除/(宣言)を追加することは、
- これらの役割にユーザーを関連付けます。
私がやったことを抽象度の高いレベルで説明し、いくつかの役に立つアイデアを与えることを願っています。
@Singleton
@LocalBean
public class MySecurityDataManager {
public void declareRole(String roleName) {
...
}
public void removeRole(String roleName) {
...
}
/**
* Here, I do not know what your incoming user data looks like such as:
* do they have groups, attributes? In my case I could determine user's groups
* and then assign them to roles based on those. You may have some sort of
* other attribute or just plain username to security role association.
*/
public void associate(Object userAttribute, String roleName) {
...
}
public void disassociate(Object userAttribute, String roleName) {
...
}
/**
* Here basically you inspect whatever persistence method you chose and examine
* your existing associations to build a set of assigned security roles for a
* user based on the given attribute(s).
*/
public Set<String> determineSecurityRoles(Object userAttribute) {
...
}
}
次にカスタムjavax.security.auth.spi.LoginModule
を実装:
まず第一に、このような何かを@EJB
を実装します。私は抽象的な実装があなたのために働くことをコンテナが分かっていない限り、ゼロから実装することをお勧めします。
:また、私はあなたがいない場合、あなたがより良い私が取得していますかを理解するために、次のように慣れる示唆します
public class MyLoginModule implements LoginModule {
private MySecurityDataManager srm;
@Override
public void initialize(Subject subject, CallbackHandler callbackHandler,
Map<String, ?> sharedState, Map<String, ?> options) {
// make sure to save subject, callbackHandler, etc.
try {
InitialContext ctx = new InitialContext();
this.srm = (MySecurityDataManager) ctx.lookup("java:global/${your specific module names go here}/MySecurityDataManager");
} catch (NamingException e) {
// error logic
}
}
@Override
public boolean login() throws LoginException {
// authenticate your user, see links above
}
@Override
public boolean commit() throws LoginException {
// here is where user roles get assigned to the subject
Object userAttribute = yourLogicMethod();
Set<String> roles = srm.determineSecurityRoles(userAttribute);
// implement this, it's easy, just make sure to include proper equals() and hashCode(), or just use the Jboss provided implementation.
Group rolesGroup = new SimpleGroup("Roles", roles);
// assuming you saved the subject
this.subject.getPrincipals().add(rolesGroup);
}
@Override
public boolean abort() throws LoginException {
// see links above
}
@Override
public boolean logout() throws LoginException {
// see links above
}
}
動的な構成(ロールの宣言、ユーザーの関連付けなど)を可能にするには、UIを構築しますtは同じ@EJB MySecurityDataManager
を使用して、ログインモジュールがセキュリティロールを決定するために使用するセキュリティ設定をCRUDします。
ここでは、これらを適切な方法でパッケージ化することができます。MyLoginModule
がMySecurityDataManager
を検索し、コンテナに展開することを確認してください。私はJBossに取り組んでいましたが、あなたはJBossについて言及しました。より堅牢な実装には、LoginModuleのコンフィグレーションの検索文字列が含まれます。これは、実行時にinitialize()
メソッドのオプションマップから読み取ることができます。ここでのJBossの設定例を示します:
<security-domain name="mydomain" cache-type="default">
<authentication>
<login-module flag="required"
code="my.package.MyLoginModule"
module="deployment.${your deployment specific info goes here}">
<module-option name="my.package.MySecurityDataManager"
value="java:global/${your deployment specific info goes here}/MySecurityDataManager"/>
</login-module>
</authentication>
</security-domain>
この時点では、コンテナ内の他の展開のセキュリティを管理するには、このセキュリティドメインmydomain
を使用することができます。ここで
はカップルの使用シナリオです:
- は新しい.warファイルを展開し、
mydomain
セキュリティドメインに割り当てます。 .warには、コード全体にあらかじめ定義されたセキュリティ注釈が付いています。セキュリティ・レルムには最初はないため、ユーザーはログインできません。しかし、デプロイ後は、セキュリティ・ロールが十分に文書化されているため、書いたmydomain
構成インタフェースを開き、それらのロールを宣言してからユーザーを割り当てます。今すぐログインすることができます。
- 数ヶ月の展開後、ユーザーはもはや戦争の特定の部分にアクセスできなくなります。 .warのその部分に関係するセキュリティロールを
mydomain
から削除し、誰もそれを使用できなくなります。
最高の部分、特に#2は再配置されません。また、アノテーションで宣言されたデフォルトのセキュリティ設定をオーバーライドする編集XMLはありません(これはあなたのインタフェースがそれより優れていると仮定しています)。
乾杯! もっと詳しく説明しますが、今のところ、少なくとも必要とするかどうかを教えてください。
ありがとうございます。 1.私のコードで '@ DeclareRoles'を使用したくない理由は静的であり、ロールは時間の経過とともに(メンテナンス)変更できるからです。 2.1 RESTコード内にユーザー名だけを持つことは望ましくありません。私が現在の名前を持っていない深い文脈について考えてみると、いつも彼を提供することはできません。私はreqeustヘッダーからパラメータを簡単に読み取ることができますが、それは私の目的ではありません。 2.2私は 'SesseionContext'とユーザ役割でJEEセキュリティを持つのが好きですが、なぜそれはプログラム的ではなく静的でなければならないのですか? –
ちょうど質問のために "ちょうどそれは静的でなければならず、プログラム的ではないのですか?"アプリケーションは一般的に言えば、再デプロイメントなしでセキュリティ保護可能な機能を動的に増やすべきではないため、ロールは静的です。 web.xmlやBeanでロールを指定するかどうかを決めることで、コードのメンテナンスを容易にすることができますが、コードの再デプロイを避けるほうがよいでしょう。 – Xiangyu
良い点とweb.xml内でそれを変更することは大したことではありません(再デプロイメントは必要ありません)。私は間違いなくそれを検討します。私のプロジェクトでは、何かが変更された場合には再デプロイしないことが重要です。なぜなら、コードに触れたくない、あるいはベンダーにいつもそれをさせることを望まないクライアントのためのカスタムコードだからです。それは簡単な設定可能なソリューションを探していた理由です。しかしそれとは別に、私は自分のアプローチをする方法があると思っていました。できるだけ多くの回答を得るために賞金を開いていきます:D –