Spring SecurityでJava EEを保護する
1概要
このクイックチュートリアルでは、Spring Securityを使ってJava EE Webアプリケーションを保護する方法を見ていきます。
2.
Mavenの依存関係
このチュートリアルに必要なリンク:/spring-security-with-maven[Spring Securityの依存関係]から始めましょう
_:
_
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>4.2.3.RELEASE</version>
</dependency>
このチュートリアルの執筆時点での最新のSpring Securityバージョンは4.2.3です。いつものように、最新バージョンについてはhttps://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22org.springframework.security%22[Maven Central]をチェックすることができます。
3.
セキュリティ設定
次に、既存のJava EEアプリケーションのセキュリティ構成を設定する必要があります。
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig
extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication()
.withUser("user1").password("user1Pass").roles("USER")
.and()
.withUser("admin").password("adminPass").roles("ADMIN");
}
}
configure()
メソッドで、
AuthenticationManager
を設定します。簡単にするために、単純なメモリー内認証を実装します。
ユーザーの詳細はハードコードされています。
これは、完全な永続化メカニズムが不要な場合にラピッドプロトタイピングに使用することを目的としています。
次に、
SecurityWebApplicationInitializer
クラスを追加してセキュリティを既存のシステムに統合しましょう。
public class SecurityWebApplicationInitializer
extends AbstractSecurityWebApplicationInitializer {
public SecurityWebApplicationInitializer() {
super(SpringSecurityConfig.class);
}
}
このクラスは、アプリケーションの起動時に
SpringSecurityConfig
が確実に読み込まれるようにします。この段階で、私たちはSpring Securityの基本的な実装を達成しました。この実装では、Spring Securityはデフォルトですべてのリクエストとルートに対して認証を要求します。
4.
セキュリティルールの設定
WebSecurityConfigurerAdapter
s
configure(HttpSecurity http)
メソッドをオーバーライドすることで、Spring Securityをさらにカスタマイズできます。
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/auth/login** ").anonymous()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/auth/login")
.defaultSuccessUrl("/home", true)
.failureUrl("/auth/login?error=true")
.and()
.logout().logoutSuccessUrl("/auth/login");
}
antMatchers()
メソッドを使用して、
/auth/login
への匿名アクセスを許可し、その他の要求を認証するようにSpring Securityを設定します。
4.1. カスタムログインページ
カスタムログインページは
formLogin()
メソッドを使用して設定されます。
http.formLogin()
.loginPage("/auth/login")
これが指定されていない場合、Spring Securityはデフォルトのログインページを
/login
に生成します。
<html>
<head></head>
<body>
<h1>Login</h1>
<form name='f' action="/auth/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>
4.2. カスタムランディングページ
ログインが成功すると、Spring Securityはユーザをアプリケーションのルートにリダイレクトする。デフォルトの成功URLを指定することでこれを上書きできます。
http.formLogin()
.defaultSuccessUrl("/home", true)
defaultSuccessUrl()
メソッドの
alwaysUse
パラメータをtrueに設定すると、ユーザーは常に指定されたページにリダイレクトされます。
alwaysUse
パラメーターが設定されていないかfalseに設定されている場合、ユーザーは認証を要求される前にアクセスしようとした前のページにリダイレクトされます。
同様に、カスタム障害ランディングページを指定することもできます。
http.formLogin()
.failureUrl("/auth/login?error=true")
4.3. 承認
ロールによるリソースへのアクセスを制限できます。
http.formLogin()
.antMatchers("/home/admin** ").hasRole("ADMIN")
管理者以外のユーザーが
/home/admin
エンドポイントにアクセスしようとすると、Access Deniedエラーが表示されます。
ユーザーの役割に基づいて、JSPページ上のデータを制限することもできます。これは
<security:authorize>
タグを使用して行われます。
<security:authorize access="hasRole('ADMIN')">
This text is only visible to an admin
<br/>
<a href="<c:url value="/home/admin"/>">Admin Page</a>
<br/>
</security:authorize>
このタグを使用するには、ページの上部にSpring Securityのタグtaglibを含める必要があります。
<%@ taglib prefix="security"
uri="http://www.springframework.org/security/tags" %>
5. Spring SecurityのXML設定
これまでのところ、JavaでSpring Securityを構成することを検討しました。それと同等のXML構成を見てみましょう。
まず、
web/WEB-INF/spring
フォルダーにXML構成を含む
security.xml
ファイルを作成する必要があります。このような
security.xml
configファイルの例は、記事の最後にあります。
認証マネージャと認証プロバイダを設定することから始めましょう。簡単にするために、単純なハードコードされたユーザー資格情報を使用します。
<authentication-manager>
<authentication-provider>
<user-service>
<user name="user"
password="user123"
authorities="ROLE__USER"/>
</user-service>
</authentication-provider>
</authentication-manager>
今行ったことは、ユーザー名、パスワード、およびロールを持つユーザーを作成することです。
あるいは、パスワードエンコーダーを使って認証プロバイダーを設定することもできます。
<authentication-manager>
<authentication-provider>
<password-encoder hash="sha"/>
<user-service>
<user name="user"
password="d7e6351eaa13189a5a3641bab846c8e8c69ba39f"
authorities="ROLE__USER"/>
</user-service>
</authentication-provider>
</authentication-manager>
認証プロバイダとして、Springの
UserDetailsService
または
Datasource
のカスタム実装を指定することもできます。
詳細はhttps://docs.spring.io/spring-security/site/docs/3.0.x/reference/ns-config.html[ここにあります。]
認証マネージャを設定したので、セキュリティルールを設定し、アクセス制御を適用しましょう。
<http auto-config='true' use-expressions="true">
<form-login default-target-url="/secure.jsp"/>
<intercept-url pattern="/" access="isAnonymous()"/>
<intercept-url pattern="/index.jsp" access="isAnonymous()"/>
<intercept-url pattern="/secure.jsp" access="hasRole('ROLE__USER')"/>
</http>
上記のスニペットでは、フォームログインを使用するように
HttpSecurity
を設定し、ログイン成功URLとして
/secure.jsp
を設定しました。
/index.jsp
と
“/”
パスへの匿名アクセスを許可しました。また、
/secure.jsp
へのアクセスには認証が必要であり、認証されたユーザーには少なくとも
ROLE
USER__レベルの権限が必要であると指定しました。
http
タグの
auto-config
属性を
true
に設定すると、Spring Securityは設定でオーバーライドする必要のないデフォルトの動作を実装するようになります。したがって、
/login
と
/logout
がそれぞれユーザーログインとログアウトに使用されます。デフォルトのログインページも提供されています。
認証の失敗と成功の両方を処理するためのカスタムログインページとログアウトページ、URLを使用して
form-login
タグをさらにカスタマイズできます。
Security Namespace appendix
には、
form-login
(およびその他の)タグに使用可能なすべての属性がリストされています。 。いくつかのIDEはまた、
ctrl
キーを押しながらタグをクリックすることによって検査を可能にします。
最後に、アプリケーションの起動時に
security.xml
設定を読み込むには、
web.xml
に次の定義を追加する必要があります。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/** .xml
</param-value>
</context-param>
<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>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
同じJEEアプリケーションでXMLベースとJavaベースの両方の構成を使用しようとすると、エラーが発生する可能性があることに注意してください。
6. 結論
この記事では、Spring Securityを使用してJava EEアプリケーションを保護する方法を説明し、Javaベースの構成とXMLベースの構成の両方を示しました。
ユーザーの役割に基づいて、特定のリソースへのアクセスを許可または取り消す方法についても説明しました。
完全なソースコードとXML定義はhttps://github.com/eugenp/tutorials/tree/master/jee-7-security[GitHubで利用可能]です。