私は、Java EEアプリケーションでユーザーを安らかに認証するために使用できるオプションを評価することに時間を費やしてきました。
したがって、以下にリストされているオプションが有効であるかどうか、および利点または欠点に関する記述とともに提案してください. 認証方法を実行可能にする詳細が不足している可能性があります。または、私が見逃した別のオプションがある可能性があります(ここでも厳密に Java EE について話しているため、クエリ認証はありません。EE 準拠の方法で実行できない限り、そうではありません)。
1.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>
利点
これは REST フレンドリーな認証方法です。AJAX 呼び出しを介して認証資格情報を送信できます。ユーザーが認証されると、ブラウザーはすべての要求に適切な
Authorization: Basic/Digest QWxhZGRpbjpvcGVuIHNlc2FtZQ==
ヘッダーを付けます。資格情報が正しくない場合、ユーザーには醜いブラウザーのログイン画面が表示されます。それを受け入れることができる場合は、BASIC/DIGEST 認証が適しています。Digest の場合、サーバーに渡される文字列は MD5 で暗号化された文字列であり、Basic (「user:password」文字列の Base64 エンコーディング) よりも確実に安全ですが、解読可能です。したがって、セキュリティに関しては、BASIC は FORM 認証とほぼ同じくらい安全であり、DIGEST はそれらすべての中で最も安全です。結論として、サイトが完全に HTTPS である場合 (一部のリソースが HTTP 経由で取得される場合、たとえば、認証ヘッダーがサード パーティに表示されるため)、BASIC/DIGEST を使用しても安全です。
- セットアップが簡単。
短所
- ログアウトは実装が難しいです。hereとhereを参照してください。確かに、ユーザーを認証する素晴らしい AJAX 要求がありますが、?AJAX? も必要です。ユーザーをログオフする要求 - ブラウザーのログイン ウィンドウが再び表示されるようにトリガーします)。ところで、素敵なサーブレット 3.0 の request.logout() メソッドは、この場合正しく機能しません。
- セッション タイムアウトの実装は非常に困難です。セッションの有効期限は発生しますが (これはサーブレット コンテナーの仕事です)、ブラウザーは次の要求で承認ヘッダーを送信し、再認証をトリガーします。
- パーソナライズされたログイン ページはありません。なし。
- 認証されたセッションを追跡するのは困難です。
2.フォームベースの認証
<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
タグで構成されたログイン ページが表示されます。パスワードに問題がなければ、最初に要求されたprotected/*
URL に転送されます (302 Paged Moved Permanently)。パスワードが NOK の場合、ユーザーはエラー ページに転送されます (302 Paged Moved Permanently)。
利点
- パーソナライズされたログイン ページ - これが最も人気があるようです :)
- ログオフは簡単に実装できます。HttpSession を無効にするか、request.logout() メソッド (サーブレット 3.0) を呼び出すだけで済みます。
- セッションのタイムアウト
- IF および ONLY ログイン用に別のページを使用することを受け入れる場合は、これが解決策です。
短所
- REST に不親切 (休息の哲学を掘り下げるつもりはありません。また、サーバー側の状態を維持することは RESTful な議論ではありません。Java EE の方法で REST 認証を分析しており、サーバー側の状態は、認証されたサブジェクトに対して常に維持されます) . FORM 認証を使用することの本当に悪い点は、ブラウザー間で一貫した動作を行うことができないという事実です。これはすべて、一部のブラウザーが AJAX 応答関数で処理する 302 リダイレクトによるものですが、他のブラウザーはページ全体をリダイレクトします (ナビゲーション バーで URL を変更します)。詳細はこちらとこちら。その 302 リダイレクトを回避することはできないため、FORM および REST 認証はありません。
3. プログラムによる認証
認証用の URL を設定します。その URL の背後に、ログイン モジュール (JAAS の方法) をインスタンス化し、認証情報と共に HttpServletRequest.login(user,pass) メソッドを呼び出すサーブレットを配置できます。ログインに失敗すると、401/403 応答が生成されます。
web.xml で security-constraints を指定するだけで実装できます。
<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());
利点
- パーソナライズされたログインページ。
- AJAX/REST 互換
- ログアウト URL (ログアウトするように URL が設定されている場合)
- セッション タイムアウト (コンテナー管理)
- 応答でログイン データ (ユーザー名、電子メール、ロール、グループなど) を返すことができます (ログインが成功した後に別の呼び出しを行う必要がないため、非常に便利です)。
短所
- 少しコードを書く必要があります。
- アプリケーションが 401/403 応答を処理し、ログイン ウィンドウを表示できる必要がある
結論として、実行可能な最良のオプションは次のとおりです。
- セッションのタイムアウトやログアウトを気にしない場合 --> DIGEST
- 上記がうまくいかず、ログイン ページ (またはモーダル パネルのようなページ) を埋め込む必要がなく、認証用に 1 つのページで問題ない場合 --> FORM
- 上記がうまくいかず、世界中のすべての柔軟性と互換性が必要な場合は、PROGRAMMATIC アプローチを使用してください。ログイン/ログアウト URL を定義する必要があり、クライアント コードは 401/403 応答に対応できる必要があります (簡単ではありません)。
実行可能な代替ソリューションを提案することを本当に楽しみにしています。今のところ、私はPROGRAMMATICアプローチを採用するのが嫌いだからです