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的实现。我们也可以自己实现。
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
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权限。