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の UserDetailsS​​ervice または 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で利用可能]です。