日常记录,代码是根据SpringSecurity写的。
###写个Entity类实现UserDetails
<!-- lang: java -->
package com.lqz.b2c.base.web.controller.member.support;
import com.lqz.b2c.base.entity.Passport;
import com.lqz.base.auth.UsernameNotFoundException;
import com.lqz.base.auth.userdetails.UserDetails;
public class LoginUserSupport implements UserDetails {
private static final long serialVersionUID = 20130411151453L;
public LoginUserSupport() {
// TODO Auto-generated constructor stub
}
public LoginUserSupport(Passport passport) throws UsernameNotFoundException {
if (passport == null || passport.getId() == null
|| passport.getId() <= 0 || passport.getLoginName() == null
|| passport.getPassword() == null) {
throw new UsernameNotFoundException();
}
setId(passport.getId());
setUsername(passport.getLoginName());
setPassword(passport.getPassword());
}
private Long id;
private String username;
private String password;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public void setLoginName(String loginName) {
this.username = loginName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
/**
* 非过期账户
*/
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
###写个处理类,继承UserDetailsService
<!-- lang: java -->
package com.lqz.b2c.base.service.impl;
import javax.annotation.Resource;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.lqz.b2c.base.entity.Passport;
import com.lqz.b2c.base.repository.IPassportDao;
import com.lqz.b2c.base.service.IPassportMgr;
import com.lqz.b2c.base.web.controller.member.support.LoginUserSupport;
import com.lqz.base.auth.UsernameNotFoundException;
import com.lqz.base.auth.userdetails.UserDetails;
import com.lqz.base.auth.userdetails.UserDetailsService;
/**
* @author 小败
*
*/
@Service("passportMgrImpl")
@Transactional(readOnly = true)
public class PassportMgrImpl implements IPassportMgr, UserDetailsService {
@Override
public UserDetails loadUser(Long userId, String username)
throws UsernameNotFoundException, DataAccessException {
Passport passport = passportDao.findByIDAndLoginName(userId, username);
LoginUserSupport user = new LoginUserSupport(passport);
return user;
}
/** 注入 **/
private IPassportDao passportDao;
@Resource(name = "passportDao")
public void setPassportDao(IPassportDao passportDao) {
this.passportDao = passportDao;
}
}
###登录处使用
<!-- lang: java -->
@RequestMapping(method = RequestMethod.POST)
public String login(LoginUserSupport user, HttpServletRequest request,
HttpServletResponse response, RedirectAttributes redirectAttributes) {
Passport passport = passportMgr.login(user.getUsername(),
user.getPassword());
if (passport != null) {
user.setId(passport.getId());
user.setPassword(passport.getPassword());
rememberMeService.loginSuccess(request, response, user);
return passportMgr.login(request.getSession(), passport);
}
redirectAttributes.addFlashAttribute("login_error", "登录失败");
return "redirect:/login";
}
###退出登录处理
<!-- lang: java -->
public String logout(HttpServletRequest request,
HttpServletResponse response, HttpSession session) {
logger.info("LogoutController#logout");
rememberMeService.logout(request, response);
session.invalidate();
return "redirect:/";
}
###拦截器自动登录实现
<!-- lang: java -->
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object obj) throws Exception {
/**
* 判断用户有没有登录
*/
Passport account = (Passport) WebUtils.getSessionAttribute(request, "passport");
if (account != null) {
return true;
}
/**
* 判断有没有Cookie 有的话提取Cookie 内容
*/
UserDetails user = rememberMeService.autoLogin(request, response);
if (user == null) {
return true;
}
/**
* 自动登录
*/
Passport passport = passportMgr.getPassportById(user.getId());
if (passport != null) {
passportMgr.login(request.getSession(), passport);
} else {
rememberMeService.loginFail(request, response);
}
return true;
}
Spring 配置
<!-- lang: xml -->
<bean id="rememberMeService" class="com.lqz.base.auth.rememberme.TokenBasedRememberMeServices">
<property name="key" value="20130411192953"/>
<property name="domain" value=".lqz.com"/><!-- option -->
<property name="parameter" value="rememberMe"/><!-- defult: remember_me -->
<property name="userDetailsService" ref="passportMgrImpl"/>
</bean>
原理
登录时,把数据以[用户名:时间:密码:key:id]形式加密 其中密码与key是单项加密
自动登录时,首先使用id与用户名加载用户信息. 然后把查询出来的密码与key再次加密,与上次结果比较 如果两次加密相等,则登录成功