第八章:核心架构
authentication和authority,认证和授权
SecurityContext, SecurityContextHolder, Authentication,SecurityContextRepository
- securityContext正如其名,表示“环境”,存储安全信息的环境。其实里面只存了Authentication
- securityContextHolder存储了securityContext,官方给了3种存储方式,threadlocal,inheritthreadlocal,global
- Authentication对象用于“Authentication” -- 认证。很直白的名字。关键的属性是isAuthenticated,如果验证成功,这个值是true。另外验证成功后,getPricipal方法,返回的对象一般是Userdetails类型。里面有用户的关键信息和角色信息。令人困惑的是还有这2个方法:getCredential和getDetails(看方法名很容易跟getPricipal弄混了),前者是用于验证的数据(一般是用户名和密码, UserDetails里也有用户名),后者是补充信息,可有可无。
- SecurityContextHolder如果是threadlocal的,但用户的已登录状态一般都需要session级的,于是还需要SecurityContextRepository。这个配合SecurityContextPesistenceFilter一起使用,这个filter负责在拦截器链结束前,把securityContextHolder中的securityContext存入session。在拦截器链开始前,把session中的securiytcontext放入当前线程的SecurityContextHolder。
UserDetails和UserDetailsService
Authentication验证成功后,方法getPricipal放回的对象一般是UserDetails类型的对象。该对象有用户名,密钥和角色等关键信息。负责构造userDetails对象的是UserDetailsService接口。简而言之流程就是验证Authencation对象中的credential,验证成功了,用UserDtailsService构造UserDetails对象,并存入Authentication中。
验证失败处理ExceptionTranslationFilter和ExceptionEntryPoint
如果验证失败了,拦截器链会走到ExceptionTranslationFilter(这个filter不仅处理验证失败,还能处理权限失败),失败后如何跳转,它会调用ExceptionEntrypoint的方法
AuthenticationManager, ProviderManager and AuthenticationProvider
负责认证Authentication对象的是AuthticationManager。它又调用了ProviderManager来验证。ProviderManager和AuthenticationProvider使用了组合模式,也就是一个Providermanager中包含多个AuthenticationProvider。不同的AuthenticationProvider支持不同的Authentication对象。如果有一个AuthenticationProvider验证成功,则该Authentication验证成功。
授权filterSecurityInterceptor/AccessDecisionManager
FilterSecurityInterceptor是AbstractSecurityInterceptor的子类,表示对请求的授权。另外还有方法授权的子类MethodSecurityInterceptor,表示执行某个方法的授权