Spring Security(三十):9.5 Access-Control (Authorization) in Spring Security

Posted 帅S俊

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Security(三十):9.5 Access-Control (Authorization) in Spring Security相关的知识,希望对你有一定的参考价值。

The main interface responsible for making access-control decisions in Spring Security is the AccessDecisionManager. It has a decide method which takes an Authentication object representing the principal requesting access, a "secure object" (see below) and a list of security metadata attributes which apply for the object (such as a list of roles which are required for access to be granted).

负责在Spring Security中进行访问控制决策的主界面是AccessDecisionManager。它有一个decision方法,它接受一个表示请求访问的主体的Authentication对象,一个“安全对象”(见下文)和一个适用于该对象的安全元数据属性列表(例如访问所需的角色列表)被授予)。

9.5.1 Security and AOP Advice

If you’re familiar with AOP, you’d be aware there are different types of advice available: before, after, throws and around. An around advice is very useful, because an advisor can elect whether or not to proceed with a method invocation, whether or not to modify the response, and whether or not to throw an exception. Spring Security provides an around advice for method invocations as well as web requests. We achieve an around advice for method invocations using Spring’s standard AOP support and we achieve an around advice for web requests using a standard Filter.

如果您熟悉AOP,您会发现有不同类型的建议可用:之前,之后,投掷和周围。 around建议非常有用,因为顾问可以选择是否继续进行方法调用,是否修改响应,以及是否抛出异常。 Spring Security为方法调用和Web请求提供了周围的建议。我们使用Spring的标准AOP支持实现方法调用的周围建议,并使用标准Filter实现Web请求的周围建议。
 
For those not familiar with AOP, the key point to understand is that Spring Security can help you protect method invocations as well as web requests. Most people are interested in securing method invocations on their services layer. This is because the services layer is where most business logic resides in current-generation Java EE applications. If you just need to secure method invocations in the services layer, Spring’s standard AOP will be adequate. If you need to secure domain objects directly, you will likely find that AspectJ is worth considering.
对于那些不熟悉AOP的人来说,要理解的关键是Spring Security可以帮助您保护方法调用以及Web请求。大多数人都对在服务层上保护方法调用感兴趣。这是因为服务层是大多数业务逻辑驻留在当前一代Java EE应用程序中的地方。如果您只需要在服务层中保护方法调用,那么Spring的标准AOP就足够了。如果您需要直接保护域对象,您可能会发现AspectJ值得考虑。
 
You can elect to perform method authorization using AspectJ or Spring AOP, or you can elect to perform web request authorization using filters. You can use zero, one, two or three of these approaches together. The mainstream usage pattern is to perform some web request authorization, coupled with some Spring AOP method invocation authorization on the services layer.
您可以选择使用AspectJ或Spring AOP执行方法授权,也可以选择使用过滤器执行Web请求授权。您可以将这些方法中的零个,一个,两个或三个一起使用。主流使用模式是执行一些Web请求授权,再加上服务层上的一些Spring AOP方法调用授权。

9.5.2 Secure Objects and the AbstractSecurityInterceptor

So what is a "secure object" anyway? Spring Security uses the term to refer to any object that can have security (such as an authorization decision) applied to it. The most common examples are method invocations and web requests.

那么什么是“安全对象”呢? Spring Security使用该术语来引用可以对其应用安全性(例如授权决策)的任何对象。最常见的示例是方法调用和Web请求。
 

Each supported secure object type has its own interceptor class, which is a subclass of AbstractSecurityInterceptor. Importantly, by the time the AbstractSecurityInterceptor is called, the SecurityContextHolder will contain a valid Authentication if the principal has been authenticated.

每个受支持的安全对象类型都有自己的拦截器类,它是AbstractSecurityInterceptor的子类。重要的是,在调用AbstractSecurityInterceptor时,如果主体已经过身份验证,则SecurityContextHolder将包含有效的身份验证。

AbstractSecurityInterceptor provides a consistent workflow for handling secure object requests, typically:

AbstractSecurityInterceptor为处理安全对象请求提供了一致的工作流,通常:
  1. Look up the "configuration attributes" associated with the present request 
    查找与当前请求关联的“配置属性”
  2. Submitting the secure object, current Authentication and configuration attributes to the AccessDecisionManager for an authorization decision 
    将安全对象,当前身份验证和配置属性提交给AccessDecisionManager以进行授权决策
  3. Optionally change the Authentication under which the invocation takes place 
    (可选)更改进行调用的身份验证
  4. Allow the secure object invocation to proceed (assuming access was granted)  
    允许安全对象调用继续(假设已授予访问权限)
  5. Call the AfterInvocationManager if configured, once the invocation has returned. If the invocation raised an exception, the AfterInvocationManager will not be invoked. 
    调用返回后,调用AfterInvocationManager(如果已配置)。如果调用引发异常,则不会调用AfterInvocationManager。

What are Configuration Attributes?

A "configuration attribute" can be thought of as a String that has special meaning to the classes used by AbstractSecurityInterceptor. They are represented by the interface ConfigAttribute within the framework. They may be simple role names or have more complex meaning, depending on the how sophisticated the AccessDecisionManager implementation is. The AbstractSecurityInterceptor is configured with a SecurityMetadataSource which it uses to look up the attributes for a secure object. Usually this configuration will be hidden from the user.

