spring3.0 MVC笔记4-集成spring security3.1
1、下载spring security,集成下列jar包:
--spring-security-config-3.1.3.RELEASE.jar
--spring-security-core-3.1.3.RELEASE.jar
--spring-security-taglibs-3.1.3.RELEASE.jar
--spring-security-web-3.1.3.RELEASE.jar
2、配置web.xml中的filter
一定要写上filer-mapping,因为忘写filter-mapping程序根本不触发spring security的任何东西,也不报错,就是不干security的活。
3、修改log4j.properties增加下面行:
log4j.logger.org.springframework.security=DEBUG
以观察security的执行情况
4、在src下创建security.xml:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
把它加到context路径中
启动tomcat,报错:
No bean named 'org.springframework.security.authenticationManager' is defined: Did you forget to add a gobal
因为没有配置用户库
5、配置最简单的内存用户库
<authentication-manager>
注意角色名称一定要有ROLE_前缀,不用这个前缀需要改配置。
运行起来,访问http://t18:3000/s4/home,出现spring security自带的登陆界面;输入habuma letmein,登陆成功!
6、配置jdbc访问数据库用户
去掉上面5中的内容,加上:
data-source-ref="dataSource"
users-by-username-query=
"select logname,password,1 from users where logName=?"
authorities-by-username-query=
"select b.logName username,rolename from users_roles a,users b,roles c where a.userId=b.userId and a.roleId=c.roleId and b.logName=?" />
注意sql语句的写法:
--取用户:select logname,password,1 from users where logName=?一定要有1(SQLServer,其他数据库可取能为true);
--取角色:select b.logName username,rolename from users_roles a,users b,roles c where a.userId=b.userId and a.roleId=c.roleId and b.logName=?
用户名一定要用username的别名,否则取不到
运行起来,访问http://t18:3000/s4/home,出现spring security自带的登陆界面;输入test test,登陆成功!
当然,数据库中用户名test,密码test,角色ROLE_TEST
7、配置hibernate访问数据库用户
参照http://stackoverflow.com/questions/2683308/spring-security-3-database-authentication-with-hibernate
这里需要写一点代码。
a、写一个org.springframework.security.core.userdetails.User的构造器assembler bean:
@Service("assembler")
public class Assembler {
//@Transactional(readOnly = true)
User buildUserFromUserEntity(com.tdrc.common.beans.User userEntity) {
String username = userEntity.getLogName();
String password = userEntity.getPassword();
boolean enabled = true;//userEntity.isActive();
boolean accountNonExpired = true;//userEntity.isActive();
boolean credentialsNonExpired = true;//userEntity.isActive();
boolean accountNonLocked = true;//userEntity.isActive();
Collection
for (Object userrole : userEntity.getUserRoles()) {
UserRole ur = (UserRole)userrole;
authorities.add(new GrantedAuthorityImpl(ur.getId().getRole().getRoleName()));
}
User user = new User(username, password, enabled,
accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
return user;
}
}
b、实现org.springframework.security.core.userdetails.UserDetailsService接口的服务userDetailsService bean:
@Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired private com.tdrc.common.dao.IUserDao dao;
@Autowired private Assembler assembler;
//@Transactional(readOnly = true)
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException, DataAccessException {
UserDetails userDetails = null;
User userEntity = (User)dao.findObjectByHQL("from User u where u.logName='"+username+"'");
if (userEntity == null)
throw new UsernameNotFoundException("user not found");
return assembler.buildUserFromUserEntity(userEntity);
}
}
c、在security.xml中,用userDetailsService提供用户:
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
class="org.springframework.security.authentication.ProviderManager">
<authentication-manager>
d、配置事务,使得hibernate可用:
advice-ref="txAdvice"/>
advice-ref="txAdvice"/>
运行起来,访问http://t18:3000/s4/home,出现spring security自带的登陆界面;输入test test,登陆成功!
依然,数据库中用户名test,密码test,角色ROLE_TEST。
8、修改默认登陆界面
security.xml中修改http配置,增加form-login属性
login-page="/login"
authentication-failure-url="/login?login_error=t"/>
这里login-page和authentication-failure-url的/login指向一个spring mvc 控制器,它指向一个自定义登陆页面。
login-processing-url="/j_spring_security_check" 在《spring in action》第三版中写的是/static/j_spring_security_check
有的地方又说是/应用根/j_spring_security_check,折腾一上午,最后在我的环境里应该是/j_spring_security_check
自定义登陆页面就是一个form,用POST方法提交到/j_spring_security_check,用户名的name属性写成j-username,密码的name属性写成j-password即可。
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags" %>
9、另注:在参考spring security tutorial时,它用的是logback日志系统,需要添加:
jcl-over-slf4j-1.6.1.jar
logback-classic-0.9.29.jar
logback-core-0.9.29.jar
slf4j-api-1.6.1.jar
并在src下创建logback.xml: