1. 序章

このチュートリアルでは、Springセキュリティ式に焦点を当て、もちろんこれらの式を使用した実際の例に焦点を当てます。

より複雑な実装(ACLなど)を検討する前に、セキュリティ式をしっかりと把握することが重要です。正しく使用すれば、非常に柔軟で強力になる可能性があります。

2. Mavenの依存関係

Spring Securityを使用するには、pom.xmlファイルに次のセクションを含める必要があります。

<dependencies>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
        <version>5.6.0</version>
    </dependency>
</dependencies>

最新バージョンはここにあります。

そして簡単な注意–この依存関係はSpringセキュリティのみをカバーします。 完全なWebアプリケーションには、s pring-corespring-contextを追加することを忘れないでください。

3. 構成

まず、Javaの構成を見てみましょう。

WebSecurityConfigurerAdapter を拡張します。これにより、基本クラスが提供する拡張ポイントのいずれかにフックするオプションがあります。

@Configuration
@EnableAutoConfiguration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityJavaConfig extends WebSecurityConfigurerAdapter {
    ...
}

もちろん、XML構成も行うことができます。

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans ...>
    <global-method-security pre-post-annotations="enabled"/>
</beans:beans>

4. Webセキュリティ式

それでは、セキュリティ式を見てみましょう。

  • hasRole hasAnyRole
  • hasAuthority hasAnyAuthority
  • permitAll denyAll
  • isAnonymous isRememberMe isAuthenticated isFullyAuthenticated
  • プリンシパル認証
  • hasPermission

そして、これらのそれぞれについて詳しく見ていきましょう。

4.1. hasRole、hasAnyRole

これらの式は、アプリケーション内の特定のURLまたはメソッドへのアクセス制御または承認を定義する役割を果たします。

例を見てみましょう:

@Override
protected void configure(final HttpSecurity http) throws Exception {
    ...
    .antMatchers("/auth/admin/*").hasRole("ADMIN")
    .antMatchers("/auth/*").hasAnyRole("ADMIN","USER")
    ...
}

この例では、で始まるすべてのリンクへのアクセスを指定します / auth / 役割でログインしているユーザーに制限ユーザーまたは役割管理者。 さらに、で始まるリンクにアクセスするには / auth / admin / 私たちは持っている必要があります管理者システムにおける役割。

XMLファイルでも、次のように記述して同じ構成を実現できます。

<http>
    <intercept-url pattern="/auth/admin/*" access="hasRole('ADMIN')"/>
    <intercept-url pattern="/auth/*" access="hasAnyRole('ADMIN','USER')"/>
</http>

4.2. hasAuthority、hasAnyAuthority

春の役割と権限は似ています。

主な違いは、ロールには特別なセマンティクスがあることです。Spring Security 4以降、「 ROLE_ 」プレフィックスは、ロール関連のメソッドによって自動的に追加されます(まだ存在しない場合)。

したがって、 hasAuthority(’ROLE_ADMIN’) hasRole(’ADMIN’)に似ています。これは、’ROLE_‘プレフィックスが自動的に追加されるためです。

ただし、権限を使用することの良い点は、ROLE_プレフィックスをまったく使用する必要がないことです。

特定の権限を持つユーザーを定義する簡単な例を次に示します。

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
      .withUser("user1").password(encoder().encode("user1Pass"))
      .authorities("USER")
      .and().withUser("admin").password(encoder().encode("adminPass"))
      .authorities("ADMIN");
}

もちろん、次の権限式を使用できます。

@Override
protected void configure(final HttpSecurity http) throws Exception {
    ...
    .antMatchers("/auth/admin/*").hasAuthority("ADMIN")
    .antMatchers("/auth/*").hasAnyAuthority("ADMIN", "USER")
    ...
}

ご覧のとおり、ここでは役割についてはまったく触れていません。 さらに、Spring 5以降、 PasswordEncoderBeanが必要です。

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

最後に、もちろん、XML構成を使用して同じ機能を実現できます。

<authentication-manager>
    <authentication-provider>
        <user-service>
            <user name="user1" password="user1Pass" authorities="ROLE_USER"/>
            <user name="admin" password="adminPass" authorities="ROLE_ADMIN"/>
        </user-service>
    </authentication-provider>
</authentication-manager>
<bean name="passwordEncoder" 
  class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>

と:

<http>
    <intercept-url pattern="/auth/admin/*" access="hasAuthority('ADMIN')"/>
    <intercept-url pattern="/auth/*" access="hasAnyAuthority('ADMIN','USER')"/>
</http>

4.3. permitAll、denyAll

これらの2つの注釈も非常に簡単です。 サービス内の一部のURLへのアクセスを許可するか、アクセスを拒否する場合があります。

例を見てみましょう:

...
.antMatchers("/*").permitAll()
...

