1. PasswordEncoder 采用密码加密
使用前面的例子。可以看出我们数据库密码是采用明文的,我们在登录的时候也需要将传递的明文密码使用对应的算法加密后再与保存好的密码比较,这样比较好,Spring-Security也有支持通过在authentication-provider下定义一个password-encoder我们可以定义当前AuthenticationProvider需要在进行认证时需要使用的password-encoder。password-encoder是一个PasswordEncoder的实例,我们可以直接使用它,如:
<!-- 认证管理器,配置了管理员与角色的关系 -->
<security:authentication-manager alias="authenticationManager">
<!-- accountService 实现了UserDetailsService接口
-->
<security:authentication-provider user-service-ref="accountService">
<!-- 密码采用md5加密 -->
<security:password-encoder hash="md5" />
</security:authentication-provider>
</security:authentication-manager>
上面的例子只是简单是使用md5加密。
- 其属性hash表示我们将用来进行加密的哈希算法,系统已经为我们实现的有plaintext、sha、sha-256、md4、md5、{sha}和{ssha}。它们对应的PasswordEncoder实现类如下:
加密算法 | PasswordEncoder实现类 |
---|---|
plaintext | PlaintextPasswordEncoder |
sha | ShaPasswordEncoder |
sha-256 | ShaPasswordEncoder,使用时new ShaPasswordEncoder(256) |
md4 | Md4PasswordEncoder |
md5 | Md5PasswordEncoder |
{sha} | LdapShaPasswordEncoder |
{ssha} | LdapShaPasswordEncoder |
- 使用BASE64编码加密后的密码
<security:password-encoder hash="md5" base64="true"/>
- 加密时使用salt
<!-- (1)下面的配置将使用常量“abc”作为salt。 -->
<security:authentication-manager>
<security:authentication-provider user-service-ref="userDetailsService">
<security:password-encoder hash="md5" base64="true">
<security:salt-source system-wide="abc"/>
</security:password-encoder>
</security:authentication-provider>
</security:authentication-manager>
<!--(2)下面的配置将使用UserDetails的username作为salt。 -->
<security:authentication-manager>
<security:authentication-provider user-service-ref="userDetailsService">
<security:password-encoder hash="md5" base64="true">
<security:salt-source user-property="username"/>
</security:password-encoder>
</security:authentication-provider>
</security:authentication-manager>
来源: http://www.mincoder.com/article/3505.shtml
2. 获取当前的用户信息
spring-security 登录的时候,会将用户信息放到 session中,其中的key为 “SPRING_SECURITY_CONTEXT”,spring-security也给我们提供了获取方案
Account account = (Account) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
- 如果想管理我们用户信息。我们可以添加一个sessionAttribute监听器,来监听SPRING_SECURITY_CONTEXT,当spring-security中SPRING_SECURITY_CONTEXT有变化时,我们可以同步到我们自己的session中。这样方便我们自己管理用户信息。
package com.hp.listener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import com.hp.model.Account;
import com.hp.utils.ConfigUtil;
public class UserHttpSessionAttributeListener implements HttpSessionAttributeListener {
protected final Log logger = LogFactory.getLog(UserHttpSessionAttributeListener.class);
private SecurityContext context = null;
private final String springSecurityContext = "SPRING_SECURITY_CONTEXT";
/**
* session添加
*/
@Override
public void attributeAdded(HttpSessionBindingEvent event) {
// logger.info("attributeAdded---->" + event.getName() + event.getValue());
// 当前session中有新的属性时触发 SPRING_SECURITY_CONTEXT 是spring存放的key
if (event.getName().equals(springSecurityContext)) {
context = SecurityContextHolder.getContext();
Account account = (Account) context.getAuthentication().getPrincipal();
event.getSession().setAttribute(ConfigUtil.getSessionInfoName(), account);
}
}
@Override
public void attributeRemoved(HttpSessionBindingEvent event) {
// 在注销的时候,security已经销毁的整个session
}
/**
* session替换
*/
@Override
public void attributeReplaced(HttpSessionBindingEvent event) {
if (event.getName().equals(springSecurityContext)) {
// System.out.println("----session中更新登陆信息------");
context = SecurityContextHolder.getContext();
Account account = (Account) context.getAuthentication().getPrincipal();
event.getSession().setAttribute(ConfigUtil.getSessionInfoName(), account);
}
}
}