最新の安定バージョンについては、Spring Security 6.3.1 を使用してください!

メソッドのセキュリティ

バージョン 2.0 以降、Spring Security は、サービスレイヤーメソッドにセキュリティを追加するためのサポートを大幅に改善しました。JSR-250 アノテーションセキュリティとフレームワークの元の @Secured アノテーションのサポートを提供します。3.0 から、新しい式ベースのアノテーションを利用することもできます。intercept-methods 要素を使用して Bean 宣言を装飾することにより、単一の Bean にセキュリティを適用するか、AspectJ スタイルのポイントカットを使用してサービス層全体にわたって複数の Bean を保護することができます。

EnableMethodSecurity

Spring Security 5.6 では、任意の @Configuration インスタンスで @EnableMethodSecurity アノテーションを使用して、アノテーションベースのセキュリティを有効にできます。

これは、いくつかの点で @EnableGlobalMethodSecurity を改善します。@EnableMethodSecurity:

  1. メタデータソース、構成属性、意思決定マネージャー、投票者の代わりに、簡略化された AuthorizationManager API を使用します。これにより、再利用とカスタマイズが簡単になります。

  2. Bean をカスタマイズするために GlobalMethodSecurityConfiguration を継承する必要はなく、直接 Bean ベースの構成を優先します

  3. ネイティブ Spring AOP を使用して構築され、抽象化を削除し、Spring AOP ビルドブロックを使用してカスタマイズできるようにします

  4. 競合するアノテーションをチェックして、明確なセキュリティ構成を確保します

  5. JSR-250 に準拠

  6. デフォルトで @PreAuthorize@PostAuthorize@PreFilter@PostFilter を有効にします

以前のバージョンについては、@EnableGlobalMethodSecurity での同様のサポートについて参照してください。

例: 次の場合、Spring Security の @PreAuthorize アノテーションが有効になります。

メソッドセキュリティ構成
  • Java

  • Kotlin

  • XML

@EnableMethodSecurity
public class MethodSecurityConfig {
	// ...
}
@EnableMethodSecurity
class MethodSecurityConfig {
	// ...
}
<sec:method-security/>

(クラスまたはインターフェース上の)メソッドにアノテーションを追加すると、それに応じてそのメソッドへのアクセスが制限されます。Spring Security のネイティブアノテーションサポートは、メソッドの一連の属性を定義します。これらは、実際の決定を行うために DefaultAuthorizationMethodInterceptorChain に渡されます。

メソッドセキュリティアノテーションの使用箇所
  • Java

  • Kotlin

public interface BankService {
	@PreAuthorize("hasRole('USER')")
	Account readAccount(Long id);

	@PreAuthorize("hasRole('USER')")
	List<Account> findAccounts();

	@PreAuthorize("hasRole('TELLER')")
	Account post(Account account, Double amount);
}
interface BankService {
	@PreAuthorize("hasRole('USER')")
	fun readAccount(id : Long) : Account

	@PreAuthorize("hasRole('USER')")
	fun findAccounts() : List<Account>

	@PreAuthorize("hasRole('TELLER')")
	fun post(account : Account, amount : Double) : Account
}

以下を使用して、Spring Security の @Secured アノテーションのサポートを有効にできます。

@Secured の設定
  • Java

  • Kotlin

  • XML

@EnableMethodSecurity(securedEnabled = true)
public class MethodSecurityConfig {
	// ...
}
@EnableMethodSecurity(securedEnabled = true)
class MethodSecurityConfig {
	// ...
}
<sec:method-security secured-enabled="true"/>

または JSR-250 を使用:

JSR-250 構成
  • Java

  • Kotlin

  • XML

@EnableMethodSecurity(jsr250Enabled = true)
public class MethodSecurityConfig {
	// ...
}
@EnableMethodSecurity(jsr250Enabled = true)
class MethodSecurityConfig {
	// ...
}
<sec:method-security jsr250-enabled="true"/>

認可のカスタマイズ

Spring Security の @PreAuthorize@PostAuthorize@PreFilter@PostFilter には、表現ベースの豊富なサポートが付属しています。

