# 方法安全性

从版本 2.0 开始 Spring，安全性大大提高了对向服务层方法添加安全性的支持。它提供了对 JSR-250 注释安全性的支持，以及框架的原始`@Secured`注释。从 3.0 开始，你还可以使用 New[基于表达式的注释](expression-based.html#el-access)。你可以对单个 Bean 应用安全性，使用`intercept-methods`元素来装饰 Bean 声明，或者可以使用 AspectJ 样式的切入点在整个服务层中保护多个 bean。

## EnableMethodSecurity

在 Spring Security5.6 中，我们可以在任何`@Configuration`实例上使用`@EnableMethodSecurity`注释来启用基于注释的安全性。

这在许多方面改进了`@启用全球方法安全`。`@EnableMethodSecurity`:

1. 使用简化的`AuthorizationManager`API，而不是元数据源、配置属性、决策管理器和投票者。这简化了重用和定制。

2. 支持基于直接 Bean 的配置，而不是要求扩展`GlobalMethodSecurityConfiguration`来定制 bean

3. 是使用本机 Spring  AOP 构建的，删除了抽象，并允许你使用 Spring  AOP 构建块来自定义

4. 检查相互冲突的注释，以确保安全配置的明确性.

5. 符合 JSR-250

6. 默认情况下启用`@PreAuthorize`、`@PostAuthorize`、`@PreFilter`和`@PostFilter`

|   |对于更早的版本，请阅读[@enableGlobalMethodSecurity ](#jc-enable-global-method-security)的类似支持。|
|---|------------------------------------------------------------------------------------------------------------------------------|

例如，下面将启用 Spring Security 的`@PreAuthorize`注释：

例 1。方法安全配置

爪哇

```
@EnableMethodSecurity
public class MethodSecurityConfig {
	// ...
}
```

Kotlin

```
@EnableMethodSecurity
class MethodSecurityConfig {
	// ...
}
```

XML

```
<sec:method-security/>
```

然后，向方法（在类或接口上）添加注释将相应地限制对该方法的访问。 Spring Security 的本机注释支持为该方法定义了一组属性。这些将传递给`DefaultAuthorizationMethodInterceptorChain`，以便它做出实际的决定：

例 2。方法安全注释的使用

爪哇

```
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);
}
```

Kotlin

```
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`注释的支持：

例 3。@Secured Configuration

爪哇

```
@EnableMethodSecurity(securedEnabled = true)
public class MethodSecurityConfig {
	// ...
}
```

Kotlin

```
@EnableMethodSecurity(securedEnabled = true)
class MethodSecurityConfig {
	// ...
}
```

XML

```
<sec:method-security secured-enabled="true"/>
```

或 JSR-250 使用：

例 4。JSR-250 配置

爪哇

```
@EnableMethodSecurity(jsr250Enabled = true)
public class MethodSecurityConfig {
	// ...
}
```

Kotlin

```
@EnableMethodSecurity(jsr250Enabled = true)
class MethodSecurityConfig {
	// ...
}
```

XML

```
<sec:method-security jsr250-enabled="true"/>
```

### 自定义授权

Spring Security 的`@PreAuthorize`、`@PostAuthorize`、`@PreFilter`和`@PostFilter`提供了丰富的基于表达式的支持。

如果需要自定义表达式的处理方式，可以公开一个自定义`MethodSecurityExpressionHandler`，如下所示：

例 5。自定义方法 SecurityExpressionHandler

爪哇

```
@Bean
static MethodSecurityExpressionHandler methodSecurityExpressionHandler() {
	DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler();
	handler.setTrustResolver(myCustomTrustResolver);
	return handler;
}
```

Kotlin

```
companion object {
	@Bean
	fun methodSecurityExpressionHandler() : MethodSecurityExpressionHandler {
		val handler = DefaultMethodSecurityExpressionHandler();
		handler.setTrustResolver(myCustomTrustResolver);
		return handler;
	}
}
```

XML

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

|   |我们使用`MethodSecurityExpressionHandler`方法公开`static`，以确保 Spring 在初始化 Spring Security 的方法 Security`@Configuration`类之前发布它|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

另外，对于基于角色的授权， Spring Security 添加了一个默认的`ROLE_`前缀，该前缀在计算`hasRole`之类的表达式时使用。

可以通过公开`GrantedAuthorityDefaults` Bean 来将授权规则配置为使用不同的前缀，如下所示：

例 6。自定义方法 SecurityExpressionHandler

爪哇

```
@Bean
static GrantedAuthorityDefaults grantedAuthorityDefaults() {
	return new GrantedAuthorityDefaults("MYPREFIX_");
}
```

Kotlin

```
companion object {
	@Bean
	fun grantedAuthorityDefaults() : GrantedAuthorityDefaults {
		return GrantedAuthorityDefaults("MYPREFIX_");
	}
}
```

XML

```
<sec:method-security/>

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

|   |我们使用`GrantedAuthorityDefaults`方法公开`static`，以确保 Spring 在初始化 Spring Security 的方法 Security`@Configuration`类之前发布它|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

### 自定义授权管理器

方法授权是方法授权之前和方法授权之后的组合。

|   |在方法被调用之前执行前方法授权。<br/>如果该授权拒绝访问，则不调用该方法，并抛出一个`AccessDeniedException`<br/>后方法授权是在方法被调用之后，但在方法返回调用者之前执行的。<br/>如果该授权拒绝访问，不返回该值，并抛出一个`AccessDeniedException`|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

要重新创建添加`@EnableMethodSecurity`所做的默认操作，你需要发布以下配置：

例 7。完整的 pre-post 方法安全配置

爪哇

```
@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();
	}
}
```

Kotlin

```
@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();
	}
}
```

XML

```
<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`进行自定义，如下所示：

例 8。发布自定义顾问

爪哇

```
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
Advisor postFilterAuthorizationMethodInterceptor() {
	PostFilterAuthorizationMethodInterceptor interceptor = new PostFilterAuthorizationMethodInterceptor();
	interceptor.setOrder(AuthorizationInterceptorOrders.POST_AUTHORIZE.getOrder() - 1);
	return interceptor;
}
```

Kotlin

```
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
fun postFilterAuthorizationMethodInterceptor() : Advisor {
	val interceptor = PostFilterAuthorizationMethodInterceptor();
	interceptor.setOrder(AuthorizationInterceptorOrders.POST_AUTHORIZE.getOrder() - 1);
	return interceptor;
}
```

XML

```
<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`，在这种情况下，你可以执行以下操作：

例 9。仅 @preauthorize 配置

爪哇

```
@EnableMethodSecurity(prePostEnabled = false)
class MethodSecurityConfig {
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	Advisor preAuthorize() {
		return AuthorizationManagerBeforeMethodInterceptor.preAuthorize();
	}
}
```

Kotlin

```
@EnableMethodSecurity(prePostEnabled = false)
class MethodSecurityConfig {
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	fun preAuthorize() : Advisor {
		return AuthorizationManagerBeforeMethodInterceptor.preAuthorize()
	}
}
```

XML

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

在这种情况下，你需要告知 Spring 安全性`AuthorizationManager`以及你的授权管理器应用到哪些方法和类。

因此，可以将 Spring 安全性配置为在`@PreAuthorize`和`@PostAuthorize`之间调用`AuthorizationManager`，就像这样：

例 10。顾问之前的自定义

爪哇

```
@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;
    }
}
```

Kotlin

```
@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;
	}
}
```

XML

```
<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 安全方法拦截器之间。|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------|

