RememberMe 功能的實現(base-auth使用說明)

平常記錄,代碼是根據SpringSecurity寫的。java

###寫個Entity類實現UserDetailsgit

<!-- 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;
	}

}

###寫個處理類,繼承UserDetailsServiceweb

<!-- 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;
	}	

}

###登陸處使用spring

<!-- 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";
}

###退出登陸處理session

<!-- lang: java -->
	public String logout(HttpServletRequest request,
    			HttpServletResponse response, HttpSession session) {
    		logger.info("LogoutController#logout");
    		rememberMeService.logout(request, response);
    		session.invalidate();
    		return "redirect:/";
    	}

###攔截器自動登陸實現app

<!-- 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是單項加密dom

自動登陸時,首先使用id與用戶名加載用戶信息. 而後把查詢出來的密碼與key再次加密,與上次結果比較 若是兩次加密相等,則登陸成功ide

項目地址:http://git.oschina.net/unsuccessful/remembermethis

相關文章
相關標籤/搜索