从数据库或者其他数据源加载用户数据
1.ApplicationContext.xml配置,根据密码是加密过和使用salt的,则在<authentication-provider>中需要配置<password-encoder>和<salt-source>
<beans:property name="userPropertyToUse" value="salt" /> salt在UserDetail获取getSalt()方法的返回值
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<http use-expressions="true">
<intercept-url pattern="/login.html" filters="none"/>
<intercept-url pattern="/loginfail.html" filters="none"/>
<intercept-url pattern="/loginsucc.html" access="hasAnyRole('user')" />
<intercept-url pattern="/resource.html" access="hasAnyRole('admin')" />
<form-login login-page="/login.html" login-processing-url="/login.shtml"
default-target-url="/loginsucc.html" authentication-failure-url="/loginfail.html"/>
<!-- 配置退出页面 -->
<logout logout-url="/logout.shtml" logout-success-url="/login.html" />
<anonymous enabled="false"/>
</http>
<authentication-manager>
<authentication-provider user-service-ref="userService">
<password-encoder ref="encoder">
<salt-source ref="saltSource"/>
</password-encoder>
</authentication-provider>
</authentication-manager>
<beans:bean id="encoder"
class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />
<beans:bean id="saltSource"
class="org.springframework.security.authentication.dao.ReflectionSaltSource">
<beans:property name="userPropertyToUse" value="salt" />
</beans:bean>
<beans:bean id="userService" class="lan.service.impl.UserServiceImpl">
<beans:property name="encoder" ref="encoder"/>
<beans:property name="saltSource" ref="saltSource" />
</beans:bean>
</beans:beans>
2.实现UserDetailService
package lan.service.impl;
import lan.model.User;
import lan.service.UserService;
import org.springframework.dao.DataAccessException;
import org.springframework.security.authentication.dao.SaltSource;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
public class UserServiceImpl implements UserService, UserDetailsService {
//用于给密码加密
private PasswordEncoder encoder;
private SaltSource saltSource;
public void setEncoder(PasswordEncoder encoder) {
this.encoder = encoder;
}
public void setSaltSource(SaltSource saltSource) {
this.saltSource = saltSource;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
//在此处加载用户信息,比如根据用户名从数据库获取用户密码,角色等信息
return user; //该出返回的user是UserDetail的一个实现
}
}
3.认证主体必须实现UserDetail
package lan.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
public class User implements UserDetails {
private static final long serialVersionUID = -7107484257288140958L;
private String companyname;
private String username; //lan
private String password = "3fdf39fe84f3ac372f41fecb1c51299b"; //原始密码为:111111
private Set<Role> roles = new HashSet<Role>();
public User(){}
public User(String username) {
super();
this.username = username;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
public String getCompanyname() {
return "lan";
}
public void setCompanyname(String companyname) {
this.companyname = companyname;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public Collection<GrantedAuthority> getAuthorities() {
Role role = new Role();
role.setName("user");
Collection<GrantedAuthority> roles = new ArrayList<GrantedAuthority>();
roles.add(role);
return roles;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
public Object getSalt(){
return username;
}
@Override
public String toString() {
return "User [companyname=" + companyname + ", username=" + username + ", password=" + password + "]";
}
}
package lan.model;
import org.springframework.security.core.GrantedAuthority;
public class Role implements GrantedAuthority {
private static final long serialVersionUID = -2431947985974407523L;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String getAuthority() {
return name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Role other = (Role) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}