JavaのWebアプリケーション:カスタムレルムを使用します
-
23-08-2019 - |
質問
私は、Webサービス経由でログインを実行する必要があるのJava Webアプリケーションを書いています。もちろん、私は(のGlassFish v2)が使用しているアプリケーションサーバに付属のレルムのどれもトリックを行うことはできません。そこで私は自分自身を書かなければなりませんでした。私が書いたレルム実装は完全にGlassFishのために結ばれ、他のアプリケーションサーバであるとして使用することはできません、しかしそうです。
カスタムレルムを実装するための任意の標準または広くサポートされている方法はありますか? .warからそのレルムを展開することができどのような方法でそれをある、またはそれは常にサーバ自身のクラスパスからロードする必要があるのでしょうか?
解決
注:以下の答えは他の回答の一つに私の注意に持って来られたのJava EE 5のようにのみ有効である、のJava EE 6がこれをサポートしています。あなたは、Java EE 6を使用しているのであれば、この回答を読んで、それ以外の関連する答えを読んでいない。
私自身の研究から、この質問への回答から、私が見つけた答えは次のようである:JAASは、標準的なインターフェースですが、様々なアプリケーションサーバでJAASレルム+ LoginModuleを、書き展開と統合するための統一方法はありません。
のGlassFish v2はログインモジュールまたはレルム自身を実装する独自の内部クラスの一部を拡張する必要があります。 LoginModuleインタフェースの多くのメソッドは、Glassfishののスーパークラスの最後のマークされているので、あなたは、しかし、全体のログインプロセスをカスタマイズすることはできません。カスタムログインモジュールとレルムのクラスは、ASクラスパス(ないアプリケーションの)に置かなければならない、とレルムは、手動で(可能性の.warからの展開)登録されていないされている必要があります。
状況は、あなたが完全に独自のレルムとLoginModuleをコーディングせ、その後、あなたの実装レルムのに実際の作業を委任します独自のJAASRealmを(使用してアプリケーションサーバーにそれらを構成するであろう、Tomcatの少し良くなるようですそして、のLoginModule)。しかし、Tomcatはあなたの.warからカスタムレルムを展開ことはできません。
私の結果を示したアプリケーションサーバーのどれもが、すべてのJAASコールバックを最大限に活用することができるように思わないことに注意してください。それらのすべては、基本的なユーザ名+パスワード方式に対応しているようです。あなたはそれよりも複雑なものを必要とする場合は、あなたのJava EEコンテナによって管理されていない解決策を見つける必要があります。
参考のために、それは私の質問へのコメントにするために頼まれたので、ここで私はGlassfishV2のために書いたコードです。
まず、ここでのレルムの実装があります:
public class WebserviceRealm extends AppservRealm {
private static final Logger log = Logger.getLogger(WebserviceRealm.class.getName());
private String jaasCtxName;
private String hostName;
private int port;
private String uri;
@Override
protected void init(Properties props) throws BadRealmException, NoSuchRealmException {
_logger.info("My Webservice Realm : init()");
// read the configuration properties from the user-supplied properties,
// use reasonable default values if not present
this.jaasCtxName = props.getProperty("jaas-context", "myWebserviceRealm");
this.hostName = props.getProperty("hostName", "localhost");
this.uri = props.getProperty("uri", "/myws/EPS");
this.port = 8181;
String configPort = props.getProperty("port");
if(configPort != null){
try{
this.port = Integer.parseInt(configPort);
}catch(NumberFormatException nfe){
log.warning("Illegal port number: " + configPort + ", using default port (8181) instead");
}
}
}
@Override
public String getJAASContext() {
return jaasCtxName;
}
public Enumeration getGroupNames(String string) throws InvalidOperationException, NoSuchUserException {
List groupNames = new LinkedList();
return (Enumeration) groupNames;
}
public String getAuthType() {
return "My Webservice Realm";
}
public String getHostName() {
return hostName;
}
public int getPort() {
return port;
}
public String getUri() {
return uri;
}
}
そしてLoginModule実装ます:
public class WebserviceLoginModule extends AppservPasswordLoginModule {
// all variables starting with _ are supplied by the superclass, and must be filled
// in appropriately
@Override
protected void authenticateUser() throws LoginException {
if (_username == null || _password == null) {
throw new LoginException("username and password cannot be null");
}
String[] groups = this.getWebserviceClient().login(_username, _password);
// must be called as last operation of the login method
this.commitUserAuthentication(groups);
}
@Override
public boolean commit() throws LoginException {
if (!_succeeded) {
return false;
}
// fetch some more information through the webservice...
return super.commit();
}
private WebserviceClient getWebserviceClient(){
return theWebserviceClient;
}
}
最後に、レルムにログインモジュールに接続する必要があります。これは、GlassFishのV2にYOURDOMAIN /設定/ login.confにであるJAAS設定ファイルレベルで行われます。
:そのファイルの末尾に以下の行を追加します。myWebserviceRealm { // use whatever String is returned from you realm's getJAASContext() method
my.auth.login.WebserviceLoginModule required;
};
これは、GlassFishの上で私のために働いて物事を得たものです。ここでも、このソリューションは、アプリケーション・サーバー間で移植ではありませんが、私の知る限り、既存のポータブルソリューションはありません。
他のヒント
カスタムを実装するための任意の標準または広くサポートされている方法はあります レルム? .warからそのレルムをデプロイするためにどのような方法で可能であることを、または それは常にサーバ自身のクラスパスからロードする必要があるのでしょうか?
絶対にカスタムレルム、またはより一般的な用語でカスタム認証モジュールを実装するための標準的な方法があります。これは JASPIC / JASPI / JSR 196 SPI / API を介して行うことができます。 JASPICは、標準のいずれかの完全なJava EE 6実装の一部が、Java EE 6 Webプロファイルの、残念ながら一部ではありません。
しかし、JASPICは、Java EE 6の一部であるにも関わらず、それが最適なベンダーによってサポートされていません。 GlassFishのおよびWebLogicは、JBoss ASとGeronimoはもう少し問題があり、非常に優れた実装を持っているように見えます。このトピック(アニルSaldhana)上のJBossからのリードエンジニアであっても、彼はhref="https://community.jboss.org/wiki/JBossAS7EnablingJASPIAuthenticationForWebApplications#comment-10018">がデフォルト一瞬のために。 JBossで最も深刻なバグの数7.1は、最近固定になっているとしてではなく、のない公共のリリースはありませんとしてJBoss 7.1はもう、スケジュールおよび7.2 AS JBossはまだそれが今、少なくともJBossのJASPICのが面倒であるの手段として離れていくつかの時間です。
もう一つの不幸な問題は、実際の認証モジュールを標準化することができるということですが、標準化されているのようにそれを設定するには、何の宣言的な方法は、(XMLファイルを読み込む)ありません。
の.warからそのレルムをデプロイするためにどのような方法で可能です、またはそれをしません 常にサーバ自身のクラスパスからロードする必要がありますか?
JASPIC、認証モジュール(「レルム」)とは、実際の.warからロードすることができます。私は、これは仕様によって保証されているかどうかを100%わからないんだけど、私がテストした4台のサーバー(GlassFishのは、WebLogic、GeronimoとJBossのAS)の、それらはすべて、これをサポートします。 Geronimoは、残念ながらそのプログラムによる登録の競合状態のいくつかの種類を持っているので、あなたが二回ホットデプロイを実行して、醜い回避策を必要とするが、それは終わりでの.warからモジュールをロードしない場合ます。
独自のメカニズムのように、少なくともJBoss ASは常にの.warまたは.earファイルから(例えばorg.jboss.security.auth.spi.AbstractServerLoginModuleのサブクラス)モジュールをロードするサポートしています。
私は、いくつかのより多く持っていることが最近、このトピックについてのブログ記事を書きました詳細ます。
あなたはWARからレルムを展開ことはできません、それはコンテナアーティファクト(したがって句「コンテナベースのセキュリティ」)です。あなたは、コンテナによって提供される特定のレルムを使用するようにアプリを設定することができますが、アプリケーションはこの自体を提供することはできません。
これは、コンテナのすべてが異なっており、これらのレルムはポータブルではありませんが、あなたが移植を探しているなら、簡単な常識は、コンテナと統合するために必要なグルーコードの少しの違いを削減する、と述べました。
持つあなたは自分のアプリケーションサーバーの特定のクラスを拡張するカスタムLoginModuleを記述する必要がありますように見える太陽のドキュメントを簡単に見ています。これは、少し後方に私とGlassFishの限界のようです。
あなたはこのよりポータブルにしたい場合は、私が標準に代表団を標準のJavaEEインターフェース(複数可)に対して開発したカスタムのLoginModuleに実装の大部分を入れた後、Glassfishの特有の薄い実装層を有することをお勧めしたいです、ポータブルな実装ます。
の このテーマに関するSunの記事のチェックアウト強い>。
私は実際にこれを自分でやったことはありませんが、私はあなたがそれの上に新たな領域(セキュリティドメイン)を登録するためのオプションを与えるので、各かなり確信しています。
これはおそらく100%移植できないだろう、とあなたASごとに異なる設定XMLを必要とするかもしれないが、基本的には、コードがするための理由はありません任意の異なるます。