清单 1. 在 web.xml 中添加 Spring Security 的过滤器
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Spring Security 使用的是 Servlet 规范中标准的过滤器机制。对于特定的请求,Spring Security 的过滤器会检查该请求是否通过认证,以及当前用户是否有足够的权限来访问此资源。对于非法的请求,过滤器会跳转到指定页面让用户进行认证,或是返回出错信息。需要注意的是,代码清单 1 中虽然只定义了一个过滤器,Spring Security 实际上是使用多个过滤器形成的链条来工作的。
下一步是配置 Spring Security 来声明系统中的合法用户及其对应的权限。用户相关的信息是通过 org.springframework.security.core.userdetails.UserDetailsService 接口来加载的。该接口的唯一方法是 loadUserByUsername(String username),用来根据用户名加载相关的信息。这个方法的返回值是 org.springframework.security.core.userdetails.UserDetails 接口,其中包含了用户的信息,包括用户名、密码、权限、是否启用、是否被锁定、是否过期等。其中最重要的是用户权限,由 org.springframework.security.core.GrantedAuthority 接口来表示。虽然 Spring Security 内部的设计和实现比较复杂,但是一般情况下,开发人员只需要使用它默认提供的实现就可以满足绝大多数情况下的需求,而且只需要简单的配置声明即可。
在第一个示例应用中,使用的是数据库的方式来存储用户的信息。Spring Security 提供了 org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl 类来支持从数据库中加载用户信息。开发人员只需要使用与该类兼容的数据库表结构,就可以不需要任何改动,而直接使用该类。代码清单 2 中给出了相关的配置。
清单 2. 声明使用数据库来保存用户信息
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.apache.derby.jdbc.ClientDriver" />
<property name="url" value="jdbc:derby://localhost:1527/mycompany" />
<property name="username" value="app" />
<property name="password" value="admin" />
</bean>
<bean id="userDetailsService"
class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource" ref="dataSource" />
</bean>
<sec:authentication-manager>
<sec:authentication-provider user-service-ref="userDetailsService" />
</sec:authentication-manager>
如 代码清单 2 所示,首先定义了一个使用 Apache Derby 数据库的数据源,Spring Security 的 org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl 类使用该数据源来加载用户信息。最后需要配置认证管理器使用该 UserDetailsService。
接着就可以配置用户对不同资源的访问权限了。这里的资源指的是 URL 地址。配置的内容如 代码清单 3 所示。sec 是 Spring Security 的配置元素所在的名称空间的前缀。