1. 概要

このクイックチュートリアルでは、Springセキュリティを使用してJakartaEEWebアプリケーションをセキュリティで保護する方法を見ていきます。

2. Mavenの依存関係

このチュートリアルに必要なSpringセキュリティ依存関係から始めましょう

<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>

最新のSpringSecurityバージョン(このチュートリアルの執筆時点)は4.2.3.RELEASEです。 いつものように、 MavenCentralで最新バージョンを確認できます。

3. セキュリティ構成

次に、既存のJakartaEEアプリケーションのセキュリティ構成をセットアップする必要があります。

@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セキュリティの基本的な実装を実現しました。 この実装では、SpringSecurityはデフォルトですべてのリクエストとルートの認証を必要とします。

4. セキュリティルールの構成

WebSecurityConfigurerAdapterconfigure(HttpSecurity http)メソッドをオーバーライドすることで、SpringSecurityをさらにカスタマイズできます。

@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およびが他の要求を認証する匿名アクセスを許可するようにSpringSecurityを構成します。

4.1. カスタムログインページ

カスタムログインページは、 formLogin()メソッドを使用して構成されます。

http.formLogin()
  .loginPage("/auth/login")

これが指定されていない場合、SpringSecurityは/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. カスタムランディングページ

ログインに成功すると、SpringSecurityはユーザーをアプリケーションのルートにリダイレクトします。 デフォルトの成功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 エンドポイントにアクセスしようとすると、アクセス拒否エラーが発生します。

また、ユーザーの役割に基づいて、JSPページのデータを制限することもできます。 これは、 鬼ごっこ:

<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>

このタグを使用するには、ページの上部にSpringSecurityタグtaglibを含める必要があります。

<%@ taglib prefix="security" 
  uri="http://www.springframework.org/security/tags" %>

5. SpringSecurityXML構成

これまで、JavaでのSpringSecurityの構成について見てきました。 同等のXML構成を見てみましょう。

まず、XML構成を含む web / WEB-INF /springフォルダーにsecurity.xmlファイルを作成する必要があります。 このようなsecurity.xml構成ファイルの例は、記事の最後にあります。

認証マネージャーと認証プロバイダーを構成することから始めましょう。 簡単にするために、ハードコードされた単純なユーザー資格情報を使用します。

<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のカスタム実装を認証プロバイダーとして指定することもできます。 詳細については、こちらをご覧ください。

認証マネージャーを構成したので、セキュリティルールを設定し、アクセス制御を適用しましょう。

<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セキュリティは、構成でオーバーライドする必要のないデフォルトの動作を実装するように指示されます。 。 したがって、 /login/logout は、それぞれユーザーのログインとログアウトに使用されます。 デフォルトのログインページも提供されています。

form-login タグを、認証の失敗と成功の両方を処理するためのカスタムログインページとログアウトページ、URLでさらにカスタマイズできます。 セキュリティ名前空間付録には、 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. 結論

この記事では、SpringSecurityを使用してJakartaEEアプリケーションを保護する方法を確認し、JavaベースとXMLベースの両方の構成を示しました。

また、ユーザーの役割に基づいて特定のリソースへのアクセスを許可または取り消す方法についても説明しました。

完全なソースコードとXML定義は、GitHubから入手できます。