2013-05-23 6 views
19

私は、Java EEアプリケーションで、ユーザーを安心して認証するために利用できるオプションを評価するのに少し時間を費やしてきました。Java EEのRESTfulな認証

以下のオプションが長所と短所に関する声明とともに有効であるかどうかをご提案ください。それは、私が認証方法を実行可能にするかもしれない詳細が欠落している可能性があります。それとも、

1(再び、私たちは厳格なJava EEのでクエリなし認証とそれがEEに準拠した方法で行うことができない場合を除きを話している)私が見逃している別のオプションがあることかもしれません。DIGEST/BASIC認証

<security-constraint> 
    <web-resource-collection> 
     <web-resource-name>admin</web-resource-name> 
     <url-pattern>/protected/*</url-pattern> 
    </web-resource-collection> 
    <auth-constraint> 
     <role-name>admin</role-name> 
    </auth-constraint> 
</security-constraint> 
<login-config> 
    <auth-method>DIGEST/BASIC</auth-method> 
    <realm-name>as-defined-secuity-realm</realm-name> 
</login-config> 

利点

  1. これはRESTに適した認証方法です。 AJAXコールを介して認証資格情報を送信することができます。ユーザが認証されると、ブラウザは適切なAuthorization: Basic/Digest QWxhZGRpbjpvcGVuIHNlc2FtZQ==ヘッダーを持つすべての要求に同行します。悪い信用証明書の場合は、醜いブラウザのログイン画面が表示されます。もしあなたがそれを利用することができれば、BASIC/DIGEST認証があなたのための方法です。

  2. ダイジェストの場合、サーバーに渡される文字列はMD5で暗号化された文字列であり、Basic(「user:password」文字列のBase64エンコード)よりはるかに安全ですが、それにもかかわらずdecipherableです。したがってセキュリティの面では、BASICはFORM認証ほど安全であり、DIGESTはその中で最も安全です。結論として、あなたのサイトが完全にHTTPSの場合(つまり、が全部)、HTTP経由で取得されたリソースがあれば、認証ヘッダーなどが第三者に表示されるため、BASIC/DIGESTと一緒に行くことができます。

  3. セットアップが簡単です。

デメリット

  1. 実装するのが難しいですログアウト。 herehereを参照してください。ユーザーを認証する素晴らしいAJAXリクエストがありますが、AJAXも必要ですか?ユーザーからログオフする要求 - ブラウザのログインウィンドウが再度表示される)。いいサーブレット3.0のrequest.logout()メソッドdoes not work properly in this caseをBTWに送ってください。
  2. セッションタイムアウトを実装するのは非常に難しいです。セッションの有効期限が切れる(サーブレットコンテナのジョブです)が、ブラウザは次のリクエストで承認ヘッダーを送信し、再認証をトリガーします。
  3. パーソナライズされたログインページはありません。なし。
  4. 認証されたセッションを追跡するのが難しい。

2。FORMベースの認証

<security-constraint> 
    <web-resource-collection> 
     <web-resource-name>admin</web-resource-name> 
     <url-pattern>/protected/*</url-pattern> 
    </web-resource-collection> 
    <auth-constraint> 
     <role-name>admin</role-name> 
    </auth-constraint> 
</security-constraint> 
<login-config> 
    <auth-method>FORM</auth-method> 
    <realm-name>as-defined-security-realm</realm-name> 
    <form-login-config> 
     <form-login-page>/auth/login.html</form-login-page> 
     <form-error-page>/auth/error.html</form-error-page> 
    </form-login-config> 
</login-config> 

かいつまんユーザーがprotected/* URLにアクセスする場合、ログインページは応じてが含まれています。したがって、ユーザーはコンテンツの代わりに、form-login-pageタグで設定されたログインページを取得します。パスワードがOKであれば、最初に要求されたprotected/*のURLに転送されます(302ページが永久に移動しました)。パスワードがNOKの場合、ユーザーはエラーページに転送されます(302ページ移動が永続的に行われます)。

利点

  1. パーソナライズログインページ - この1つは、最も人気があるようです:)
  2. ログオフは、実装が容易です。 HttpSessionを無効にするか、request.logout()メソッド(Servlet 3.0)を呼び出すだけで済みます。
  3. セッションタイムアウト
  4. IFとオンリーログイン用に別のページを持つことを承諾した場合は、これが解決策です。 (私は休みのphylosophyと保管サーバ側の状態で掘るつもりはない無愛想

デメリット

  1. RESTはRESTfulな議論ではない。我々はでREST認証を分析していますJAVA EEの方法とサーバー側の状態は、認証されたサブジェクトに対して常に維持されます)。フォーム認証を使用するのが本当に悪いのは、ブラウザ間で一貫した動作をすることができないという事実です。また、AJAXの応答関数では一部のブラウザが処理し、ページ全体をリダイレクトする(ナビゲーションバーのURLを変更する)302リダイレクトが原因です。詳細はherehereです。その302リダイレクトを回避することはできませんので、FORMとRESTの認証は必要ありません。

3.プログラムによる認証

は、認証のためのURLを設定します。このURLの後ろには、ログインモジュール(JAASの方法)をインスタンス化し、資格情報とともにHttpServletRequest.login(user、pass)メソッドを呼び出すサーブレットを持つことができます。ログインに失敗すると、401/403応答を生成するはずです。

あなたは自分のweb.xmlにセキュリティ制約を指定することによって、それを実装することができます。サーバー側で

<security-constraint> 
    <web-resource-collection> 
     <web-resource-name>admin</web-resource-name> 
     <url-pattern>/protected/*</url-pattern> 
    </web-resource-collection> 
    <auth-constraint> 
     <role-name>admin</role-name> 
    </auth-constraint> 
</security-constraint> 

をあなたは、単に発信者を認証するRESTfulなサービスを設定する必要があります。

@Path("/auth") 
@ApplicationPath("/rest") 
public class AuthenticationRestFacade { 

@POST 
@Path("/login") 
@Consumes(MediaType.APPLICATION_JSON) 
@Produces(MediaType.APPLICATION_JSON) 
public User login(User loginInfo, @Context HttpServletRequest request) throws LoginException, ServletException { 

    // nasty work-around for Catalina AuthenticatorBase to be able to 
    // change/create the session cookie 
    request.getSession(); 
    request.login(loginInfo.getName(), loginInfo.getPassword()); 

利点

  1. Personlizedログインページ:ここではいくつかのサンプルコードです。(URLがそうするように設定されている場合)
  2. AJAX/REST互換
  3. ログアウトURL
  4. セッションのタイムアウト(コンテナ管理)
  5. あなたはログインデータ(ユーザー名、電子メール、役割、グループなどを返すことができます。 。)(reaaaallly素敵な応答であなたがログイン成功後、別の呼び出しを行う必要はありませんので)

デメリット

  1. コードの書き方が少し必要です。
  2. アプリケーションは、最高の実行可能な選択肢と結論するには403分の401のレスポンスと表​​示ログイン画面

を処理できるようにする必要があります:あなたはセッションタイムアウトまたはログアウト気にしないのであれば

  1. を - > DIGEST
  2. 上記がうまくいかず、埋め込みログインページ(またはモーダルパネルのようなページ)を持っていなくても、認​​証のための単一のページでうまくいけば - > FORM
  3. 上記の場合世界中の柔軟性と互換性をPROGRAMMATICのアプローチにしたいと思っています。ログイン/ログアウトURLを定義する必要があります。また、クライアントコードは401/403応答(容易ではない)に対応できる必要があります。

実用的な代替ソリューションの提案を本当に楽しみにしています。そのため、今私は、これらはRESTfulなですが、少なくとも以下に対処するのが良いでしょうか。おそらく議論の余地がプログラム的なアプローチ

+1

あなたが言及していない1つのJava EEオプションは、おそらくJASPICです。これは完全なJava EE 6プロファイルで利用可能であり、認証をどのように配置するかについて多くの自由を提供します。 –

+0

正直なところ私は十分な成熟していないので、JASPICと一緒に行かないだろう。ところで、JASPIC @Arjanに関する素晴らしいチュートリアル。 – victor

+0

うわー、この質問の愛。私ももっと知りたいです。しかし、非常に良い質問。 – mikato

答えて

0

で行くことを憎むでしょう:

何Keberosは? Windows ADなどの認証サーバーを使用します。

公開キー証明書?クライアント提供の証明書を使用してユーザーを特定する...

のトークン? OpenIDなどのサードパーティのトークン発行者...

3

私の経験では、Java EE認証と認可サービスを使用して、RESTサービスとJSPやJSFのようなサーバー側のMVCの両方で機能するシステムを実装するのは難しいです同時。すべての私の経験は、MVCの部分のためのフォームベース認証とRESTサービスのためのある種のトークン認証(OAuth、Kerberos、LTPA)を使用することに傾いています。 RESTサービスにフォーム認証または基本認証を使用するのは通常は困難でしたが、2つのプロジェクトで正常に動作しましたが、

これはまた、優先サーバーの実装によって異なります。

関連する問題