Spring Security、Javascript、および AJAX によってログイン時のユーザー エクスペリエンスを向上させるには、サーバとクライアントの両方で構成を調整する必要があります。これらの調整は、通常の Spring Security ログイン メカニズムに対する機能強化として行い、その強化されたログイン プロセスと並行して通常のフォームベースのログインも引き続き機能するようにします。
注:これらの調整は、Spring MVC ベースのアプリケーションに対して行う必要があります。
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.0.5.RELEASE</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>3.0.5.RELEASE</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>3.0.5.RELEASE</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Spring Security の構成
<http>
<form-login>
<logout />
<remember-me />
<intercept-url pattern="/resources/**" filters="none" />
<intercept-url pattern="/" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/secure" access="ROLE_USER" />
<intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" />
</http>
</form-login>
<authentication-manager alias="authenticationManager">
<authentication-provider>
<user-service>
<user name="frank" password="1234" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
<import resource="security.xml" />
@ImportResource("security.xml")
この時点で、Spring Security は標準のフォームベース認証で完全に構成されている必要があります。残りのインストール処理を続行する前に、ここまでのすべての設定が正しく構成されていることをテストすることは重要です。
このテストを行うには、アプリケーションをデプロイし、セキュリティで保護されているリソースへのアクセスを試みます。正しく構成されていれば、Web ブラウザが簡単なログイン フォームにリダイレクトされます。ログイン名 ( frank) およびパスワード (1234) を入力します。ログインが正常に完了し、ブラウザがセキュリティで保護されているリソースにリダイレクトされれば、アプリケーションは正常に機能しています。
例外が発生した場合は、この記事の前のセクションに戻り、誤りがないかどうか調べてください。
AjaxLoginController という新しいコントローラを作成します。このコントローラにより、ログイン フォームを HTML フラグメントとして表示し、フォームが送信されるときの AJAX POST 要求を処理します。
クラスは次のようになります。@Controller
注:
@RequestMapping("/login")
public class AjaxLoginController {
@Autowired
@Qualifier("authenticationManager")
AuthenticationManager authenticationManager;
@Autowired
SecurityContextRepository repository;
@Autowired
RememberMeServices rememberMeServices;
@RequestMapping(method=RequestMethod.GET)
public void login() {}
@RequestMapping(method=RequestMethod.POST)
@ResponseBody
public String performLogin(
@RequestParam("j_username") String username,
@RequestParam("j_password") String password,
HttpServletRequest request, HttpServletResponse response)
{
UsernamePasswordAuthenticationToken token =
new UsernamePasswordAuthenticationToken(username, password);
try {
Authentication auth = authenticationManager.authenticate(token);
SecurityContextHolder.getContext().setAuthentication(auth);
repository.saveContext(SecurityContextHolder.getContext(), request, response);
rememberMeServices.loginSuccess(request, response, auth);
return "{\"status\": true}";
} catch (BadCredentialsException ex) {
return "{\"status\": false, \"error\": \"Bad Credentials\"}";
}
}
}
コントローラをアプリケーションの Spring MVC 構成に追加します。通常これは、コントローラが、コンポーネント スキャンによって検索(つまり、< context:component-scan />)されるパッケージ内に確実に配置されるようにすることを意味します。ただし、アプリケーションの構成によっては、コントローラの bean を手動で定義することが必要になる場合もあります(たとえば、アプリケーションでコンポーネント スキャンを使用しない場合)。
GET および POST の両方で、 AjaxLoginController の可用性をテストします。
GET 要求を検証するには、Web ブラウザを開いて http://localhost:8080/login に移動します。これにより、ログイン フォームの HTML フラグメントが表示されます(完全な HTML ページではないため、異常のように見える可能性があります)。
HTML フラグメントが表示されず、代わりにデフォルトの Spring Security ログイン フォームが表示される場合は、Spring Security の構成を調べ、未認証のユーザーも /login URL にアクセスできるようになっている(つまり、アクセス権が IS_AUTHENTICATED_ANONYMOUSLY に設定されている)ことを確認してください。
POST 要求を検証するには、cURL のようなツールを使用して要求を http://localhost:8080/login に POST します。このコマンドにより、POST 要求が実行され、JSON 応答が返されます。JSON 応答が正常なことを検証します。curl -d "j_username=frank" -d "j_password=1234" http://localhost:8080/appName/login
コントローラを検証する場合は、クライアントの構成に進みます。
ランディング ページを定義します。これは、未認証ユーザーの最初の移動先で、そのページでログイン リンクをクリックします。サンプル アプリケーションの場合、これは / url です。
ログイン フォームを定義します。これは、ユーザーがログイン リンクをクリックすると表示されます。これは、フォームの単なる HTML フラグメントです。ほとんどの場合、ログイン フォームは「ダイアログ」ボックスで表示されます。このフォームを表示するために使用される実際の方法は、アプリケーションとアプリケーションが使用する Javascript ライブラリによって決まります。
サンプル アプリケーションの場合、これは /login url であり、jQuery ダイアログ ボックスに表示されます。
ユーザーのログイン試行を処理する Javascript コードを記述します。
このプロセスは、次の手順に分割されます。
ユーザーがログイン リンクをクリックする場合は、Javascript を使用して GET 要求を AjaxLoginController's ログイン メソッドに送信します。これにより、HTML フラグメントとしてログイン フォームが返されます。このフォームは、
ユーザーが認証情報をフォームに入力して [ログイン] ボタンをクリックする場合は、フォーム データを収集し、Javascript を使用して POST 要求を AjaxLoginController's performLogin メソッドに送信します。このメソッドからの応答は、ユーザーが正常に認証されたかどうかを示す JSON メッセージです。
JSON 応答を解析し、ログインの試行に成功したかどうかを判別します。ログインに失敗した場合は、ユーザーに理由を表示します。理由は、エラー プロパティとして JSON 応答に含まれています。ログインに成功した場合は、ダイアログを閉じ、アプリケーションに現在ログインしていることを示すアラートをユーザーに表示します。
注:両方の側がフォーマットについて同意する場合は、 AjaxLoginController's performLogin メソッドと Javascript ログイン プロセスの間で交換される JSON データをカスタマイズすることが可能です。
ログアウトするには、ユーザーを /j_spring_security_logout URL に転送します。これには、 タグを使用するか、Javascript を使用して GET 要求を同じ URL に送信します。
この記事には、サンプル アプリケーションが添付されています ( 2002229_SpringSecutiryAjaxDemo.zip)。このアプリケーションは Maven を使用して作成することができ、 mvn tomcat:run コマンドによって実行できます。
これにより、サンプル アプリケーションが URL ( http://localhost:8080/ajax-login/) にデプロイされます。この URL にアクセスすると、アプリケーションのランディング ページが表示されます。標準ログインリンクをクリックすると、標準の Spring Security ログインのワークフローが開始されます。Ajax ログインリンクをクリックすると、強化された Spring Security ログインのワークフローが開始されます。
サンプル アプリケーションは、Spring MVC、Spring Security、および jQuery を使用して開発されています。上の説明にあるプロセスの詳細については、添付されているサンプル アプリケーションを参照してください。