在开发时,可以让系统记住登录,可以避免开发调试重复登录带来的麻烦,提高调试的效率,在系统中,点击“让系统记住我”选项。
若要启用该功能,系统需要进行以下的配置:
1.系统现在打开了用户密码加密的配置(加密配置为SHA-256),因而系统的密码需要重新设置,可以调用系统StringUtil的方法:
public static synchronized String encryptSha256(String inputStr) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte digest[] = md.digest(inputStr.getBytes("UTF-8"));
return new String(Base64.encodeBase64(digest));
//return (new BASE64Encoder()).encode(digest);
//return new String(Hex.encodeHex(digest));
}
catch (Exception e) {
return null;
}
}
public static void main(String[]args){
String password="111";
String result=encryptSha256(password);
//System.out.println("array:"+ new String(Hex.encodeHex(dis)));
System.out.println("result:" + result);
}
如密码为111,加密后为:9uCh4qxBlFqap/+KiqoM68EqO8yYGpKa1c+BCgkOEa4=
请执行:
update app_user set password='9uCh4qxBlFqap/+KiqoM68EqO8yYGpKa1c+BCgkOEa4=';
把所有的用户的密码更新为111
2.App-security.xml中打开配置:
<?xml version="1.0" encoding="UTF-8"?>
<b:beans xmlns="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:b="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">
<http auto-config="true" access-denied-page="/403.jsp" lowercase-comparisons="true" >
<intercept-url pattern="/images/**" filters="none"/>
<intercept-url pattern="/css/**" filters="none"/>
<intercept-url pattern="/js/**" filters="none"/>
<intercept-url pattern="/403*" filters="none"/>
<intercept-url pattern="/404*" filters="none"/>
<intercept-url pattern="/500*" filters="none"/>
<intercept-url pattern="/ext3/**" filters="none"/>
<intercept-url pattern="/fckeditor/**" filters="none"/>
<intercept-url pattern="/jsonStruts**" filters="none"/>
<intercept-url pattern="/file-upload" access="ROLE_PUBLIC,ROLE_ANONYMOUS"/>
<intercept-url pattern="/fileDetail.do" access="ROLE_PUBLIC"/>
<intercept-url pattern="/index.jsp" access="ROLE_PUBLIC"/>
<intercept-url pattern="/login.do**" access="ROLE_PUBLIC,ROLE_ANONYMOUS"/>
<intercept-url pattern="/check.do**" access="ROLE_PUBLIC,ROLE_ANONYMOUS"/>
<intercept-url pattern="/**" access="ROLE_PUBLIC"/>
<form-login default-target-url="/index.jsp" login-page="/login.jsp" authentication-failure-url="/login.jsp?error=true" login-processing-url="/j_security_check" />
<logout logout-url="/j_logout.do" logout-success-url="/login.jsp"/>
<remember-me key="RememberAppUser"/>
</http>
<authentication-manager alias="authenticationManager"/>
<authentication-provider user-service-ref="appUserDao">
<password-encoder hash="sha-256" base64="true"/>
</authentication-provider>
</b:beans>
3.在LoginAction中,添加如下代码(红色部分):
package com.htsoft.oa.action.system;
import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import nl.captcha.Captcha;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.security.AuthenticationManager;
import org.springframework.security.context.SecurityContext;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.ui.rememberme.TokenBasedRememberMeServices;
import org.springframework.security.ui.webapp.AuthenticationProcessingFilter;
import com.htsoft.core.util.AppUtil;
import com.htsoft.core.util.StringUtil;
import com.htsoft.core.web.action.BaseAction;
import com.htsoft.oa.model.system.AppUser;
import com.htsoft.oa.service.system.AppUserService;
public class LoginAction extends BaseAction{
private AppUser user;
private String username;
private String password;
private String checkCode;//验证码
//must be same to app-security.xml
private String key="RememberAppUser";
//private String rememberMe;//自动登录
@Resource
private AppUserService userService;
@Resource(name="authenticationManager")
private AuthenticationManager authenticationManager=null;
/**
* 登录
* @return
*/
public String login(){
StringBuffer msg = new StringBuffer("{msg:'");
Captcha captcha = (Captcha)getSession().getAttribute(Captcha.NAME);
Boolean login = false;
String newPassword=null;
if(!"".equals(username)&&username!=null){
setUser(userService.findByUserName(username));
if(user!=null){
if(StringUtils.isNotEmpty(password)){
newPassword=StringUtil.encryptSha256(password);
if(user.getPassword().equalsIgnoreCase(newPassword)){
if(captcha.isCorrect(checkCode)){
if(user.getStatus()==1){
login=true;
}
else msg.append("此用户已被禁用.'");
}
else msg.append("验证码不正确.'");
}
else msg.append("密码不正确.'");
}
else msg.append("密码不能为空.'");
}
else msg.append("用户不存在.'");
}
if(login){
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
SecurityContext securityContext = SecurityContextHolder.getContext();
securityContext.setAuthentication(authenticationManager.authenticate(authRequest));
SecurityContextHolder.setContext(securityContext);
getSession().setAttribute(AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY,username);
String rememberMe = getRequest().getParameter("_spring_security_remember_me");
if(rememberMe!=null&&rememberMe.equals("on")){
//加入cookie
long tokenValiditySeconds = 1209600; // 14 days
long tokenExpiryTime = System.currentTimeMillis() + (tokenValiditySeconds * 1000);
//DigestUtils.md5Hex(username + ":" + tokenExpiryTime + ":" + password + ":" + getKey());
String signatureValue = DigestUtils.md5Hex(username + ":" + tokenExpiryTime + ":" + user.getPassword() + ":" + key);
String tokenValue = username + ":" + tokenExpiryTime + ":" + signatureValue;
String tokenValueBase64 = new String(Base64.encodeBase64(tokenValue.getBytes()));
getResponse().addCookie(makeValidCookie(tokenExpiryTime, tokenValueBase64));
}
//登录成功后,需要把该用户显示至在线用户
AppUtil.addOnlineUser(getSession().getId(), user);
setJsonString("{success:true}");
}else{
msg.append(",failure:true}");
setJsonString(msg.toString());
}
return SUCCESS;
}
//add Cookie
protected Cookie makeValidCookie(long expiryTime, String tokenValueBase64) {
HttpServletRequest request=getRequest();
Cookie cookie = new Cookie(TokenBasedRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY, tokenValueBase64);
cookie.setMaxAge(60 * 60 * 24 * 365 * 5); // 5 years
cookie.setPath(org.springframework.util.StringUtils.hasLength(request.getContextPath()) ? request.getContextPath():"/");
return cookie;
}
public AppUser getUser() {
return user;
}
public void setUser(AppUser user) {
this.user = user;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getCheckCode() {
return checkCode;
}
public void setCheckCode(String checkCode) {
this.checkCode = checkCode;
}
}
当登录后,该Cookie的信息如下图所示:
可以看到SPRING_SECURITY_REMEMBER_ME_COOKIE存在,并且有效期是五年,不过里面的令牌只有14天,则真正有效期是14天,主要该COOKIE没有被删除,下次访问系统时,可以不用登录,直接访问index.jsp则可。