1.配置web.xml
<filter>
<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>
2.配置applicationContext-security.xml
<!-- 皮肤css及css图片 -->
<http pattern="/style/**" security="none"/>
<!-- 其他图片文件夹 -->
<http pattern="/**/*.png" security="none"/>
<http pattern="/**/*.jpg" security="none"/>
<http pattern="/**/*.gif" security="none"/>
<http pattern="/**/*.htm*" security="none"/>
<!-- 其他css -->
<http pattern="/**/*.css" security="none"/>
<!-- 所有的JS -->
<http pattern="/**/*.js" security="none"/>
<!-- 所有的flash -->
<http pattern="/**/*.swf" security="none"/>
<!--
配置所有需要进行权限控制的页面
-->
<http use-expressions="true" auto-config="false"
access-denied-page="/warning/accessDenied.html">
<form-login login-page="/login.jsp"
authentication-failure-url="/login.jsp?error=true"
always-use-default-target="true"
default-target-url="/loginAction_index.do"/>
<logout invalidate-session="true" logout-success-url="/logoutOk.html" logout-url="/j_spring_security_logout"/>
<!-- 限制该用户在线链接(httpSession)数量以及超过之后的处理 ,超时处理 , session攻击处理 -->
<session-management invalid-session-url="/warning/sessionTimeOut.html"
session-fixation-protection="migrateSession">
<concurrency-control max-sessions="3"
error-if-maximum-exceeded="false" expired-url="/warning/accessExprired.html"/>
<!--
error-if-maximum-exceeded为true时报异常且不让登录,为false则将最先登录的session过期
-->
</session-management>
<custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="filterSecurityInterceptor"/>
</http>
<!--
核心2 :
重新定义的FilterSecurityInterceptor,使用"databaseFilterInvocationDefinitionSource"提供的url-授权关系定义
-->
<!-- 用于标签AuthorizeTag,默认的标签只能经过intercept-url配置的验证,我们扩展为支持动态数据库的
配合修正后的AbstractAuthorizeTag.java,必须有ID -->
<b:bean id="webInvocationPrivilegeEvaluatorForTag" class="org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator">
<b:constructor-arg type="org.springframework.security.access.intercept.AbstractSecurityInterceptor" ref="filterSecurityInterceptor"/>
</b:bean>
<b:bean id="filterSecurityInterceptor"
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<!--
认证管理器
-->
<b:property name="authenticationManager" ref="authenticationManager"/>
<!--
决策管理器
-->
<b:property name="accessDecisionManager" ref="accessDecisionManager"/>
<!--
授权处理器
-->
<b:property name="securityMetadataSource" ref="databaseFilterInvocationDefinitionSource"/>
</b:bean>
<!-- 核心1 : 认证配置 ,设定用户权限并缓存-->
<authentication-manager alias="authenticationManager">
<authentication-provider ref="daoAuthenticationProvider"/>
</authentication-manager>
<b:bean id="daoAuthenticationProvider"
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<!-- 缓存用户信息 -->
<b:property name="userCache" ref="userCache"/>
<b:property name="passwordEncoder">
<!-- 数据库的md5密码必须是小写字母,默认32位 -->
<b:bean
class="org.springframework.security.authentication.encoding.Md5PasswordEncoder"/>
</b:property>
<b:property name="userDetailsService" ref="userDetailsService"/>
</b:bean>
<!-- 核心1的实现类(实现UserDetailService接口) -->
<b:bean id="userDetailsService" class="cn.cbsw.security.UserDetailServiceImpl">
<b:property name="userDao" ref="secUserDao"/>
</b:bean>
<!-- 完全自写的dao 用于获取需要的数据 -->
<b:bean id="secUserDao" class="cn.cbsw.security.SecUserDao">
<b:property name="sessionFactory">
<b:ref bean="sessionFactory"/>
</b:property>
<b:property name="userQuery"
value="select user_name,user_password,user_del from sys_user where user_name=?" />
<b:property name="userRoleQuery"
value="select u.user_name,p.group_id from sys_user u,sys_user_group p where u.user_id=p.user_id and u.user_name=?" />
<b:property name="resourceQueryout"
value="select m.menu_link_path||'*',gm.group_id from (select m.menu_link_path,m.menu_id from sys_menu m where m.menu_iscd=0 and m.menu_link_path is not null) m left join sys_group_menu gm on m.menu_id=gm.menu_id"/>
<!--
left join..on.. 可以查找出没有授权给任何用户组的功能URL和用户组null对应关系( 有个好处:
这时没有授权给任何用户组,则任何用户组都不能访问,如果没有加载这个未授权的URL,
则根据比对保护资源原则,未在被保护列表的请求都被接受),建议只加载分配了用户组的URL [说明:security加载资源-角色
如果角色为null或者等效""的值是不会载入likehashmap的,但我们做了处理会保存.url后面的*必须保留]
-->
</b:bean>
<b:bean id="accessDecisionManager"
class="org.springframework.security.access.vote.AffirmativeBased">
<b:constructor-arg name="decisionVoters">
<b:list>
<b:bean class="org.springframework.security.access.vote.RoleVoter">
<!-- 将授权名称的默认前缀由ROLE_改为空. -->
<b:property name="rolePrefix" value=""/>
</b:bean>
<b:bean
class="org.springframework.security.access.vote.AuthenticatedVoter"/>
</b:list>
</b:constructor-arg>
</b:bean>
<b:bean id="databaseFilterInvocationDefinitionSource"
class="org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource">
<!-- 匹配url的matcher antUrlPathMatcher是定义的url格式,随后定义
<b:constructor-arg type="org.springframework.security.web.util.UrlMatcher"
ref="myUrlPathMatcher"/>-->
<!-- url对应authority的map -->
<b:constructor-arg type="java.util.LinkedHashMap"
ref="requestMap"/>
</b:bean>
<!-- 修改为自己定义的匹配模式
<b:bean id="myUrlPathMatcher"
class="org.springframework.security.web.util.AntUrlPathMatcher"/> -->
<!-- 自定义的获取保护资源-授权关系的实现类(实现FactoryBean接口) -->
<b:bean id="requestMap" class="cn.cbsw.security.RequestMapFactoryBean"
init-method="init">
<b:property name="userDao" ref="secUserDao"/>
</b:bean>
<!--
缓存配置-->
<b:bean id="userCache"
class="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache">
<b:property name="cache" ref="userEhCache"/>
</b:bean>
<b:bean id="userEhCache"
class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<b:property name="cacheManager" ref="cacheManager"/>
<b:property name="cacheName" value="myUserCache"/>
</b:bean>
<b:bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<b:property name="configLocation" value="classpath:ehcache.xml"/>
<b:property name="shared" value="true"/><!-- 很重要,否则 报存在同名cachemanager(hibernate)-->
</b:bean>
<!-- 自动信息管理器 -->
<b:bean id="loggerListener"
class="org.springframework.security.authentication.event.LoggerListener"/>
<!-- 国际化资源信息 -->
<b:bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<!-- <b:property name="basename" value="classpath:org/springframework/security/messages_zh_CN"/> -->
<b:property name="basename" value="classpath:messages_zh_CN"/>
</b:bean>