この構成では、すべてのユーザー(匿名とログインの両方)が「/」で始まるページ(たとえば、ホームページ)にアクセスすることを許可します。

URLスペース全体へのアクセスを拒否することもできます。

...
.antMatchers("/*").denyAll()
...

また、XML構成でも同じ構成を実行できます。

<http auto-config="true" use-expressions="true">
    <intercept-url access="permitAll" pattern="/*" /> <!-- Choose only one -->
    <intercept-url access="denyAll" pattern="/*" /> <!-- Choose only one -->
</http>

4.4。isAnonymous、isRememberMe、isAuthenticated、isFullyAuthenticated

このサブセクションでは、ユーザーのログインステータスに関連する式に焦点を当てます。 私たちのページにログインしなかったユーザーから始めましょう。 Java構成で以下を指定することにより、許可されていないすべてのユーザーがメインページにアクセスできるようにします。

...
.antMatchers("/*").anonymous()
...

XML構成でも同じです。

<http>
    <intercept-url pattern="/*" access="isAnonymous()"/>
</http>

使用するすべての人がログインする必要があるWebサイトを保護する場合は、 isAuthenticated()メソッドを使用する必要があります。

...
.antMatchers("/*").authenticated()
...

またはXMLバージョン:

<http>
    <intercept-url pattern="/*" access="isAuthenticated()"/>
</http>

さらに、 isRememberMe() isFullyAuthenticated()の2つの追加式があります。 SpringはCookieを使用することで、remember-me機能を有効にしているため、毎回システムにログインする必要はありません。 ここでRememberMeの詳細を読むことができます。

記憶機能によってのみログインしたユーザーにアクセスを許可するために、これを使用する場合があります。

...
.antMatchers("/*").rememberMe()
...

またはXMLバージョン:

<http>
    <intercept-url pattern="*" access="isRememberMe()"/>
</http>

最後に、当社のサービスの一部では、ユーザーがすでにログインしている場合でも、ユーザーを再度認証する必要があります。 たとえば、ユーザーが設定や支払い情報を変更したい場合。 もちろん、システムのより機密性の高い領域で手動認証を要求することをお勧めします。

これを行うために、 isFullyAuthenticated()を指定できます。これは、ユーザーが匿名ユーザーまたは覚えているユーザーでない場合にtrueを返します。

...
.antMatchers("/*").fullyAuthenticated()
...

またはXMLバージョン:

<http>
    <intercept-url pattern="*" access="isFullyAuthenticated()"/>
</http>

4.5. プリンシパル、認証

これらの式により、 SecurityContext から、現在の許可された(または匿名の)ユーザーを表すprimaryオブジェクトと現在のAuthenticationオブジェクトにそれぞれアクセスできます。

たとえば、プリンシパルを使用して、ユーザーの電子メール、アバター、またはログインしたユーザーがアクセスできるその他のデータを読み込むことができます。

また、認証は、許可された権限とともに、完全な認証オブジェクトに関する情報を提供します。

どちらも、次の記事でさらに詳しく説明されています:SpringSecurityでのユーザー情報の取得

4.6. hasPermission API

この式は文書化されており、式システムとSpring SecurityのACLシステムの間を橋渡しすることを目的としており、抽象権限に基づいて個々のドメインオブジェクトに承認制約を指定できます。

例を見てみましょう。 他の著者が提案した記事を公開するかどうかを主編集者が共同で執筆できるサービスを提供しています。

このようなサービスの使用を許可するために、アクセス制御メソッドを使用して次のメソッドを作成する場合があります。

@PreAuthorize("hasPermission(#articleId, 'isEditor')")
public void acceptArticle(Article article) {
   …
}

このメソッドを呼び出すことができるのは許可されたユーザーのみであり、ユーザーはサービスでisEditorのアクセス許可を持っている必要があります。

また、アプリケーションコンテキストでPermissionEvaluatorを明示的に構成することも忘れないでください。

<global-method-security pre-post-annotations="enabled">
    <expression-handler ref="expressionHandler"/>
</global-method-security>

<bean id="expressionHandler"
    class="org.springframework.security.access.expression
      .method.DefaultMethodSecurityExpressionHandler">
    <property name="permissionEvaluator" ref="customInterfaceImplementation"/>
</bean>

どこ customInterfaceImplementation を実装するクラスになります PermissionEvaluator。

もちろん、Java構成でもこれを行うことができます。

@Override
protected MethodSecurityExpressionHandler expressionHandler() {
    DefaultMethodSecurityExpressionHandler expressionHandler = 
      new DefaultMethodSecurityExpressionHandler();
    expressionHandler.setPermissionEvaluator(new CustomInterfaceImplementation());
    return expressionHandler;
}

5. 結論

このチュートリアルは、SpringSecurityExpressionsの包括的な紹介とガイドです。

ここで説明するすべての例は、GitHubプロジェクト利用できます。