式の処理方法をカスタマイズする必要がある場合は、次のようにカスタム MethodSecurityExpressionHandler を公開できます。

カスタム MethodSecurityExpressionHandler
  • Java

  • Kotlin

  • XML

@Bean
static MethodSecurityExpressionHandler methodSecurityExpressionHandler() {
	DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler();
	handler.setTrustResolver(myCustomTrustResolver);
	return handler;
}
companion object {
	@Bean
	fun methodSecurityExpressionHandler() : MethodSecurityExpressionHandler {
		val handler = DefaultMethodSecurityExpressionHandler();
		handler.setTrustResolver(myCustomTrustResolver);
		return handler;
	}
}
<sec:method-security>
	<sec:expression-handler ref="myExpressionHandler"/>
</sec:method-security>

<bean id="myExpressionHandler"
		class="org.springframework.security.messaging.access.expression.DefaultMessageSecurityExpressionHandler">
	<property name="trustResolver" ref="myCustomTrustResolver"/>
</bean>

static メソッドを使用して MethodSecurityExpressionHandler を公開し、Spring Security のメソッドセキュリティ @Configuration クラスを初期化する前に Spring がそれを公開するようにします。

また、ロールベースの認可の場合、Spring Security はデフォルトの ROLE_ プレフィックスを追加します。これは、hasRole などの式を評価するときに使用されます。

次のように、GrantedAuthorityDefaults Bean を公開することにより、異なるプレフィックスを使用するように認可ルールを構成できます。

カスタム MethodSecurityExpressionHandler
  • Java

  • Kotlin

  • XML

@Bean
static GrantedAuthorityDefaults grantedAuthorityDefaults() {
	return new GrantedAuthorityDefaults("MYPREFIX_");
}
companion object {
	@Bean
	fun grantedAuthorityDefaults() : GrantedAuthorityDefaults {
		return GrantedAuthorityDefaults("MYPREFIX_");
	}
}
<sec:method-security/>

<bean id="grantedAuthorityDefaults" class="org.springframework.security.config.core.GrantedAuthorityDefaults">
	<constructor-arg value="MYPREFIX_"/>
</bean>

static メソッドを使用して GrantedAuthorityDefaults を公開し、Spring Security のメソッドセキュリティ @Configuration クラスを初期化する前に Spring がそれを公開するようにします。

カスタム認可マネージャー

メソッド認証は、メソッド前とメソッド後の認証を組み合わせたものです。

メソッド前の認可は、メソッドが呼び出される前に実行されます。その認可がアクセスを拒否した場合、メソッドは呼び出されず、AccessDeniedException がスローされます。メソッドが呼び出された後、メソッドが呼び出し元に戻る前に、メソッド後の認可が実行されます。その認可がアクセスを拒否した場合、値は返されず、AccessDeniedException がスローされます

@EnableMethodSecurity の追加がデフォルトで行うことを再現するには、次の構成を公開します。

完全なポストポストメソッドのセキュリティ構成
  • Java

  • Kotlin

  • XML

