第 34 章 权限管理的基本概念

34.1. 认证与验证

Spring Security作为权限管理框架,其内部机制可分为两大部分,其一是认证授权authentication,其二是权限校验auhorization。

认证授权authentication是指,根据用户提供的身份凭证,生成权限实体,并为之授予相应的权限。

权限校验authorization是指,用户请求访问被保护资源时,将被保护资源所需的权限和用户权限实体所拥护的权限二者进行比对,如果校验通过则用户可以访问被保护资源,否则拒绝访问。

我们之前讲过的form-login,http-basic, digest都属于认证授权authentication部分的概念,用户可以通过这些机制登录到系统中,系统会为用户生成权限主体,并授予相应的权限。

与之相对的,FilterSecurityInterceptor,Method保护,taglib,@Secured都属于权限校验authorizationn,无论是对URL的请求,对方法的调用,页面信息的显示,都要求用户拥有相应的权限才能访问,否则请求即被拒绝。

34.2. SecurityContext安全上下文

为使所有的组件都可以通过同一方式访问当前的权限实体,Spring Security特别提供了SecurityContext作为安全上下文,可以直接通过SecurityContextHolder获得当前线程中的SecurityContext。

SecurityContext securityContext = SecurityContextHolder.getContext();
        

默认情况下,SecurityContext的实现基于ThreadLocal,系统会在每次用户请求时将SecurityContext与当前Thread进行绑定,这在web系统中是很常用的使用方式,服务器维护的线程池允许多个用户同时并发访问系统,而ThreadLocal可以保证隔离不同Thread之间的信息。

当时对于单机应用来说,因为只有一个人使用,并不存在并发的情况,所以完全可以让所有Thread都共享同一个SecurityContext,因此Spring Security为我们提供了不同的策略模式,我们可以通过设置系统变量的方式选择希望使用的策略类。

java -Dspring.security.strategy=MODE_GLOBAL com.family168.springsecuritybook.Main
        

也可以调用SecurityContextHolder的setStrategyName()方法来修改系统使用的策略。

SecurityContextHolder.setStrategyName("MODE_GLOBAL");
        

34.3. Authentication验证对象

SecurityContext中保存着实现了Authentication接口的对象,如果用户尚未通过认证,那么SecurityContext.getAuthenticaiton()方法就会返回null。

可以使用Authentication接口中定义的几个方法,获得当前权限实体的信息。

public interface Authentication extends Principal, Serializable {

    GrantedAuthority[] getAuthorities();1

    Object getCredentials();2

    Object getDetails();3

    Object getPrincipal();4

    boolean isAuthenticated();

    void setAuthenticated(boolean isAuthenticated)
        throws IllegalArgumentException;
}
        

默认情况下,会在某一个进行认证的过滤器中生成一个UsernamePasswordAuthenticationToken实例,并将此实例放到SecurityContext中。

1

获得权限主体拥有的权限。

权限实体拥有的权限,GrantedAuthority接口内只有一个方法getAuthority(),它的返回值是一个字符串,这个字符串用来标识系统中的某一权限。用户认证后权限实体将拥有一个保存了一系列GrantedAuthority对象的数组,之后可以用于进行验证用户是否可以访问系统中被保护资源。

2

获得权限主体的凭证,此凭证应该可以唯一标示权限主体。

默认情况下,凭证是用户的登录密码。

3

获得验证请求有关的附加信息。

默认情况下,附加信息是WebAuthenticationDetails的一个实例,其中保存了客户端ip和sessionid。

4

获得权限主体。

默认情况下,权限主体是一个实现了UserDetails接口的对象。