Spring Boot整合Spring Security简记-授
new無语 转载请注明原创出处,谢谢!
Spring Security中的高级授权功能是其受欢迎最引人注目的原因之一。无论您如何选择进行身份验证 (无论是使用Spring Security提供的机制和提供程序,还是与容器或其他非Spring Security身份验证机构集成),你都会发现授权服务可以在您的应用程序中一直以简单的方式使用。
在本部分中,我们将探讨
AbstractSecurityInterceptor
第一部分介绍的不同实现。然后我们继续探讨如何通过使用域访问控制列表来微调授权。
GrantedAuthority
像我们之前看到的,所有Authentication
都存储一个GrantedAuthority
列表。这个代表当前的授权。
GrantedAuthority
对象存入Authentication
中,由AuthenticationManager
调用AccessDecisionManager
进行权限验证。
GrantedAuthority
接口只有一个方法
String getAuthority();
这个方法供AccessDecisionManager
获取一个准确的String
表示GrantedAuthority
。通过返回一个String
,GrantedAuthority
可以被大多数AccessDecisionManager
轻松的识别。
但是,如果GrantedAuthority
不能用GrantedAuthority
表示,则GrantedAuthority
被认为是需要复杂验证的权限信息。并且getAuthority()
必须返回null
。
"复杂"的GrantedAuthority
适用于不同账号的操作和权限的阈值等场景。这种复合体权限的GrantedAuthority
用一个String
很难表示。所以getAuthority()
返回null
。这向AccessDecisionManager
表示,需要特殊支持的处理。下面会讲到。
AccessDecisionManager
AccessDecisionManager
由AbstractSecurityInterceptor
调用,并负责最终访问控制决策。
该AccessDecisionManager
接口包含三个方法:
void decide(Authentication authentication, Object secureObject,
Collection<ConfigAttribute> attrs) throws AccessDeniedException;
boolean supports(ConfigAttribute attribute);
boolean supports(Class clazz);
AccessDecisionManager
的decide
方法传递所需的所有相关信息,以做出授权决策。secureObject
是传递"目标资源对象"使这些参数中包含实际的"目标资源对象"调用进行检查。如果访问被拒绝,则抛出AccessDeniedException
。
configAttributes
验证配置信息。
supports(ConfigAttribute)
判断AccessDecisionManager
是否支持传递的ConfigAttribute
。
supports(Class)
判断是否支持"目标资源对象"的类型。
基于投票的AccessDecisionManager实现
Spring Security包含了几个AccessDecisionManager
的实现。我们也可以自己实现。
使用这种方法,AccessDecisionVoter
集合进行轮询,AccessDecisionManager
决定是否抛出AccessDeniedException
。
AccessDecisionVoter
接口有三个方法
int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attrs);
boolean supports(ConfigAttribute attribute);
boolean supports(Class clazz);
vote
方法返回int,返回值为AccessDecisionVoter
的ACCESS_ABSTAIN
(为0,弃权),ACCESS_DENIED
(为-1,反对)和ACCESS_GRANTED
(为1,通过)。
AfterInvocationManager
AccessDecisionManager
是被AbstractSecurityInterceptor
在调用"目标资源对象"之前,一些应用程序还需要修改"目标资源对象"的返回对象信息,这里Spring Security就提供了一个AfterInvocationManager
进行实现。
AfterInvocationManager
有一个具体的实现AfterInvocationProviderManager
,它轮询AfterInvocationProvider
的列表。每个AfterInvocationProvider
返回修改后对象或抛出一个AccessDeniedException
。事实上,多个提供者可以修改该对象,因为前一个提供者的结果被传递给列表中的下一个AfterInvocationProvider
。
分层角色
这是一个常见的需求,在应用中,特定的角色需要有其他角色的权限,例如:"admin"角色要有"user"的权限,也就是管理员要有普通用户的权限。要做到这一点,就要给管理员角色再分配一个普通用户的角色,或者要修改管理员角色的访问权限。这可能会变得很复杂。
RoleVoter
的扩展,RoleHierarchyVoter
,配置了RoleHierarchy
,可以实现分层角色验证。
@Bean
public RoleHierarchyVoter roleHierarchyVoter(){
RoleHierarchyVoter voter = new RoleHierarchyVoter(roleHierarchy());
return voter;
}
@Bean
public RoleHierarchy roleHierarchy(){
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_DBA");
return roleHierarchy;
}
之后Postman请求http://localhost:8080/db/123
,就可以看到返回404,就实现了admin角色拥有dba权限。