“配置属性”可以被认为是对AbstractSecurityInterceptor使用的类具有特殊含义的String。它们由框架内的接口ConfigAttribute表示。它们可能是简单的角色名称,也可能具有更复杂的含义,具体取决于AccessDecisionManager实现的复杂程度。 AbstractSecurityInterceptor配置了SecurityMetadataSource,用于查找安全对象的属性。通常,此配置将对用户隐藏。
 
 Configuration attributes will be entered as annotations on secured methods or as access attributes on secured URLs. For example, when we saw something like <intercept-url pattern=\'/secure/**\' access=\'ROLE_A,ROLE_B\'/> in the namespace introduction, this is saying that the configuration attributes ROLE_A and ROLE_B apply to web requests matching the given pattern. In practice, with the default AccessDecisionManager configuration, this means that anyone who has a GrantedAuthority matching either of these two attributes will be allowed access. Strictly speaking though, they are just attributes and the interpretation is dependent on the AccessDecisionManager implementation. The use of the prefix ROLE_ is a marker to indicate that these attributes are roles and should be consumed by Spring Security’s RoleVoter. This is only relevant when a voter-based AccessDecisionManager is in use. We’ll see how the AccessDecisionManager is implemented in the authorization chapter.
配置属性将作为安全方法的注释输入,或作为安全URL的访问属性输入。例如,当我们在命名空间简介中看到类似<intercept-url pattern =\'/ secure / **\'access =\'ROLE_A,ROLE_B\'/>的内容时,这就是说配置属性ROLE_A和ROLE_B适用于Web请求匹配给定的模式。实际上,使用默认的AccessDecisionManager配置,这意味着任何具有与这两个属性中的任何一个匹配的GrantedAuthority的人都将被允许访问。严格来说,它们只是属性,解释依赖于AccessDecisionManager实现。前缀ROLE_的使用是一个标记,表示这些属性是角色,应该由Spring Security的RoleVoter使用。这仅在使用基于选民的AccessDecisionManager时才有意义。我们将在授权章节中看到AccessDecisionManager的实现方式。

RunAsManager

Assuming AccessDecisionManager decides to allow the request, the AbstractSecurityInterceptor will normally just proceed with the request. Having said that, on rare occasions users may want to replace the Authentication inside the SecurityContext with a different Authentication, which is handled by the AccessDecisionManager calling a RunAsManager. This might be useful in reasonably unusual situations, such as if a services layer method needs to call a remote system and present a different identity. Because Spring Security automatically propagates security identity from one server to another (assuming you’re using a properly-configured RMI or HttpInvoker remoting protocol client), this may be useful.

假设AccessDecisionManager决定允许请求,AbstractSecurityInterceptor通常只会继续请求。话虽如此,在极少数情况下,用户可能希望使用不同的身份验证替换SecurityContext中的身份验证,该身份验证由AccessDecisionManager调用RunAsManager来处理。这在合理的异常情况下可能很有用,例如服务层方法需要调用远程系统并呈现不同的身份。因为Spring Security会自动将安全标识从一个服务器传播到另一个服务器(假设您使用的是正确配置的RMI或HttpInvoker远程协议客户端),这可能很有用。

AfterInvocationManager

Following the secure object invocation proceeding and then returning - which may mean a method invocation completing or a filter chain proceeding - the AbstractSecurityInterceptor gets one final chance to handle the invocation. At this stage the AbstractSecurityInterceptor is interested in possibly modifying the return object. We might want this to happen because an authorization decision couldn’t be made "on the way in" to a secure object invocation. Being highly pluggable, AbstractSecurityInterceptor will pass control to an AfterInvocationManager to actually modify the object if needed. This class can even entirely replace the object, or throw an exception, or not change it in any way as it chooses. The after-invocation checks will only be executed if the invocation is successful. If an exception occurs, the additional checks will be skipped.

在安全对象调用继续进行然后返回 - 这可能意味着方法调用完成或过滤器链继续进行 - AbstractSecurityInterceptor获得最后一次机会来处理调用。在此阶段,AbstractSecurityInterceptor可能会修改返回对象。我们可能希望这种情况发生,因为无法在安全对象调用的“途中”进行授权决策。作为高度可插拔的,AbstractSecurityInterceptor会将控制权传递给AfterInvocationManager,以便在需要时实际修改对象。这个类甚至可以完全替换对象,或抛出异常,或者不以任何方式更改它。只有在调用成功时才会执行调用后检查。如果发生异常,将跳过其他检查。
 
AbstractSecurityInterceptor and its related objects are shown in Figure 9.1, “Security interceptors and the "secure object" model”
AbstractSecurityInterceptor及其相关对象如图9.1所示,“安全拦截器和”安全对象“模型”
 
Figure 9.1. Security interceptors and the "secure object" model
图9.1。安全拦截器和“安全对象”模型
 

 

Extending the Secure Object Model

Only developers contemplating an entirely new way of intercepting and authorizing requests would need to use secure objects directly. For example, it would be possible to build a new secure object to secure calls to a messaging system. Anything that requires security and also provides a way of intercepting a call (like the AOP around advice semantics) is capable of being made into a secure object. Having said that, most Spring applications will simply use the three currently supported secure object types (AOP Alliance MethodInvocation, AspectJ JoinPoint and web request FilterInvocation) with complete transparency.

只有开发人员考虑采用全新的拦截和授权请求方式才需要直接使用安全对象。例如,可以构建新的安全对象以保护对消息传递系统的调用。任何需要安全性并且还提供拦截调用的方法(如围绕建议语义的AOP)都能够成为安全对象。话虽如此,大多数Spring应用程序将只使用三种当前支持的安全对象类型(AOP Alliance MethodInvocation,AspectJ JoinPoint和Web请求FilterInvocation),并具有完全透明性。
 

以上是关于Spring Security(三十):9.5 Access-Control (Authorization) in Spring Security的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security(三十四):10.4 Jackson Support

Spring Security(三十一):9.6 Localization(本地化)

Spring-Security:优化获取当前经过身份验证的用户...

spring5.0.7.RELEASE配置jackson2.9.5

Spring-Security

关于Spring Security的笔记