Spring 4 Security MVC ログイン・ログアウトの実例
今日は、Spring Securityのログインの例について学びます。この投稿を読む前に、「Spring 4セキュリティの紹介」の私の前の投稿を一読してください。
スプリングセキュリティによるログイン・ログアウトの例
このポストでは、In-Memoryオプションを使用して、ログインとログアウトの機能を提供するためにSpring 4 MVC Security Webアプリケーションを開発します。この例では、Spring Java ConfigとSpring Annotationsを使用しています。つまり、web.xmlやSpring XML Configuration(古いスタイル)を使用していません。もしSpring 3.x Security Moduleについて詳しく知りたい場合は、まず以下のポストを参照してください。
-
- JDBC認証を使用したユーザー詳細情報とインメモリを利用したSpring MVCセキュリティの例
- DAO、JDBC、インメモリ認証を使用したサーブレットウェブアプリケーションにおけるSpringセキュリティの例
「Spring 4 Securityモジュールでは、以下のオプションをサポートしてユーザーの認証情報を保存・管理します。」
-
- インメモリストア
-
- 関係データベース(RDBMS)
-
- NoSQLデータストア
- LDAP
この例では、「In-Memory Store」というオプションを使用します。他のオプションについては、私の次の投稿で説明します。この例では、Spring 4.0.2.RELEASE、Spring STS 3.7 Suite IDE、Spring TC Server 3.1、Java 1.8、およびMavenビルドツールを使用して開発します。
スプリングセキュリティのログインの例
私たちは、Spring 4セキュリティ機能を使用して、ログインとログアウトのロジックを開発する予定です。このアプリケーションの主な目的は、「web.xml」を使用せず、Spring XML Beansの設定ファイルを一切書かないでアプリケーションを開発することです。つまり、SpringのJava Config機能とSpringのアノテーションを使用する予定です。次の機能を持つこのアプリケーションを開発します:
-
- ウェルカムページ
-
- ログインページ
-
- ホームページ
- ログアウト機能
このSpring 4 Security Simple Login Exampleを開発し、探索するために、以下の手順を使用してください。
- Create a “Simple Spring Web Maven” Project in Spring STS Suite with the following details
Project Name : SpringMVCSecruityMavenApp
- Update pom.xml with the following content
<?xml version="1.0" encoding="UTF-8"?>
<project
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="https://maven.apache.org/POM/4.0.0"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.scdev</groupId>
<artifactId>SpringMVCSecruityMavenApp</artifactId>
<packaging>war</packaging>
<version>1.0</version>
<properties>
<java.version>1.8</java.version>
<spring.version>4.0.2.RELEASE</spring.version>
<spring.security.version>4.0.2.RELEASE</spring.security.version>
<servlet.api.version>3.1.0</servlet.api.version>
<jsp.api.version>2.2</jsp.api.version>
<jstl.version>1.2</jstl.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.api.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>${jsp.api.version}</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
</dependencies>
<build>
<finalName>SpringMVCSecruityMavenApp</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
以下は、日本語での同義表現です(注:必要なのは一つのオプションのみです):
<failOnMissingWebXml>フラグについて知らない場合は、この投稿の最後を読んで、この要素の使用方法を理解してください。まず、Springの@Controller注釈を使用してログインコントローラーを開発してください。LoginController.java
package com.scdev.spring.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class LoginController {
@RequestMapping(value = { "/"}, method = RequestMethod.GET)
public ModelAndView welcomePage() {
ModelAndView model = new ModelAndView();
model.setViewName("welcomePage");
return model;
}
@RequestMapping(value = { "/homePage"}, method = RequestMethod.GET)
public ModelAndView homePage() {
ModelAndView model = new ModelAndView();
model.setViewName("homePage");
return model;
}
@RequestMapping(value = "/loginPage", method = RequestMethod.GET)
public ModelAndView loginPage(@RequestParam(value = "error",required = false) String error,
@RequestParam(value = "logout", required = false) String logout) {
ModelAndView model = new ModelAndView();
if (error != null) {
model.addObject("error", "Invalid Credentials provided.");
}
if (logout != null) {
model.addObject("message", "Logged out from JournalDEV successfully.");
}
model.setViewName("loginPage");
return model;
}
}
コードの説明:「LoginController」には、3つのメソッドが定義されており、それぞれ異なる種類のクライアントリクエストを処理します。
-
- welcomePage()は、”/” URIを使用しているすべてのクライアントリクエストを処理します。
-
- homePage()は、”/homePage” URIを使用しているすべてのクライアントリクエストを処理します。
-
- loginPage()は、”/loginPage” URIを使用しているすべてのクライアントリクエストを処理します。
- loginPage()では、エラーとログアウトメッセージの処理に注意する必要があります。
- Then develop a class “LoginSecurityConfig” to provide Login and Logout Security Features using Spring 4 Security API.
LoginSecurityConfig.java
package com.scdev.spring.secuity.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class LoginSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder authenticationMgr) throws Exception {
authenticationMgr.inMemoryAuthentication()
.withUser("scdev")
.password("jd@123")
.authorities("ROLE_USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/homePage").access("hasRole('ROLE_USER')")
.and()
.formLogin().loginPage("/loginPage")
.defaultSuccessUrl("/homePage")
.failureUrl("/loginPage?error")
.usernameParameter("username").passwordParameter("password")
.and()
.logout().logoutSuccessUrl("/loginPage?logout");
}
}
コードの説明:「LoginSecurityConfig」で2つのメソッドを定義しています。これらのメソッドは、ユーザーの資格情報を保存・管理し、ログインおよびログアウトのセキュリティ機能を管理します。
-
- @EnableWebSecurityアノテーションは、任意のWebアプリケーションでWebセキュリティを有効にするために使用されます。
-
- @EnableWebMVCSecurityアノテーションは、Spring MVCベースのWebアプリケーションでWebセキュリティを有効にするために使用されます。
-
- 注意:@EnableWebSecurity = @EnableWebMVCSecurity + 追加機能です。そのため、Spring 4.xフレームワークでは@EnableWebMVCSecurityアノテーションは非推奨となっています。4.「LoginSecurityConfig」クラスまたはSpringセキュリティを設定するために指定されたクラスは、「WebSecurityConfigurerAdapter」クラスを拡張するか、関連するインターフェースを実装する必要があります。
-
- configureGlobal()メソッドはユーザーの資格情報を保管および管理するために使用されます。
-
- configureGlobal()メソッドでは、authorities()メソッドを使用して「ROLE_USER」などのアプリケーションの役割を定義することができます。同じ目的でroles()メソッドも使用することができます。
-
- authorities()メソッドとroles()メソッドの違い:
-
- authorities()メソッドでは「ROLE_USER」のような完全なロール名が必要です。roles()メソッドでは「USER」のようなロール名が必要で、「USER」というロール名に「ROLE_」の値が自動的に追加されます。注意:将来の投稿で「USER」、「ADMIN」などのロールを示すための別の例を開発します。
-
- ログインおよびログアウトセキュリティを管理するための重要なメソッドはconfigure(HttpSecurity http)です。
- 以下のコードスニペットは、「/homePage」への不正なアクセスを防ぐために使用されます。このページに直接アクセスしようとすると、自動的に「/loginPage」ページにリダイレクトされます。
.antMatchers("/homePage").access("hasRole('ROLE_USER')")
「access(’ROLE_USER’)」メソッド呼び出しを削除すれば、アプリケーションにログインせずにこのページにアクセスできます。13. フォームログイン()およびログアウト()メソッドを使用して、ログインおよびログアウトの機能を設定しています。
- Enable Spring MVC Configuration
LoginApplicationConfig.java
package com.scdev.spring.secuity.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
@EnableWebMvc
@Configuration
@ComponentScan({ "com.scdev.spring.*" })
@Import(value = { LoginSecurityConfig.class })
public class LoginApplicationConfig {
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
コードの説明:「LoginApplicationConfig」というクラスを使用して、Spring MVCビューリゾルバを定義して、”web.xml”ファイルを書かずに済ませています。
-
- @EnableWebMvcアノテーションは、SpringフレームワークでSpring Web MVCアプリケーションの機能を有効にするために使用されます。
-
- @Importアノテーションは、このクラスにSpring Security設定クラスをインポートするために使用されます。
- @ComponentScanアノテーションは、指定されたパッケージでコンポーネントスキャンを行うために使用されます。これはSpring XML設定の「context:component-scan」と等価です。
- Initialize Spring Security
package com.scdev.spring.secuity.config.core;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {
}
「SpringSecurityInitializer」は、springSecurityFilterChainを使用するためにDelegatingFilterProxyを登録するために使用されます。これにより、web.xmlファイルにフィルタの設定を記述する必要がありません。 -Spring MVCアプリケーションの初期化
「SpringMVCWebAppInitializer」クラスは、注釈ベースの設定でweb.xmlファイルなしで「DispatcherServlet」を初期化するために使用されます。SpringMVCWebAppInitializer.java
package com.scdev.spring.secuity.config.core;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import com.scdev.spring.secuity.config.LoginApplicationConfig;
public class SpringMVCWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { LoginApplicationConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
以下の文を日本語で言い換えてください(1つのオプションのみ必要です):
注意:
-
- 私たちがアプリケーションにアクセスすると、デフォルトでSpringMVCWebAppInitializerのgetServletMappings()はルートURL「/」へのアクセスを許可します。別のURLに転送するように上書きすることもできます。
- SpringまたはPivotalのチームは、この多くのJavaコードを避けるために注釈を導入することで、この問題に取り組んでいます。詳細についてはhttps://jira.spring.io/browse/SPR-10359をご確認ください。
- Develop welcomePage.jsp file
<h3>Welcome to JournalDEV Tutorials</h3>
<a href="${pageContext.request.contextPath}/loginPage">Login to Journal</a>
- Develop loginPage.jsp file
<%@ taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core"%>
<html>
<body onload='document.loginForm.username.focus();'>
<h3>JournalDEV Tutorials</h3>
<c:if test="${not empty error}"><div>${error}</div></c:if>
<c:if test="${not empty message}"><div>${message}</div></c:if>
<form name='login' action="<c:url value='/loginPage' />" method='POST'>
<table>
<tr>
<td>UserName:</td>
<td><input type='text' name='username' value=''></td>
</tr>
<tr>
<td>Password:</td>
<td><input type='password' name='password' /></td>
</tr>
<tr>
<td colspan='2'><input name="submit" type="submit" value="submit" /></td>
</tr>
</table>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
</body>
</html>
- Develop homepage.jsp file
<%@taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core"%>
<h3>Welcome to JournalDEV Tutorials</h3>
<ul>
<li>Java 8 tutorial</li>
<li>Spring tutorial</li>
<li>Gradle tutorial</li>
<li>BigData tutorial</li>
</ul>
<c:url value="/logout" var="logoutUrl" />
<form id="logout" action="${logoutUrl}" method="post" >
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
<c:if test="${pageContext.request.userPrincipal.name != null}">
<a href="javascript:document.getElementById('logout').submit()">Logout</a>
</c:if>
- Final Project Structure looks like this:
「Spring Security MVCのログイン・ログアウトの例を実行する」
このSpring Web アプリケーションを実行するためには、Spring 4 および Java 8 の環境をサポートするWebコンテナーとしてServlet 3.1.0 コンテナーが必要です。
- Deploy and Run on Spring TC Server in Spring STS Suite
- It automatically access our application welcome page url as shown below.
– click on “Login to JournalDEV” link to access login page.
– Now, provide wrong login details and click on “Login” button.
Here we can observe this error message: “Invalid Credentials provided.”- Now, provide correct login details configured in “LoginSecurityConfig” class.
After successful login to our application, we can see our Application Homepage with the “Logout” link.- click on “Logout” link to logout from Application.
Here we can observe that we are Logged out from our application successfully and redirected to Login page again. We can observe some Log out successful message in this Login page.
次の例を見ると、web.xmlファイルは使用していません。Webアプリケーションであるため、Mavenはweb.xmlファイルを検索し、アプリケーション内で見つからない場合にエラーを発生させます。Maven関連の問題を回避するために、pom.xmlファイルで「」フラグを設定する必要があります。以上がSpring 4セキュリティモジュールのシンプルな例です。私の次の投稿では、役に立つより実用的な例をいくつか開発します。役職の管理、Remember-Me機能、WebSocketセキュリティなど、投稿が気に入ったり問題/提案がある場合は、コメントを残してください。