2019独角兽企业重金招聘Python工程师标准>>>
日常记录,代码是根据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;}/*** 非过期账户*/@Overridepublic boolean isAccountNonExpired() {return true;}@Overridepublic boolean isAccountNonLocked() {return true;}@Overridepublic boolean isCredentialsNonExpired() {return true;}@Overridepublic 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 {@Overridepublic 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再次加密,与上次结果比较 如果两次加密相等,则登录成功
项目地址:http://git.oschina.net/unsuccessful/rememberme