Authorization Architecture
本节介绍适用于授权的 Spring Security 架构。
This section describes the Spring Security architecture that applies to authorization.
Authorities
Authentication
讨论了所有 `Authentication`实现如何存储一个 `GrantedAuthority`对象列表。这些对象表示已授予主体的权限。`GrantedAuthority`对象由 `AuthenticationManager`插入 `Authentication`对象,稍后由 `AccessDecisionManager`实例在做出授权决策时读取。
Authentication
discusses how all Authentication
implementations store a list of GrantedAuthority
objects.
These represent the authorities that have been granted to the principal.
The GrantedAuthority
objects are inserted into the Authentication
object by the AuthenticationManager
and are later read by AccessDecisionManager
instances when making authorization decisions.
GrantedAuthority
接口只有一个方法:
The GrantedAuthority
interface has only one method:
String getAuthority();
此方法由 AuthorizationManager
实例用于获取 GrantedAuthority
的精确 String
表示。通过将表示返回为 String
,大多数 AuthorizationManager
实现都可以轻松“读取”GrantedAuthority
。如果 GrantedAuthority
无法精确表示为 String
,则 GrantedAuthority
被视为“复杂”的,且 getAuthority()
必须返回 null
。
This method is used by an
AuthorizationManager
instance to obtain a precise String
representation of the GrantedAuthority
.
By returning a representation as a String
, a GrantedAuthority
can be easily "read" by most AuthorizationManager
implementations.
If a GrantedAuthority
cannot be precisely represented as a String
, the GrantedAuthority
is considered "complex" and getAuthority()
must return null
.
复杂 GrantedAuthority
的示例是存储适用于不同客户帐号号的操作和权限阈值的列表的实现。以 String
表示此复杂的 GrantedAuthority
非常困难。因此,getAuthority()
方法应返回 null
。这向任何 AuthorizationManager
表明它需要支持特定 GrantedAuthority
实现才能理解其内容。
An example of a complex GrantedAuthority
would be an implementation that stores a list of operations and authority thresholds that apply to different customer account numbers.
Representing this complex GrantedAuthority
as a String
would be quite difficult. As a result, the getAuthority()
method should return null
.
This indicates to any AuthorizationManager
that it needs to support the specific GrantedAuthority
implementation to understand its contents.
Spring Security 包含一个具体的 GrantedAuthority
实现:SimpleGrantedAuthority
。此实现允许将任何用户指定的 String
转换为 GrantedAuthority
。安全架构中包含的所有 AuthenticationProvider
实例都使用 SimpleGrantedAuthority
填充 Authentication
对象。
Spring Security includes one concrete GrantedAuthority
implementation: SimpleGrantedAuthority
.
This implementation lets any user-specified String
be converted into a GrantedAuthority
.
All AuthenticationProvider
instances included with the security architecture use SimpleGrantedAuthority
to populate the Authentication
object.
By default, role-based authorization rules include ROLE_
as a prefix.
This means that if there is an authorization rule that requires a security context to have a role of "USER", Spring Security will by default look for a GrantedAuthority#getAuthority
that returns "ROLE_USER".
您可以使用 GrantedAuthorityDefaults
自定义此内容。GrantedAuthorityDefaults
存在允许自定义基于角色的授权规则所使用的前缀。
You can customize this with GrantedAuthorityDefaults
.
GrantedAuthorityDefaults
exists to allow customizing the prefix to use for role-based authorization rules.
您可以通过公开一个 GrantedAuthorityDefaults
bean 来配置授权规则以使用不同的前缀,如下所示:
You can configure the authorization rules to use a different prefix by exposing a GrantedAuthorityDefaults
bean, like so:
-
Java
-
Kotlin
-
Xml
@Bean
static GrantedAuthorityDefaults grantedAuthorityDefaults() {
return new GrantedAuthorityDefaults("MYPREFIX_");
}
companion object {
@Bean
fun grantedAuthorityDefaults() : GrantedAuthorityDefaults {
return GrantedAuthorityDefaults("MYPREFIX_");
}
}
<bean id="grantedAuthorityDefaults" class="org.springframework.security.config.core.GrantedAuthorityDefaults">
<constructor-arg value="MYPREFIX_"/>
</bean>
您可以使用 You expose |
Invocation Handling
Spring Security 提供控制访问安全对象的拦截器,例如方法调用或 Web 请求。是否允许调用继续的预调用决定由 AuthorizationManager
实例执行。对于给定值是否可以返回的调用后决定也由 AuthorizationManager
实例执行。
Spring Security provides interceptors that control access to secure objects, such as method invocations or web requests.
A pre-invocation decision on whether the invocation is allowed to proceed is made by AuthorizationManager
instances.
Also post-invocation decisions on whether a given value may be returned is made by AuthorizationManager
instances.
The AuthorizationManager
AuthorizationManager
取代了 <<`AccessDecisionManager` 和 AccessDecisionVoter
,authz-legacy-note>>。
AuthorizationManager
supersedes both <<`AccessDecisionManager` and AccessDecisionVoter
,authz-legacy-note>>.
鼓励自定义 AccessDecisionManager
或 AccessDecisionVoter
的应用程序 change to using AuthorizationManager
。
Applications that customize an AccessDecisionManager
or AccessDecisionVoter
are encouraged to authz-voter-adaptation.
AuthorizationManager`s are called by Spring Security’s request-based, method-based, and message-based authorization components and are responsible for making final access control decisions.
The `AuthorizationManager
接口包含两个方法:
AuthorizationManager`s are called by Spring Security’s request-based, method-based, and message-based authorization components and are responsible for making final access control decisions.
The `AuthorizationManager
interface contains two methods:
AuthorizationDecision check(Supplier<Authentication> authentication, Object secureObject);
default AuthorizationDecision verify(Supplier<Authentication> authentication, Object secureObject)
throws AccessDeniedException {
// ...
}
AuthorizationManager’s `check
方法传递了做出授权决策所需的所有相关信息。特别是,传递安全的 Object
可以检查包含在实际安全对象调用中的那些参数。例如,假设安全对象是 MethodInvocation
。那么很容易为任何 Customer
参数查询 MethodInvocation
,然后在 AuthorizationManager
中实现某种安全逻辑以确保主体被允许对该客户进行操作。预期实现如果授予访问权限,则返回正 AuthorizationDecision
;如果拒绝访问权限,则返回负 AuthorizationDecision
;如果弃权做出决定,则返回 null AuthorizationDecision
。
The AuthorizationManager’s `check
method is passed all the relevant information it needs in order to make an authorization decision.
In particular, passing the secure Object
enables those arguments contained in the actual secure object invocation to be inspected.
For example, let’s assume the secure object was a MethodInvocation
.
It would be easy to query the MethodInvocation
for any Customer
argument, and then implement some sort of security logic in the AuthorizationManager
to ensure the principal is permitted to operate on that customer.
Implementations are expected to return a positive AuthorizationDecision
if access is granted, negative AuthorizationDecision
if access is denied, and a null AuthorizationDecision
when abstaining from making a decision.
verify
调用 check
,然后在负 AuthorizationDecision
的情况下引发 AccessDeniedException
。
verify
calls check
and subsequently throws an AccessDeniedException
in the case of a negative AuthorizationDecision
.
Delegate-based AuthorizationManager Implementations
虽然用户可以实现自己的 AuthorizationManager
来控制授权的所有方面,但 Spring Security 附带了一个可以与各个 AuthorizationManager
协作的委托 AuthorizationManager
。
Whilst users can implement their own AuthorizationManager
to control all aspects of authorization, Spring Security ships with a delegating AuthorizationManager
that can collaborate with individual `AuthorizationManager`s.
RequestMatcherDelegatingAuthorizationManager
将把请求与最合适的委托 AuthorizationManager
匹配。对于方法安全性,可以使用 AuthorizationManagerBeforeMethodInterceptor
和 AuthorizationManagerAfterMethodInterceptor
。
RequestMatcherDelegatingAuthorizationManager
will match the request with the most appropriate delegate AuthorizationManager
.
For method security, you can use AuthorizationManagerBeforeMethodInterceptor
and AuthorizationManagerAfterMethodInterceptor
.
Authorization Manager Implementations illustrates the relevant classes.
使用此方法,可以在授权决定中轮询 AuthorizationManager
实现的组成。
Using this approach, a composition of AuthorizationManager
implementations can be polled on an authorization decision.
AuthorityAuthorizationManager
Spring Security 提供的最常见的 AuthorizationManager
是 AuthorityAuthorizationManager
。它使用给定的权限集在当前 Authentication
上查找权限。如果 Authentication
包含任何配置的权限,则它将返回正 AuthorizationDecision
。否则,它将返回负 AuthorizationDecision
。
The most common AuthorizationManager
provided with Spring Security is AuthorityAuthorizationManager
.
It is configured with a given set of authorities to look for on the current Authentication
.
It will return positive AuthorizationDecision
should the Authentication
contain any of the configured authorities.
It will return a negative AuthorizationDecision
otherwise.
AuthenticatedAuthorizationManager
另一个管理程序是 AuthenticatedAuthorizationManager
。它可用于区分匿名用户、完全认证用户和记忆中认证用户。许多网站在记忆中认证下允许某些有限的访问权限,但要求用户通过登录来确认其身份以获得完全访问权限。
Another manager is the AuthenticatedAuthorizationManager
.
It can be used to differentiate between anonymous, fully-authenticated and remember-me authenticated users.
Many sites allow certain limited access under remember-me authentication, but require a user to confirm their identity by logging in for full access.
AuthorizationManagers
在 {security-api-url}org/springframework/security/authorization/AuthorizationManagers.html[AuthorizationManagers
] 中还有一些有用的静态工厂,用于将各个 AuthorizationManager
组合成更复杂的表达式。
There are also helpful static factories in {security-api-url}org/springframework/security/authorization/AuthorizationManagers.html[AuthorizationManagers
] for composing individual `AuthorizationManager`s into more sophisticated expressions.
Custom Authorization Managers
显然,您还可以实现一个自定义的 AuthorizationManager
,并且可以在其中放置您想要的任何访问控制逻辑。它可能特定于您的应用程序(与业务逻辑相关),或者它可以实现一些安全管理逻辑。例如,您可以创建一个可以查询开放策略代理或您自己的授权数据库的实现。
Obviously, you can also implement a custom AuthorizationManager
and you can put just about any access-control logic you want in it.
It might be specific to your application (business-logic related) or it might implement some security administration logic.
For example, you can create an implementation that can query Open Policy Agent or your own authorization database.
你会在 Spring 网站上发现 blog article,其中描述了如何使用过时的 |
You’ll find a blog article on the Spring web site which describes how to use the legacy |
Adapting AccessDecisionManager and AccessDecisionVoters
在 AuthorizationManager
之前,Spring Security 发布了 <<`AccessDecisionManager` 和 AccessDecisionVoter
,authz-legacy-note>>。
Previous to AuthorizationManager
, Spring Security published <<`AccessDecisionManager` and AccessDecisionVoter
,authz-legacy-note>>.
在某些情况下(如迁移较旧的应用程序),可能希望引入一个 AuthorizationManager
,它调用 AccessDecisionManager
或 AccessDecisionVoter
。
In some cases, like migrating an older application, it may be desirable to introduce an AuthorizationManager
that invokes an AccessDecisionManager
or AccessDecisionVoter
.
要调用现有的 AccessDecisionManager
,您可以执行以下操作:
To call an existing AccessDecisionManager
, you can do:
-
Java
@Component
public class AccessDecisionManagerAuthorizationManagerAdapter implements AuthorizationManager {
private final AccessDecisionManager accessDecisionManager;
private final SecurityMetadataSource securityMetadataSource;
@Override
public AuthorizationDecision check(Supplier<Authentication> authentication, Object object) {
try {
Collection<ConfigAttribute> attributes = this.securityMetadataSource.getAttributes(object);
this.accessDecisionManager.decide(authentication.get(), object, attributes);
return new AuthorizationDecision(true);
} catch (AccessDeniedException ex) {
return new AuthorizationDecision(false);
}
}
@Override
public void verify(Supplier<Authentication> authentication, Object object) {
Collection<ConfigAttribute> attributes = this.securityMetadataSource.getAttributes(object);
this.accessDecisionManager.decide(authentication.get(), object, attributes);
}
}
然后将其连接到 SecurityFilterChain
。
And then wire it into your SecurityFilterChain
.
或者要仅调用 AccessDecisionVoter
,您可以执行以下操作:
Or to only call an AccessDecisionVoter
, you can do:
-
Java
@Component
public class AccessDecisionVoterAuthorizationManagerAdapter implements AuthorizationManager {
private final AccessDecisionVoter accessDecisionVoter;
private final SecurityMetadataSource securityMetadataSource;
@Override
public AuthorizationDecision check(Supplier<Authentication> authentication, Object object) {
Collection<ConfigAttribute> attributes = this.securityMetadataSource.getAttributes(object);
int decision = this.accessDecisionVoter.vote(authentication.get(), object, attributes);
switch (decision) {
case ACCESS_GRANTED:
return new AuthorizationDecision(true);
case ACCESS_DENIED:
return new AuthorizationDecision(false);
}
return null;
}
}
然后将其连接到 SecurityFilterChain
。
And then wire it into your SecurityFilterChain
.
Hierarchical Roles
特定应用程序中的特定角色应自动“包含”其他角色是很常见的要求。例如,在具有“管理员”和“用户”角色概念的应用程序中,您可能希望管理员能够执行普通用户可以执行的所有操作。要实现此目的,您可以确保所有管理员用户也被分配了“用户”角色。或者,您可以修改每个需要“用户”角色的访问约束以包含“管理员”角色。如果您的应用程序中有很多不同的角色,可能会变得相当复杂。
It is a common requirement that a particular role in an application should automatically "include" other roles. For example, in an application which has the concept of an "admin" and a "user" role, you may want an admin to be able to do everything a normal user can. To achieve this, you can either make sure that all admin users are also assigned the "user" role. Alternatively, you can modify every access constraint which requires the "user" role to also include the "admin" role. This can get quite complicated if you have a lot of different roles in your application.
角色层次结构的使用允许您配置哪些角色(或权限)应包含其他角色。Spring Security 的 RoleVoter
、RoleHierarchyVoter
的扩展版本已配置 RoleHierarchy
,它从中获取用户被分配的所有“可访问权限”。典型的配置可能如下所示:
The use of a role-hierarchy allows you to configure which roles (or authorities) should include others.
An extended version of Spring Security’s RoleVoter
, RoleHierarchyVoter
, is configured with a RoleHierarchy
, from which it obtains all the "reachable authorities" which the user is assigned.
A typical configuration might look like this:
-
Java
-
Xml
@Bean
static RoleHierarchy roleHierarchy() {
return RoleHierarchyImpl.withDefaultRolePrefix()
.role("ADMIN").implies("STAFF")
.role("STAFF").implies("USER")
.role("USER").implies("GUEST")
.build();
}
// and, if using method security also add
@Bean
static MethodSecurityExpressionHandler methodSecurityExpressionHandler(RoleHierarchy roleHierarchy) {
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
expressionHandler.setRoleHierarchy(roleHierarchy);
return expressionHandler;
}
<bean id="roleHierarchy"
class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl" factory-method="fromHierarchy">
<constructor-arg>
<value>
ROLE_ADMIN > ROLE_STAFF
ROLE_STAFF > ROLE_USER
ROLE_USER > ROLE_GUEST
</value>
</constructor-arg>
</bean>
<!-- and, if using method security also add -->
<bean id="methodSecurityExpressionHandler"
class="org.springframework.security.access.expression.method.MethodSecurityExpressionHandler">
<property ref="roleHierarchy"/>
</bean>
|
|
此示例中,层次结构中有四个角色 ROLE_ADMIN ⇒ ROLE_STAFF ⇒ ROLE_USER ⇒ ROLE_GUEST
。使用 ROLE_ADMIN
认证过的用户在针对适应于调用上述 RoleHierarchyVoter
的 AuthorizationManager
评估安全约束时将表现为拥有所有四个角色。>
符号意为“包含”。
Here we have four roles in a hierarchy ROLE_ADMIN ⇒ ROLE_STAFF ⇒ ROLE_USER ⇒ ROLE_GUEST
.
A user who is authenticated with ROLE_ADMIN
, will behave as if they have all four roles when security constraints are evaluated against an AuthorizationManager
adapted to call the above RoleHierarchyVoter
.
The >
symbol can be thought of as meaning "includes".
角色层次结构提供了一种简化应用程序的访问控制配置数据和/或减少需要分配给用户权限数目的便捷手段。对于更复杂的要求,您可能希望在您的应用程序要求的特定访问权限和分配给用户的角色之间定义逻辑映射,并在加载用户信息时在两者之间进行转换。
Role hierarchies offer a convenient means of simplifying the access-control configuration data for your application and/or reducing the number of authorities which you need to assign to a user. For more complex requirements you may wish to define a logical mapping between the specific access-rights your application requires and the roles that are assigned to users, translating between the two when loading the user information.
Legacy Authorization Components
Spring Security包含一些旧版组件。由于其尚未被移除,因此包含文档以供参考。建议的替代方法如上。 |
Spring Security contains some legacy components. Since they are not yet removed, documentation is included for historical purposes. Their recommended replacements are above. |
The AccessDecisionManager
AccessDecisionManager
由 AbstractSecurityInterceptor
调用,负责做出最终的访问控制决策。AccessDecisionManager
接口包含三个方法:
The AccessDecisionManager
is called by the AbstractSecurityInterceptor
and is responsible for making final access control decisions.
The AccessDecisionManager
interface contains three methods:
void decide(Authentication authentication, Object secureObject,
Collection<ConfigAttribute> attrs) throws AccessDeniedException;
boolean supports(ConfigAttribute attribute);
boolean supports(Class clazz);
AccessDecisionManager
的 decide
方法传递了它做出授权决策所需的所有相关信息。特别是,传递安全的 Object
可以检查实际安全对象调用中包含的自变量。例如,假设安全对象是 MethodInvocation
。您可以查询 MethodInvocation
以获取任何 Customer
自变量,然后在 AccessDecisionManager
中实现某种安全逻辑,以确保主体被允许对该客户进行操作。如果拒绝了访问,预计实施会引发 AccessDeniedException
。
The decide
method of the AccessDecisionManager
is passed all the relevant information it needs to make an authorization decision.
In particular, passing the secure Object
lets those arguments contained in the actual secure object invocation be inspected.
For example, assume the secure object is a MethodInvocation
.
You can query the MethodInvocation
for any Customer
argument and then implement some sort of security logic in the AccessDecisionManager
to ensure the principal is permitted to operate on that customer.
Implementations are expected to throw an AccessDeniedException
if access is denied.
AbstractSecurityInterceptor
会在启动时调用 supports(ConfigAttribute)
方法,以确定 AccessDecisionManager
是否可以处理传递的 ConfigAttribute
。supports(Class)
方法由安全拦截器实现调用,以确保配置的 AccessDecisionManager
支持安全拦截器呈现的安全对象类型。
The supports(ConfigAttribute)
method is called by the AbstractSecurityInterceptor
at startup time to determine if the AccessDecisionManager
can process the passed ConfigAttribute
.
The supports(Class)
method is called by a security interceptor implementation to ensure the configured AccessDecisionManager
supports the type of secure object that the security interceptor presents.
Voting-Based AccessDecisionManager Implementations
虽然用户可以实现自己的 AccessDecisionManager
来控制授权的所有方面,但 Spring Security 包含几个基于投票的 AccessDecisionManager
实现。Voting Decision Manager 描述了相关类。
While users can implement their own AccessDecisionManager
to control all aspects of authorization, Spring Security includes several AccessDecisionManager
implementations that are based on voting.
Voting Decision Manager describes the relevant classes.
下图显示了 AccessDecisionManager
接口:
The following image shows the AccessDecisionManager
interface:
使用这种方法,系统会针对授权决策对一系列 AccessDecisionVoter
实现进行轮询。然后,AccessDecisionManager
根据其对投票的评估决定是否抛出 AccessDeniedException
。
By using this approach, a series of AccessDecisionVoter
implementations are polled on an authorization decision.
The AccessDecisionManager
then decides whether or not to throw an AccessDeniedException
based on its assessment of the votes.
AccessDecisionVoter
接口有三个方法:
The AccessDecisionVoter
interface has three methods:
int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attrs);
boolean supports(ConfigAttribute attribute);
boolean supports(Class clazz);
具体实施返回 int
,可能的值反映在名为 ACCESS_ABSTAIN
、ACCESS_DENIED
和 ACCESS_GRANTED
的 AccessDecisionVoter
静态字段中。如果对授权决策没有意见,投票实施将返回 ACCESS_ABSTAIN
。如果有意见,则必须返回 ACCESS_DENIED
或 ACCESS_GRANTED
。
Concrete implementations return an int
, with possible values being reflected in the AccessDecisionVoter
static fields named ACCESS_ABSTAIN
, ACCESS_DENIED
and ACCESS_GRANTED
.
A voting implementation returns ACCESS_ABSTAIN
if it has no opinion on an authorization decision.
If it does have an opinion, it must return either ACCESS_DENIED
or ACCESS_GRANTED
.
Spring Security 提供了三个具体 AccessDecisionManager
实现来统计选票。ConsensusBased
实现基于非弃权票的共识来授予或拒绝访问。提供的属性可控制在平票事件或所有票均弃权情况下的行为。AffirmativeBased
实现会在收到一个或多个 ACCESS_GRANTED
票时授予访问权限(换句话说,将忽略拒绝票,前提是有至少一个授予票)。与 ConsensusBased
实现类似,有一个参数控制所有投票者弃权时的行为。UnanimousBased
提供程序需要一致的 ACCESS_GRANTED
票才能授予访问权限,忽略弃权票。如果出现任何 ACCESS_DENIED
票,它会拒绝访问。和其他实现类似,有一个参数控制所有投票者弃权时的行为。
There are three concrete AccessDecisionManager
implementations provided with Spring Security to tally the votes.
The ConsensusBased
implementation grants or denies access based on the consensus of non-abstain votes.
Properties are provided to control behavior in the event of an equality of votes or if all votes are abstain.
The AffirmativeBased
implementation grants access if one or more ACCESS_GRANTED
votes were received (in other words, a deny vote will be ignored, provided there was at least one grant vote).
Like the ConsensusBased
implementation, there is a parameter that controls the behavior if all voters abstain.
The UnanimousBased
provider expects unanimous ACCESS_GRANTED
votes in order to grant access, ignoring abstains.
It denies access if there is any ACCESS_DENIED
vote.
Like the other implementations, there is a parameter that controls the behavior if all voters abstain.
您可以实现一个以不同方式统计选票的自定义 AccessDecisionManager
。例如,来自特定 AccessDecisionVoter
的选票可能会收到额外的加权,而来自特定选民的拒绝票可能具有否决权效果。
You can implement a custom AccessDecisionManager
that tallies votes differently.
For example, votes from a particular AccessDecisionVoter
might receive additional weighting, while a deny vote from a particular voter may have a veto effect.
RoleVoter
Spring Security 中最常用的 AccessDecisionVoter
是 RoleVoter
,它将配置属性视为角色名称,并投票以在用户已被分配该角色的情况下授予访问权限。
The most commonly used AccessDecisionVoter
provided with Spring Security is the RoleVoter
, which treats configuration attributes as role names and votes to grant access if the user has been assigned that role.
如果任何 ConfigAttribute
以 ROLE_
前缀开头,它都会投票。如果存在一个 GrantedAuthority
返回的 String
表示形式(来自 getAuthority()
方法) 与一个或多个以 ROLE_
前缀开头的 ConfigAttributes
完全相等,则它会投票以授予访问权限。如果没有与 ROLE_
开头的任何 ConfigAttribute
完全匹配,RoleVoter
会投票拒绝访问。如果没有 ConfigAttribute
以 ROLE_
开头,投票者会弃权。
It votes if any ConfigAttribute
begins with the ROLE_
prefix.
It votes to grant access if there is a GrantedAuthority
that returns a String
representation (from the getAuthority()
method) exactly equal to one or more ConfigAttributes
that start with the ROLE_
prefix.
If there is no exact match of any ConfigAttribute
starting with ROLE_
, RoleVoter
votes to deny access.
If no ConfigAttribute
begins with ROLE_
, the voter abstains.
AuthenticatedVoter
我们隐式看到的另一个投票者是 AuthenticatedVoter
,它可用于区分匿名用户、完全认证用户和记住我的认证用户。许多站点允许在记住我的认证下进行某些有限访问,但要求用户通过登录来确认他们的身份以获得完全访问权限。
Another voter which we have implicitly seen is the AuthenticatedVoter
, which can be used to differentiate between anonymous, fully-authenticated, and remember-me authenticated users.
Many sites allow certain limited access under remember-me authentication but require a user to confirm their identity by logging in for full access.
当我们使用 IS_AUTHENTICATED_ANONYMOUSLY
属性授予匿名访问时,此属性由 AuthenticatedVoter
处理。有关详细信息,请参见 {security-api-url}org/springframework/security/access/vote/AuthenticatedVoter.html[AuthenticatedVoter
].
When we have used the IS_AUTHENTICATED_ANONYMOUSLY
attribute to grant anonymous access, this attribute was being processed by the AuthenticatedVoter
.
For more information, see
{security-api-url}org/springframework/security/access/vote/AuthenticatedVoter.html[AuthenticatedVoter
].
Custom Voters
您还可以实现自定义 AccessDecisionVoter
并放入所需的任何访问控制逻辑。它可能是特定于应用程序(与业务逻辑相关),也可能是实现某些安全管理逻辑。例如,在 Spring 网站上,您可以找到一个 blog article ,描述了如何使用选民实时拒绝帐户已被暂停的用户的访问。
You can also implement a custom AccessDecisionVoter
and put just about any access-control logic you want in it.
It might be specific to your application (business-logic related) or it might implement some security administration logic.
For example, on the Spring web site, you can find a blog article that describes how to use a voter to deny access in real-time to users whose accounts have been suspended.
像 Spring Security 的许多其他部分一样,AfterInvocationManager
具有一个单一的具体实现 AfterInvocationProviderManager
,它轮询一个 AfterInvocationProvider`s.
Each `AfterInvocationProvider
列表。该列表允许修改返回对象或抛出一个 AccessDeniedException
。事实上,多个提供程序可以修改对象,因为前一个提供程序的结果会传递给列表中的下一个提供程序。
Like many other parts of Spring Security, AfterInvocationManager
has a single concrete implementation, AfterInvocationProviderManager
, which polls a list of AfterInvocationProvider`s.
Each `AfterInvocationProvider
is allowed to modify the return object or throw an AccessDeniedException
.
Indeed multiple providers can modify the object, as the result of the previous provider is passed to the next in the list.
请注意,如果你正在使用 AfterInvocationManager
,你仍需要允许 MethodSecurityInterceptor’s `AccessDecisionManager
执行操作的配置属性。如果你正在使用典型的 Spring Security 包含 AccessDecisionManager
实现,为特定的安全方法调用没有定义任何配置属性将导致每个 AccessDecisionVoter
弃权。同时,如果 AccessDecisionManager
属性 “allowIfAllAbstainDecisions” 是 false
,将会抛出一个 AccessDeniedException
。你可以通过 (i) 将 “allowIfAllAbstainDecisions” 设置为 true
(尽管通常不建议这样做)或 (ii) 仅确保至少有一个 AccessDecisionVoter
将投票以授予访问权限的配置属性来避免此潜在问题。后者的(推荐)方法通常通过 ROLE_USER
或 ROLE_AUTHENTICATED
配置属性来实现。
Please be aware that if you’re using AfterInvocationManager
, you will still need configuration attributes that allow the MethodSecurityInterceptor’s `AccessDecisionManager
to allow an operation.
If you’re using the typical Spring Security included AccessDecisionManager
implementations, having no configuration attributes defined for a particular secure method invocation will cause each AccessDecisionVoter
to abstain from voting.
In turn, if the AccessDecisionManager
property “allowIfAllAbstainDecisions” is false
, an AccessDeniedException
will be thrown.
You may avoid this potential issue by either (i) setting “allowIfAllAbstainDecisions” to true
(although this is generally not recommended) or (ii) simply ensure that there is at least one configuration attribute that an AccessDecisionVoter
will vote to grant access for.
This latter (recommended) approach is usually achieved through a ROLE_USER
or ROLE_AUTHENTICATED
configuration attribute.