Springセキュリティ式の紹介
1前書き
このチュートリアルでは、Spring Security Expressionsと、これらの式を使用した実際の例に焦点を当てます。
ACLなどのより複雑な実装を検討する前に、セキュリティ表現をしっかりと把握しておくことが重要です。正しく使用すると非常に柔軟で強力になる可能性があるためです。
2 Mavenの依存関係
Spring Securityを使用するには、
pom.xml
ファイルに次のセクションを含める必要があります。
<dependencies>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.1.1.RELEASE</version>
</dependency>
</dependencies>
最新版はhttps://search.maven.org/classic/#search%7Cga%7C1%7Ca%3A%22spring-security-web%22[here]を見つけることができます。
そして、ちょっとしたメモ – この依存関係はSpring Securityだけをカバーしています。完全なWebアプリケーションの場合は、s
__pring-core
と
spring-context__を追加することを忘れないでください。
3構成
まず、Javaの設定を見てみましょう。
WebSecurityConfigurerAdapter
を拡張します – そのため、基本クラスが提供する拡張ポイントのいずれかにフックするオプションがあります。
@Configuration
@EnableAutoConfiguration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityWithoutCsrfConfig 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
-
許可すべて、拒否すべて
-
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/
で始まるすべてのリンクへのアクセスをロール
USER
またはロール
ADMINでログインしているユーザーに制限します。さらに、
/auth/admin/
で始まるリンクにアクセスするには
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で似ています。
主な違いは、ロールには特別なセマンティクスがあるということです – Spring Security 4以降では、ロール関連の方法で ‘
ROLE
__’プレフィックスが自動的に追加されています(まだ追加されていない場合)。
そのため、
hasAuthority( ‘ROLE
ADMIN’)
は
hasRole( ‘ADMIN’)
と似ています。というのも、 ‘
ROLE____’プレフィックスが自動的に追加されるからです。
-
しかし、権限を使うことの良いところは、
ROLE
__接頭辞を使う必要が全くないということです。**
これは、特定の権限を持つユーザーを定義する簡単な例です。
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user1").password("user1Pass")
.authorities("USER")
.and().withUser("admin").password("adminPass")
.authorities("ADMIN");
}
私たちはもちろんこれらの権威表現を使うことができます
@Override
protected void configure(final HttpSecurity http) throws Exception {
...
.antMatchers("/auth/admin/** ").hasAuthority("ADMIN")
.antMatchers("/auth/** ").hasAnyAuthority("ADMIN", "USER")
...
}
ご覧のとおり、ここでは役割については一切触れていません。
最後に – 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>
そして:
<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>
それを使用するすべての人がログインすることを要求されるであろうウェブサイトを保護したいならば、我々は
isAuthenticated()
メソッドを使用する必要があります:
...
.antMatchers("/** ").authenticated()
...
またはXMLバージョン
<http>
<intercept-url pattern="/** " access="isAuthenticated()"/>
</http>
さらに、
isRememberMe()
と
isFullyAuthenticated()
という2つの式があります。 Cookieを使用することで、Springは記憶機能を有効にしているので、毎回システムにログインする必要はありません。あなたはlink:/spring-security-remember-meを読むことができます。
ログイン機能だけでログインしたユーザーにアクセスを許可するために、これを使用することができます。
...
.antMatchers("/** ").rememberMe()
...
またはXMLバージョン
<http>
<intercept-url pattern="** " access="isRememberMe()"/>
</http>
最後に、当社のサービスの一部は、ユーザーがすでにログインしている場合でも、ユーザーに再度認証を要求します。システムの機密性の高い領域で手動認証を要求することは、もちろん良い習慣です。
そのためには、
isFullyAuthenticated()
を指定します。これは、ユーザーが匿名ユーザーでも覚えていないユーザーでもない場合に
true
を返します。
...
.antMatchers("/** ").fullyAuthenticated()
...
またはXMLのバージョン
<http>
<intercept-url pattern="** " access="isFullyAuthenticated()"/>
</http>
4.5.
プリンシパル、認証
これらの式は、現在の許可された(または匿名の)ユーザーを表す
principal
オブジェクトおよび
SecurityContext
からの現在の
Authentication
オブジェクトへのアクセスをそれぞれ許可します。
たとえば、
principal
を使用して、ユーザーの電子メール、アバター、またはログインしたユーザーでアクセス可能なその他のデータを読み込むことができます。
そして
authentication
は、完全な
Authentication
オブジェクトに関する情報と、それに付与された権限を提供します。
次の記事では、両方ともさらに詳しく説明しています。
4.6.
hasPermission
API
この表現はhttps://docs.spring.io/spring-security/site/docs/current/reference/html/authorization.html#el-access[文書化]であり、表現システムと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結論
このチュートリアルはSpring Security Expressionsの包括的な紹介とガイドです。
ここで説明した例はすべてhttps://github.com/eugenp/tutorials/tree/master/spring-security-rest[GitHubプロジェクト]から入手できます。