由于ss2的demo配置太过简单,要想在项目中应用的话必须进行相应扩展,这里简单写一下简单的扩展方法。
xml头中引入security命名空间
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:security="http://www.springframework.org/schema/security"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
- http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd"
- default-lazy-init="true">
然后是启用ss2默认配置的一段代码
- <!--
- 2.0新增的命名空间,使得配置简化了很多
- auto-config 自动使用默认的配置
- access-denied-page 指定访问未授权页面时显示的页面
- -->
- <security:http auto-config="true" access-denied-page="/accessDenied.html">
- <security:anonymous granted-authority="BASIC" />
- </security:http>
这段代码作用是以ss2的默认配置方式加入1.0时需要手工配置的AuthenticationProcessingFilter等多个必须配置的filter,详细可参考1.0配置和2.0参考手册。
auto-config="true" 表示使用ss2自动配置
access-denied-page="/accessDenied.html"表示拒绝访问时显示的页面
<security:anonymous granted-authority="BASIC" />表示匿名权限的authority为BASIC
ss对权限的管理分为认证和授权两部分,先看认证
- <!--
- 负责认证处理的filter
- -->
- <bean id="authenticationProcessingFilter"
- class="org.springframework.security.ui.webapp.AuthenticationProcessingFilter">
- <!-- 此行说明此filter会覆盖ss2默认配置的filter,before 被覆盖filter的别名 -->
- <security:custom-filter before="AUTHENTICATION_PROCESSING_FILTER" />
- <!-- 认证管理器 -->
- <property name="authenticationManager" ref="authenticationManager" />
- <!-- 认证失败后跳转到的页面,/spring_security_login是ss2默认的登录入口 -->
- <property name="authenticationFailureUrl"
- value="/spring_security_login" />
- <!-- 认证成功后跳转到的页面 -->
- <property name="defaultTargetUrl" value="/index.html" />
- </bean>
这是负责认证处理的filter,中间custom-filter一行意思是将filter放在默认配置中别名为AUTHENTICATION_PROCESSING_FILTER的filter前边,即负责认证的filter(别名列表参照参考手册)。
按官方的说法,如果需要用自定义的filter覆盖默认filter,则应该将security:http标签的auto-config属性改为false,这样的话就需要增加很多手动配置项。我试了下,不改false也可以,只是运行期间会出现一个warn信息“Possible error: Filters at position 2 and 3 are both instances of xxxx”,意思是filter串中有两个相同类型的filter。
另:在2.0.2中可以使用position代替before,真正的覆盖默认filter。但是有个bug,如果使用默认登录入口的话,还是会调用默认filter,必须连登录入口一并改掉。
其引用的authenticationManager
- <!--
- 认证管理器
- 根据用户名和密码,使用多个provider进行认证
- 认证成功会生成一个Authentication,否则抛出AuthenticationException
- -->
- <bean id="authenticationManager"
- class="org.springframework.security.providers.ProviderManager">
- <property name="providers">
- <list>
- <ref local="daoAuthenticationProvider" />
- </list>
- </property>
- </bean>
认证管理器通过多个provider实现基于用户名和密码的认证,多个provider中只要有一个认证成功,即成功。
这里只使用了一个daoPorvider
- <!--
- 认证的provider
- userDetailsService 根据用户名获取用户信息
- userCache ehcache缓存user信息。
- -->
- <bean id="daoAuthenticationProvider"
- class="org.springframework.security.providers.dao.DaoAuthenticationProvider">
- <property name="userDetailsService" ref="userDetailsService" />
- <property name="userCache" ref="userCache" />
- </bean>
userDetailsService:根据登录的用户名获取一个UserDetails,即代表一个用户的实体对象。
- <!-- 通过dao查询用户信息 -->
- <bean id="userDetailsService"
- class="org.catspaw.ss2test1.security.UserDetailsSerivceImpl">
- <property name="userDao" ref="userDao" />
- </bean>
UserDetailsSerivceImpl代码
- package org.catspaw.ss2test1.security;
- import org.catspaw.ss2test1.dao.UserDao;
- import org.springframework.dao.DataAccessException;
- import org.springframework.security.userdetails.UserDetails;
- import org.springframework.security.userdetails.UserDetailsService;
- import org.springframework.security.userdetails.UsernameNotFoundException;
- /**
- * 获取UserDetails
- * 使用UserDao查询User
- *
- * @author 孙宁振
- *
- */
- public class UserDetailsSerivceImpl implements UserDetailsService {
- private UserDao userDao;
- public UserDao getUserDao() {
- return userDao;
- }
- public void setUserDao(UserDao userDao) {