对于后方法授权也可以这样做。后方法授权通常涉及分析返回值以验证访问。

例如，你可能有一个方法来确认请求的帐户实际上属于登录用户，如下所示：

例 11。@postauthorize 示例

爪哇

```
public interface BankService {

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

Kotlin

```
interface BankService {

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

你可以提供自己的`AuthorizationMethodInterceptor`以自定义如何计算对返回值的访问。

例如，如果你有自己的自定义注释，那么可以这样配置它：

例 12。自定义后的顾问

爪哇

```
@EnableMethodSecurity
class MethodSecurityConfig {
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public Advisor customAuthorize(AuthorizationManager<MethodInvocationResult> rules) {
		AnnotationMethodMatcher pattern = new AnnotationMethodMatcher(MySecurityAnnotation.class);
		AuthorizationManagerAfterMethodInterceptor interceptor = new AuthorizationManagerAfterMethodInterceptor(pattern, rules);
		interceptor.setOrder(AuthorizationInterceptorsOrder.POST_AUTHORIZE_ADVISOR_ORDER.getOrder() + 1);
		return interceptor;
	}
}
```

Kotlin

```
@EnableMethodSecurity
class MethodSecurityConfig {
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	fun customAuthorize(rules : AuthorizationManager<MethodInvocationResult>) : Advisor {
		val pattern = AnnotationMethodMatcher(MySecurityAnnotation::class.java);
		val interceptor = AuthorizationManagerAfterMethodInterceptor(pattern, rules);
		interceptor.setOrder(AuthorizationInterceptorsOrder.POST_AUTHORIZE_ADVISOR_ORDER.getOrder() + 1);
		return interceptor;
	}
}
```

XML

```
<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`注释。

爪哇

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

Kotlin

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

然后，向方法（在类或接口上）添加注释将相应地限制对该方法的访问。 Spring Security 的本机注释支持为该方法定义了一组属性。这些将被传递给 accessDecisionManager，以便它做出实际的决定：

爪哇

```
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);
}
```

Kotlin

```
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 注释的支持

爪哇

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

Kotlin

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

这些是基于标准的，允许应用简单的基于角色的约束，但不具有 Spring Security 的本机注释的功能。要使用新的基于表达式的语法，你可以使用

爪哇

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

Kotlin

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

与之对应的 爪哇 代码是

爪哇

```
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);
}
```

Kotlin

```
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`，则可以使用以下配置：

爪哇

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

Kotlin

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

有关可以重写的方法的其他信息，请参阅`GlobalMethodSecurityConfiguration`爪哇doc。

## \<global-method-security\>元素

此元素用于在应用程序中启用基于注释的安全性（通过在元素上设置适当的属性），还用于将安全性切入点声明组合在一起，这些声明将在整个应用程序上下文中应用。你应该只声明一个`<global-method-security>`元素。以下声明将支持 Spring Security 的`@Secured`:

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

然后，向方法（在类或接口上）添加注释将相应地限制对该方法的访问。 Spring Security 的本机注释支持为该方法定义了一组属性。这些将被传递到`AccessDecisionManager`，以便它做出实际的决定：

Java

```
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);
}
```

Kotlin

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

```
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);
}
```

Kotlin

```
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 的实例（在启用方法安全性的相同应用程序上下文中）进行保护。<br/>如果你想保护不是由 Spring 创建的实例（例如，使用`new`操作符），那么你需要使用 AspectJ。|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

|   |你可以在同一个应用程序中启用多个类型的注释，但是对于任何接口或类只应使用一种类型，因为在其他情况下，行为不会被很好地定义。，<br/>如果发现两个注释适用于特定的方法，然后只应用其中的一个。|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

## 使用 protect-pointcut 添加安全切入点

`protect-pointcut`的使用特别强大，因为它允许你只需简单的声明就可以将安全性应用于许多 bean。考虑以下示例：

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

这将保护在应用程序上下文中声明的 bean 上的所有方法，这些 bean 的类在`com.mycompany`包中，其类名以“service”结尾。只有具有`ROLE_USER`角色的用户才能够调用这些方法。与 URL 匹配一样，最特定的匹配必须在切入点列表中排在第一位，因为将使用第一个匹配表达式。安全性注释优先于切入点。

[安全对象实现](secure-objects.html)[域对象安全 ACLS](acls.html)