@EnableMethodSecurity(prePostEnabled = false)
class MethodSecurityConfig {
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	Advisor preFilterAuthorizationMethodInterceptor() {
		return new PreFilterAuthorizationMethodInterceptor();
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	Advisor preAuthorizeAuthorizationMethodInterceptor() {
		return AuthorizationManagerBeforeMethodInterceptor.preAuthorize();
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	Advisor postAuthorizeAuthorizationMethodInterceptor() {
		return AuthorizationManagerAfterMethodInterceptor.postAuthorize();
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	Advisor postFilterAuthorizationMethodInterceptor() {
		return new PostFilterAuthorizationMethodInterceptor();
	}
}
@EnableMethodSecurity(prePostEnabled = false)
class MethodSecurityConfig {
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	fun preFilterAuthorizationMethodInterceptor() : Advisor {
		return PreFilterAuthorizationMethodInterceptor();
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	fun preAuthorizeAuthorizationMethodInterceptor() : Advisor {
		return AuthorizationManagerBeforeMethodInterceptor.preAuthorize();
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	fun postAuthorizeAuthorizationMethodInterceptor() : Advisor {
		return AuthorizationManagerAfterMethodInterceptor.postAuthorize();
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	fun postFilterAuthorizationMethodInterceptor() : Advisor {
		return PostFilterAuthorizationMethodInterceptor();
	}
}
<sec:method-security pre-post-enabled="false"/>

<aop:config/>

<bean id="preFilterAuthorizationMethodInterceptor"
		class="org.springframework.security.authorization.method.PreFilterAuthorizationMethodInterceptor"/>
<bean id="preAuthorizeAuthorizationMethodInterceptor"
		class="org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor"
		factory-method="preAuthorize"/>
<bean id="postAuthorizeAuthorizationMethodInterceptor"
		class="org.springframework.security.authorization.method.AuthorizationManagerAfterMethodInterceptor"
		factory-method="postAuthorize"/>
<bean id="postFilterAuthorizationMethodInterceptor"
		class="org.springframework.security.authorization.method.PostFilterAuthorizationMethodInterceptor"/>

Spring Security のメソッドセキュリティは Spring AOP を使用して構築されていることに注意してください。インターセプターは指定された順序に基づいて呼び出されます。これは、次のようにインターセプターインスタンスで setOrder を呼び出すことによってカスタマイズできます。

カスタムアドバイザーを公開する
  • Java

  • Kotlin

  • XML

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
Advisor postFilterAuthorizationMethodInterceptor() {
	PostFilterAuthorizationMethodInterceptor interceptor = new PostFilterAuthorizationMethodInterceptor();
	interceptor.setOrder(AuthorizationInterceptorOrders.POST_AUTHORIZE.getOrder() - 1);
	return interceptor;
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
fun postFilterAuthorizationMethodInterceptor() : Advisor {
	val interceptor = PostFilterAuthorizationMethodInterceptor();
	interceptor.setOrder(AuthorizationInterceptorOrders.POST_AUTHORIZE.getOrder() - 1);
	return interceptor;
}
<bean id="postFilterAuthorizationMethodInterceptor"
		class="org.springframework.security.authorization.method.PostFilterAuthorizationMethodInterceptor">
	<property name="order"
			value="#{T(org.springframework.security.authorization.method.AuthorizationInterceptorsOrder).POST_AUTHORIZE.getOrder() -1}"/>
</bean>

アプリケーションで @PreAuthorize のみをサポートしたい場合は、次のようにすることができます。

@PreAuthorize 構成のみ
  • Java

  • Kotlin

  • XML

@EnableMethodSecurity(prePostEnabled = false)
class MethodSecurityConfig {
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	Advisor preAuthorize() {
		return AuthorizationManagerBeforeMethodInterceptor.preAuthorize();
	}
}
@EnableMethodSecurity(prePostEnabled = false)
class MethodSecurityConfig {
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	fun preAuthorize() : Advisor {
		return AuthorizationManagerBeforeMethodInterceptor.preAuthorize()
	}
}
<sec:method-security pre-post-enabled="false"/>

<aop:config/>

<bean id="preAuthorizeAuthorizationMethodInterceptor"
	class="org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor"
	factory-method="preAuthorize"/>

または、リストに追加するカスタムの before-method AuthorizationManager がある場合があります。

この場合、AuthorizationManager と、認可マネージャーが適用するメソッドとクラスの両方を Spring Security に通知する必要があります。

次のように、@PreAuthorize と @PostAuthorize の間で AuthorizationManager を呼び出すように Spring Security を構成できます。

カスタムビフォアアドバイザー
  • Java

  • Kotlin

  • XML

@EnableMethodSecurity
class MethodSecurityConfig {
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public Advisor customAuthorize() {
		JdkRegexpMethodPointcut pattern = new JdkRegexpMethodPointcut();
		pattern.setPattern("org.mycompany.myapp.service.*");
		AuthorizationManager<MethodInvocation> rule = AuthorityAuthorizationManager.isAuthenticated();
		AuthorizationManagerBeforeMethodInterceptor interceptor = new AuthorizationManagerBeforeMethodInterceptor(pattern, rule);
		interceptor.setOrder(AuthorizationInterceptorsOrder.PRE_AUTHORIZE_ADVISOR_ORDER.getOrder() + 1);
		return interceptor;
    }
}
@EnableMethodSecurity
class MethodSecurityConfig {
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	fun customAuthorize() : Advisor {
		val pattern = JdkRegexpMethodPointcut();
		pattern.setPattern("org.mycompany.myapp.service.*");
		val rule = AuthorityAuthorizationManager.isAuthenticated();
		val interceptor = AuthorizationManagerBeforeMethodInterceptor(pattern, rule);
		interceptor.setOrder(AuthorizationInterceptorsOrder.PRE_AUTHORIZE_ADVISOR_ORDER.getOrder() + 1);
		return interceptor;
	}
}
<sec:method-security/>

<aop:config/>

<bean id="customAuthorize"
		class="org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor">
	<constructor-arg>
		<bean class="org.springframework.aop.support.JdkRegexpMethodPointcut">
			<property name="pattern" value="org.mycompany.myapp.service.*"/>
		</bean>
	</constructor-arg>
	<constructor-arg>
		<bean class="org.springframework.security.authorization.AuthorityAuthorizationManager"
				factory-method="isAuthenticated"/>
	</constructor-arg>
	<property name="order"
			value="#{T(org.springframework.security.authorization.method.AuthorizationInterceptorsOrder).PRE_AUTHORIZE_ADVISOR_ORDER.getOrder() + 1}"/>
</bean>

AuthorizationInterceptorsOrder で指定された順序定数を使用して、Spring Security メソッドインターセプターの間にインターセプターを配置できます。

メソッド後の認可についても同じことができます。メソッド後の認可は、通常、戻り値を分析してアクセスを検証することに関係しています。

例: 次のように、リクエストされたアカウントが実際にログインしたユーザーに属していることを確認するメソッドがある場合があります。

@PostAuthorize の例
  • Java

  • Kotlin

public interface BankService {

	@PreAuthorize("hasRole('USER')")
	@PostAuthorize("returnObject.owner == authentication.name")
	Account readAccount(Long id);
}
interface BankService {

	@PreAuthorize("hasRole('USER')")
	@PostAuthorize("returnObject.owner == authentication.name")
	fun readAccount(id : Long) : Account
}

独自の AuthorizationMethodInterceptor を指定して、戻り値へのアクセスの評価方法をカスタマイズできます。

例: 独自のカスタムアノテーションがある場合は、次のように構成できます。

カスタムアフターアドバイザー
  • Java

  • Kotlin

  • XML

@EnableMethodSecurity
class MethodSecurityConfig {
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public Advisor customAuthorize(AuthorizationManager<MethodInvocationResult> rules) {
		AnnotationMatchingPointcut pattern = new AnnotationMatchingPointcut(MySecurityAnnotation.class);
		AuthorizationManagerAfterMethodInterceptor interceptor = new AuthorizationManagerAfterMethodInterceptor(pattern, rules);
		interceptor.setOrder(AuthorizationInterceptorsOrder.POST_AUTHORIZE_ADVISOR_ORDER.getOrder() + 1);
		return interceptor;
	}
}
@EnableMethodSecurity
class MethodSecurityConfig {
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	fun customAuthorize(rules : AuthorizationManager<MethodInvocationResult>) : Advisor {
		val pattern = AnnotationMatchingPointcut(MySecurityAnnotation::class.java);
		val interceptor = AuthorizationManagerAfterMethodInterceptor(pattern, rules);
		interceptor.setOrder(AuthorizationInterceptorsOrder.POST_AUTHORIZE_ADVISOR_ORDER.getOrder() + 1);
		return interceptor;
	}
}
<sec:method-security/>

<aop:config/>

<bean id="customAuthorize"
		class="org.springframework.security.authorization.method.AuthorizationManagerAfterMethodInterceptor">
	<constructor-arg>
		<bean class="org.springframework.aop.support.annotation.AnnotationMethodMatcher">
			<constructor-arg value="#{T(org.mycompany.MySecurityAnnotation)}"/>
		</bean>
	</constructor-arg>
	<constructor-arg>
		<bean class="org.springframework.security.authorization.AuthorityAuthorizationManager"
				factory-method="isAuthenticated"/>
	</constructor-arg>
	<property name="order"
		value="#{T(org.springframework.security.authorization.method.AuthorizationInterceptorsOrder).PRE_AUTHORIZE_ADVISOR_ORDER.getOrder() + 1}"/>
</bean>

@PostAuthorize インターセプターの後に呼び出されます。

EnableGlobalMethodSecurity

@Configuration インスタンスで @EnableGlobalMethodSecurity アノテーションを使用して、アノテーションベースのセキュリティを有効にできます。例: 以下は、Spring Security の @Secured アノテーションを有効にします。

  • Java

  • Kotlin

@EnableGlobalMethodSecurity(securedEnabled = true)
public class MethodSecurityConfig {
// ...
}
@EnableGlobalMethodSecurity(securedEnabled = true)
open class MethodSecurityConfig {
	// ...
}

(クラスまたはインターフェース上の)メソッドにアノテーションを追加すると、それに応じてそのメソッドへのアクセスが制限されます。Spring Security のネイティブアノテーションサポートは、メソッドの属性セットを定義します。これらは、AccessDecisionManager に渡され、実際の決定が行われます。

  • Java

  • Kotlin

public interface BankService {

@Secured("IS_AUTHENTICATED_ANONYMOUSLY")
public Account readAccount(Long id);

@Secured("IS_AUTHENTICATED_ANONYMOUSLY")
public Account[] findAccounts();

@Secured("ROLE_TELLER")
public Account post(Account account, double amount);
}
interface BankService {
    @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
    fun readAccount(id: Long): Account

    @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
    fun findAccounts(): Array<Account>

    @Secured("ROLE_TELLER")
    fun post(account: Account, amount: Double): Account
}

JSR-250 アノテーションのサポートは、次を使用して有効にできます。

  • Java

  • Kotlin

@EnableGlobalMethodSecurity(jsr250Enabled = true)
public class MethodSecurityConfig {
// ...
}
@EnableGlobalMethodSecurity(jsr250Enabled = true)
open class MethodSecurityConfig {
	// ...
}

これらは標準ベースであり、単純なロールベースの制約を適用できますが、Spring Security のネイティブアノテーションはありません。新しい式ベースの構文を使用するには、次を使用します

  • Java

  • Kotlin

@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig {
// ...
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
open class MethodSecurityConfig {
	// ...
}

同等の Java コードは

  • Java

  • Kotlin

public interface BankService {

@PreAuthorize("isAnonymous()")
public Account readAccount(Long id);

@PreAuthorize("isAnonymous()")
public Account[] findAccounts();

@PreAuthorize("hasAuthority('ROLE_TELLER')")
public Account post(Account account, double amount);
}
interface BankService {
    @PreAuthorize("isAnonymous()")
    fun readAccount(id: Long): Account

    @PreAuthorize("isAnonymous()")
    fun findAccounts(): Array<Account>

    @PreAuthorize("hasAuthority('ROLE_TELLER')")
    fun post(account: Account, amount: Double): Account
}

GlobalMethodSecurityConfiguration

@EnableGlobalMethodSecurity アノテーションで許可されるよりも複雑な操作を実行する必要がある場合があります。これらのインスタンスでは、GlobalMethodSecurityConfiguration を継承して、@EnableGlobalMethodSecurity アノテーションがサブクラスに存在することを確認できます。例: カスタム MethodSecurityExpressionHandler を提供する場合、次の構成を使用できます。

  • Java

  • Kotlin

@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
	@Override
	protected MethodSecurityExpressionHandler createExpressionHandler() {
		// ... create and return custom MethodSecurityExpressionHandler ...
		return expressionHandler;
	}
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
open class MethodSecurityConfig : GlobalMethodSecurityConfiguration() {
    override fun createExpressionHandler(): MethodSecurityExpressionHandler {
        // ... create and return custom MethodSecurityExpressionHandler ...
        return expressionHandler
    }
}

オーバーライドできるメソッドの詳細については、GlobalMethodSecurityConfiguration Javadoc を参照してください。

<global-method-security> 要素

この要素は、(要素に適切な属性を設定することにより)アプリケーションでアノテーションベースのセキュリティを有効にし、アプリケーションコンテキスト全体に適用されるセキュリティポイントカット宣言をグループ化するために使用されます。<global-method-security> 要素を 1 つだけ宣言する必要があります。次の宣言により、Spring Security の @Secured のサポートが有効になります。

<global-method-security secured-annotations="enabled" />

(クラスまたはインターフェース上の)メソッドにアノテーションを追加すると、それに応じてそのメソッドへのアクセスが制限されます。Spring Security のネイティブアノテーションサポートは、メソッドの属性セットを定義します。これらは、実際の決定を行うために AccessDecisionManager に渡されます。

  • Java

  • Kotlin

public interface BankService {

@Secured("IS_AUTHENTICATED_ANONYMOUSLY")
public Account readAccount(Long id);

@Secured("IS_AUTHENTICATED_ANONYMOUSLY")
public Account[] findAccounts();

@Secured("ROLE_TELLER")
public Account post(Account account, double amount);
}
interface BankService {
    @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
    fun readAccount(id: Long): Account

    @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
    fun findAccounts(): Array<Account>

    @Secured("ROLE_TELLER")
    fun post(account: Account, amount: Double): Account
}

JSR-250 アノテーションのサポートは、次を使用して有効にできます。

<global-method-security jsr250-annotations="enabled" />

これらは標準ベースであり、単純なロールベースの制約を適用できますが、Spring Security のネイティブアノテーションはありません。新しい式ベースの構文を使用するには、次を使用します

<global-method-security pre-post-annotations="enabled" />

同等の Java コードは

  • Java

  • Kotlin

public interface BankService {

@PreAuthorize("isAnonymous()")
public Account readAccount(Long id);

@PreAuthorize("isAnonymous()")
public Account[] findAccounts();

@PreAuthorize("hasAuthority('ROLE_TELLER')")
public Account post(Account account, double amount);
}
interface BankService {
    @PreAuthorize("isAnonymous()")
    fun readAccount(id: Long): Account

    @PreAuthorize("isAnonymous()")
    fun findAccounts(): Array<Account>

    @PreAuthorize("hasAuthority('ROLE_TELLER')")
    fun post(account: Account, amount: Double): Account
}

式ベースのアノテーションは、ユーザーの権限リストに対するロール名のチェックにとどまらない単純なルールを定義する必要がある場合に適しています。

アノテーション付きメソッドは、Spring Bean として定義されているインスタンスに対してのみ保護されます(メソッドセキュリティが有効になっている同じアプリケーションコンテキスト内)。Spring によって作成されていないインスタンスを保護する場合(たとえば、new オペレーターを使用)、AspectJ を使用する必要があります。

同じアプリケーションで複数の型のアノテーションを有効にできますが、他の方法では動作が適切に定義されないため、インターフェースまたはクラスには 1 つの型のみを使用する必要があります。特定のメソッドに適用される 2 つのアノテーションが見つかった場合、そのうちの 1 つだけが適用されます。

protect-pointcut を使用したセキュリティポイントカットの追加

protect-pointcut の使用は、単純な宣言のみで多くの Bean にセキュリティを適用できるため、特に強力です。次の例を考えてみましょう。

<global-method-security>
<protect-pointcut expression="execution(* com.mycompany.*Service.*(..))"
	access="ROLE_USER"/>
</global-method-security>

これにより、クラスが com.mycompany パッケージにあり、クラス名が "Service" で終わるアプリケーションコンテキストで宣言された Bean のすべてのメソッドが保護されます。ROLE_USER ロールを持つユーザーのみがこれらのメソッドを呼び出すことができます。URL マッチングと同様に、最初のマッチング表現が使用されるため、ポイントカットのリストで最も具体的な一致が最初に来る必要があります。セキュリティアノテーションはポイントカットよりも優先されます。