spring security 没有什么好的入门书籍, 只好翻阅了reference文档,里面有几个经典的图形, 可以帮助我们快速的了解spring security 概念。
FilterSecurityInterceptor作为起点,它用来实现对HTTP资源的 安全访问,顾名思义,它是一个拦截器,截获请求,并做好安全控制。 FilterSecurityInterceptor用到一个AuthenticationManager 和一个 AccessDecisionManager,AuthenticationManager 实现的是认证,给予身份的证明, 而AccessDecisionManager则是访问控制, 在验明正身之后,决定某个人是否有访问的权限。而securityMetaDataSource则是用来对每个HTTP请求定义访问属性, 例如哪些角色可以访问该url。而MethodSecurityInterceptor则是用来控制方法级别上的安全。基本上一个访问控制的框架就搭建起来了。
图1 “Security interceptors and the “secure object” model”. security拦截器和安全对象模型
更进一步,AuthenticationManager 可以由不同的provider来实现, 例如DaoAuthenticationProvider,LDAPAuthenticationProvider等等。provider包含三个属性, <bean
<property name="passwordEncoder" >
<ref bean="passwordEncoder" />
</property>
<property name="saltSource" >
<ref bean="saltSource" />
</property>
<property name="userDetailsService">
<ref bean="userDetailsService" />
</property>
其中userDetailsService是最基本的用户信息,它的接口loadUserByUsername及其简单,通过用户名获取用户信息。
AccessDecisionManager用投票方式决定时候可以访问某个资源。
最后看一段spring代码,AbstractSecurityInterceptor
protected InterceptorStatusToken beforeInvocation(Object object) 整个流程就很清楚了。
Collection<ConfigAttribute> attributes = this.obtainSecurityMetadataSource().getAttributes(object); //object是要访问的对象, web应用里通常是http request
if (SecurityContextHolder.getContext().getAuthentication() == null) { //从securitycontextholder判断是否有aunthenticaion对象
credentialsNotFound(messages.getMessage("AbstractSecurityInterceptor.authenticationNotFound",
"An Authentication object was not found in the SecurityContext"), object, attributes);
}
Authentication authenticated = authenticateIfRequired(); //获取aunthenticaion对象
// Attempt authorization
try {
this.accessDecisionManager.decide(authenticated, object, attributes); //决定是否可以访问某个资源,authenticated用户信息,object访问对象,attributes对象的访问属性,从SecurityMetadataSource来
}
catch (AccessDeniedException accessDeniedException) {
publishEvent(new AuthorizationFailureEvent(object, attributes, authenticated, accessDeniedException));
throw accessDeniedException;
}