SpringWebアプリへのログイン–エラー処理とローカリゼーション
1. 概要
この記事では、バックエンドでSpring Securityを使用して認証を処理するアプリケーションに対して、SpringMVCを使用して単純なログインページを実装する方法を説明します。
Spring Securityでログインを処理する方法の詳細については、ここにその構成と実装について詳しく説明している記事があります。
2. ログインページ
非常に単純なログインページを定義することから始めましょう:
<html>
<head></head>
<body>
<h1>Login</h1>
<form name='f' action="login" method='POST'>
<table>
<tr>
<td>User:</td>
<td><input type='text' name='username' value=''></td>
</tr>
<tr>
<td>Password:</td>
<td><input type='password' name='password' /></td>
</tr>
<tr>
<td><input name="submit" type="submit" value="submit" /></td>
</tr>
</table>
</form>
</body>
</html>
次に、フォームを送信する前に、ユーザー名とパスワードが入力されていることを確認するクライアント側のチェックを含めましょう。 この例では、プレーンなJavascriptを使用しますが、JQueryも優れたオプションです。
<script type="text/javascript">
function validate() {
if (document.f.username.value == "" && document.f.password.value == "") {
alert("Username and password are required");
document.f.username.focus();
return false;
}
if (document.f.username.value == "") {
alert("Username is required");
document.f.username.focus();
return false;
}
if (document.f.password.value == "") {
alert("Password is required");
document.f.password.focus();
return false;
}
}
</script>
ご覧のとおり、usernameまたはpasswordフィールドが空かどうかを確認するだけです。 そうである場合–javascriptメッセージボックスが対応するメッセージとともにポップアップ表示されます。
3. メッセージのローカリゼーション
次へ–フロントエンドで使用しているメッセージをローカライズしましょう。 このようなメッセージにはいくつかの種類があり、それぞれが異なる方法でローカライズされます。
- フォームが前に生成されたメッセージは、Springのコントローラーまたはハンドラーによって処理されます。 これらのメッセージはJSPページで参照でき、 Jsp / Jsltローカリゼーションでローカライズされます(セクション4.3を参照)。
- Springによる処理のためにページが送信されると( login フォームを送信した後)ローカライズされたメッセージ。 これらのメッセージは、 Spring MVCローカリゼーションを使用してローカライズされます(セクション4.2を参照)。
3.1. message.propertiesファイル
いずれの場合も、サポートする言語ごとにmessage.propertiesファイルを作成する必要があります。 ファイルの名前は、 messages_ [localeCode].propertiesの規則に従う必要があります。
たとえば、英語とスペイン語のエラーメッセージをサポートする場合は、messages_en.propertiesおよびmessages_es_ES.propertiesというファイルがあります。 英語の場合– messages.propertiesも有効であることに注意してください。
これらの2つのファイルをプロジェクトのクラスパス( src / main / resources )に配置します。 ファイルには、さまざまな言語で表示する必要のあるエラーコードとメッセージが含まれているだけです。例:
message.username=Username required
message.password=Password required
message.unauth=Unauthorized access!!
message.badCredentials=Invalid username or password
message.sessionExpired=Session timed out
message.logoutError=Sorry, error login out
message.logoutSucc=You logged out successfully
3.2. SpringMVCローカリゼーションの構成
SpringMVCはLocaleResolverを提供し、その LocaleChangeInterceptor APIと連携して、ロケール設定に応じてさまざまな言語でメッセージを表示できるようにします。 ローカリゼーションを構成するには– MVC構成で次のBeanを定義する必要があります:
@Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("lang");
registry.addInterceptor(localeChangeInterceptor);
}
@Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
return cookieLocaleResolver;
}
デフォルトでは、ロケールリゾルバーはHTTPヘッダーからロケールコードを取得します。 デフォルトのロケールを強制するには、 localeResolver()に設定する必要があります。
@Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
cookieLocaleResolver.setDefaultLocale(Locale.ENGLISH);
return cookieLocaleResolver;
}
このロケールリゾルバーはCookieLocaleResolverです。これは、ロケール情報をクライアント側のCookieに保存することを意味します。 そのため、ユーザーがログインするたびに、また訪問中はユーザーのロケールを記憶します。
または、 SessionLocaleResolver があり、セッション全体でロケールを記憶します。 このLocaleResolverを代わりに使用するには、上記のメソッドを次のように置き換える必要があります。
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
return sessionLocaleResolver;
}
最後に、 LocaleChangeInterceptor は、ログインページで簡単なリンクによって送信されるlangパラメーターの値に基づいてロケールを変更することに注意してください。
<a href="?lang=en">English</a> |
<a href="?lang=es_ES">Spanish</a>
3.3. JSP/JSLTローカリゼーション
JSP / JSLT APIは、jspページ自体でキャッチされたローカライズされたメッセージを表示するために使用されます。 jspローカリゼーションライブラリを使用するには、pom.xmlに次の依存関係を追加する必要があります。
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.2-b01</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
4. エラーメッセージの表示
4.1. ログイン検証エラー
JSP / JSPLサポートを使用し、ローカライズされたメッセージを login.jsp に表示するには、ページに次の変更を実装します。
1. 次のタグlib要素をlogin.jspに追加します。
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
2. messages.propertiesファイルを指すjsp/jslt要素を追加します。
<fmt:setBundle basename="messages" />
3. 以下を追加します
<fmt:message key="message.password" var="noPass" />
<fmt:message key="message.username" var="noUser" />
4. エラーメッセージをローカライズするために、セクション3で見たログイン検証スクリプトを変更します。
<script type="text/javascript">
function validate() {
if (document.f.username.value == "" && document.f.password.value == "") {
alert("${noUser} and ${noPass}");
document.f.username.focus();
return false;
}
if (document.f.username.value == "") {
alert("${noUser}");
document.f.username.focus();
return false;
}
if (document.f.password.value == "") {
alert("${noPass}");
document.f.password.focus();
return false;
}
}
</script>
4.2. ログイン前のエラー
前の操作が失敗した場合、ログインページにエラーパラメータが渡されることがあります。 たとえば、登録フォームの送信ボタンはログインページをロードします。 登録が成功した場合は、ログインフォームに成功メッセージを表示し、反対の場合はエラーメッセージを表示することをお勧めします。
以下のサンプルログインフォームでは、and regSuccおよびregErrorパラメーターをインターセプトし、それらの値に基づいてローカライズされたメッセージを表示することにより、これを実装しています。
<c:if test="${param.regSucc == true}">
<div id="status">
<spring:message code="message.regSucc">
</spring:message>
</div>
</c:if>
<c:if test="${param.regError == true}">
<div id="error">
<spring:message code="message.regError">
</spring:message>
</div>
</c:if>
4.3. ログインセキュリティエラー
何らかの理由でログインプロセスが失敗した場合、SpringSecurityはログインエラーURLにリダイレクトします。これは/login.html?error=trueと定義されています。
したがって、ページに登録のステータスを表示する方法と同様に、ログインの問題が発生した場合にも同じことを行う必要があります。
<c:if test="${param.error != null}">
<div id="error">
<spring:message code="message.badCredentials">
</spring:message>
</div>
</c:if>
を使用していることに注意してください
js検証とこれらの追加のステータスメッセージを含む完全なログインページは、githubプロジェクトにあります。
4.4. ログアウトエラー
次の例では、jspコード
たとえば、カスタムログアウトハンドラがログアウトページにリダイレクトする前にユーザーデータを保存しようとしたときに永続性例外が発生した場合。 これらのエラーはまれですが、可能な限り適切に処理する必要があります。
完全なlogout.jspを見てみましょう。
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="sec"
uri="http://www.springframework.org/security/tags"%>
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<c:if test="${not empty SPRING_SECURITY_LAST_EXCEPTION}">
<div id="error">
<spring:message code="message.logoutError">
</spring:message>
</div>
</c:if>
<c:if test="${param.logSucc == true}">
<div id="success">
<spring:message code="message.logoutSucc">
</spring:message>
</div>
</c:if>
<html>
<head>
<title>Logged Out</title>
</head>
<body>
<a href="login.html">Login</a>
</body>
</html>
ログアウトページもクエリ文字列paramlogSucc を読み取り、その値が true に等しい場合、ローカライズされた成功メッセージが表示されることに注意してください。
5. Springセキュリティ構成
この記事の焦点は、バックエンドではなく、ログインプロセスのフロントエンドです。そのため、セキュリティ構成の要点について簡単に説明します。 完全な構成については、前の記事をお読みください。
5.1. ログインエラーURLへのリダイレクト
次のディレクティブ
authentication-failure-url="/login.html?error=true"
5.2. ログアウト成功リダイレクト
<logout
invalidate-session="false"
logout-success-url="/logout.html?logSucc=true"
delete-cookies="JSESSIONID" />
logout-success-url 属性は、ログアウトが成功したことを確認するパラメーターを使用して、ログアウトページにリダイレクトするだけです。
6. 結論
この記事では、Spring Securityがサポートするアプリケーションのログインページを実装する方法を説明しました。ログイン検証の処理、認証エラーの表示、メッセージのローカリゼーションです。
次の記事では、完全な登録の実装について説明します。これは、ログインと登録のプロセスの完全な実装を本番環境で使用できるようにすることを目的としています。