一:前言
前面两篇介绍了入门实例和基本概念介绍,这篇文章来讲解下常用的配置。要想系统的理解,请移步教程四。
前两篇的地址为: {
1:http://blog.csdn.net/u012557538/article/details/49953017
}
二:常用配置
简单常用的就不写了。
1.<http auto-config="true">:使用auto-config="true"就等于在<http>中添加了五个标签,同时会启用“用户注销”,“基于表单认证”,“http basic认证”,“记忆登录信息”,“匿名认证”五个功能
2.<access-denied-handler error-page="/xxx.jsp"/> 配置没权限访问时跳转的页面
3.<logout logout-success-url="/login.jsp" logout-url="/j_spring_security_logout" invalidate-session="true" delete-cookies="JSESSIONID"/>配置注销操作跳转的页面及其附带操作,使用默认的过滤器时注销操作按钮的url应该为/j_spring_security_logout。<a href="j_spring_security_logout"'>logout</a>
4. <session-management invalid-session-url="/timeout.jsp" > <!-- invalid-session-url设置连接超时跳转页面 -->
<!-- error-if-maximum-exceeded="true":超出最大连接数以后,false-后登陆的将先登录的挤出系统,true: 后面的用户禁止登陆 -->
<concurrency-control max-sessions="2" error-if-maximum-exceeded="true" />
</session-management>
启动会话管理功能,需要在web.xml配置监听器:
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener>
5.异常信息的国际化支持
从spring-security-core-xx.jar中,你可以找到 org.springframework.security包下,包含了一些 messages.properties文件,其中中文的文字是messages_zh_CN.properties,通常所有你需要做的就是在你的application context中注册一个bean来引用这些信息。 下面是一个例子:
<!-- 定义国际化,支持中文异常信息 -->
<beans:bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename"
value="classpath*:/messages_zh_CN"/>
</beans:bean>
6.UserDetailsService的常用的四种实现方式
(1).xml硬编码
<user-service id="userDetailsService">
<user name=“aa” password=“123”authorities=”ROLE_USER,ROLE_ADMIN”/>
</user-service>
(2).采用properties文件
<user-service id="userDetailsService" properties="users.properties"/>
文件内容:
Zhou=123,ROLE_ADMIN[,ROLE_USER][,enabled|disabled]
(3).JdbcDaoImpl
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:hsql://localhost:9001"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
<bean id="userDetailsService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
默认情况下,JdbcDaoImpl会假设用户的权限都保存在authorities表中。还有一种选择是把权限分组,然后让用户加入这些用户组。
要启用用户组形式,就需要添加额外的配置,且数据库结构也需要变化,权限手册的数据库附录有讲。表结构请参考权限手册。
配置文件:
<security:authentication-manager>
<security:authentication-provider user-service-ref="userDetailsService"/>
</security:authentication-manager>
<bean id="userDetailsService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource" ref="dataSource"/>
<property name="enableGroups" value="true"/>
</bean>
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------7.<http use-expressions="true">启应用springEL表达式
比如:hasRole('admin')就是SpringEL表达式
<http use-expressions="true">
<intercept-url pattern="/admin*"
access="hasRole('admin') and hasIpAddress('192.168.1.0/24')"/>
...
</http>
8.来看看默认的认证管理器配置是怎么样的。这个不需要显示配置。配置文件中可以不配置。写出来只是方便理解。
<beanid="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
<property name="providers">
<list>
<ref local="daoAuthenticationProvider"/><!!--默认启用的是这个认证供应器-->
<!-- <ref local="anonymousAuthenticationProvider"/>
<ref local="ldapAuthenticationProvider"/>
-->
</list>
</property>
</bean>
<bean id="daoAuthenticationProvider"
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="inMemoryDaoImpl"/>
<property name="saltSource" ref bean="saltSource"/>
<property name="passwordEncoder" ref="passwordEncoder"/>
</bean>
9.标签库:主要作用是为了在视图层直接访问用户信息,再者就是对显示的内容进行权限管理 如果需要使用taglib,下载spring-security-taglibs-2.0.5.RELEASE.jar,JSP引入标签库。
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>
实例:从页面上显示当前登陆的用户名
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<div>username : <sec:authentication property="name"/></div>
10.扩展UserDetails
默认的UserDetails有6个方法
public interface UserDetails extends Serializable {
GrantedAuthority[] getAuthorities();//必须
String getPassword();//必须
String getUsername();//必须
boolean isAccountNonExpired();//账号是否过期
boolean isAccountNonLocked();//账号是否锁定(多次输错密码)
boolean isCredentialsNonExpired();//密码是否过期
boolean isEnabled();//是否被禁用
}
我们的任务就是实现这六个接口,同时扩展添加一个getEmail()方法,用以获得用户的邮箱地址。
public class UserInfo extends BaseUserDetails {
private static final long serialVersionUID = 1L;
private String email;
public UserInfo(String username, String password, boolean enabled, GrantedAuthority[] authorities)
throws IllegalArgumentException {
super(username, password, enabled, authorities);
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
}
这样在UserDetailsService中就可以添加邮箱到认证实体中了。
public class UserInfoService implements UserDetailsService {
private Map<String, UserInfo> userMap = null;
public UserInfoService() {
userMap = new HashMap<String, UserInfo>();
UserInfo userInfo = null;
userInfo = new UserInfo("user", "user", true,
Collections.singletonList(
new GrantedAuthorityImpl("ROLE_USER")));
userInfo.setEmail("user@family168.com");
userMap.put("user", userInfo);
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new GrantedAuthorityImpl("ROLE_ADMIN"));
authorities.add(new GrantedAuthorityImpl("ROLE_USER"));
userInfo = new UserInfo("admin", "admin", true, authorities);
userInfo.setEmail("admin@family168.com");
userMap.put("admin", userInfo);
}
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException, DataAccessException {
return userMap.get(username);
}
}
11.Remember-Me和持久化登录(persistent-login)
在配置文件中使用auto-config="true"就会自动启用rememberMe,之后,只要用户在登录时选中checkbox就可以实现下次无需登录直接进入系统的功能。
默认有效时间是两周,启用rememberMe之后的两周内,用户都可以直接跳过系统,直接进入系统。
<input id="_spring_security_remember_me" name="_spring_security_remember_me" type="checkbox" value="true"/>
借助数据库实现rememberme功能(持久化登录(persistent-login)):
原理:客户主机cookie中保存的不再用username,而是由系统自动生成的序列号,在验证时系统会将客户cookie中保存的序列号与数据库中保存的序列号进行比对,以确认客户请求的有效性,之后在比对成功后才会从数据库中取出对应的客户信息,继续进行认证和授权等工作
create table persistent_logins (
username varchar(64) not null,
series varchar(64) primary key,
token varchar(64) not null,
last_used timestamp not null
);
------------------------------------
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:res:/hsqldb/test"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
-----------------------------------------
<http auto-config='true'>
<intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" />
<intercept-url pattern="/**" access="ROLE_USER" />
<remember-me data-source-ref="dataSource"/>
</http>