原文地址:http://peihexian.iteye.com/blog/2155516
需要在项目里面引入的maven依赖:
<dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.2.1</version> </dependency> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache-core</artifactId> <version>2.6.9</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-quartz</artifactId> <version>1.2.3</version> </dependency>
如果项目是hibernate的,以前的时候ehcache可能不是单例的,因为shiro里面也使用到了ehcache做缓存,和hibernate的ehcache缓存配置有冲突,所以需要对hibernate的ehcache部分做些调整,调整如下:
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> <!-- <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.EhCacheRegionFactory</prop> --> <prop key="hibernate.cache.region.factory_class"> org.hibernate.cache.SingletonEhCacheRegionFactory </prop> <prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.SingletonEhCacheProvider</prop> <prop key="hibernate.cache.use_second_level_cache">true</prop> <prop key="hibernate.cache.use_query_cache">true</prop> <prop key="hibernate.cache.use_structured_entries">true</prop> <prop key="hibernate.cache.provider_configuration_file_resource_path">WEB-INF/classes/ehcache.xml</prop> <prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop> </props> </property> <property name="packagesToScan"> <list> <value>com.xxx.entity</value> </list> </property> </bean>
上面红色的文字部分是需要调整的内容。
既然用到了ehcache,ehcahce.xml文件里面的配置内容如下:
<?xml version="1.0" encoding="UTF-8"?> <ehcache> <diskStore path="java.io.tmpdir" /> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" /> <cache name="org.hibernate.cache.UpdateTimestampsCache" maxElementsInMemory="5000" eternal="true" overflowToDisk="true" /> <cache name="org.hibernate.cache.StandardQueryCache" maxElementsInMemory="10000" eternal="false" timeToLiveSeconds="120" overflowToDisk="true" /> <!-- 登录记录缓存 锁定10分钟 --> <cache name="passwordRetryCache" maxEntriesLocalHeap="2000" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="0" overflowToDisk="false" statistics="true"> </cache> <cache name="authorizationCache" maxEntriesLocalHeap="2000" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="0" overflowToDisk="false" statistics="true"> </cache> <cache name="authenticationCache" maxEntriesLocalHeap="2000" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="0" overflowToDisk="false" statistics="true"> </cache> <cache name="shiro-activeSessionCache" maxEntriesLocalHeap="2000" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="0" overflowToDisk="false" statistics="true"> </cache> </ehcache>
然后是web.xml文件里面加过滤器,注意要写在springmvc的filter前面
<!-- shiro 安全过滤器 --> <!-- The filter-name matches name of a 'shiroFilter' bean inside applicationContext.xml --> <filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <async-supported>true</async-supported> <init-param> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> </filter> <!-- Make sure any request you want accessible to Shiro is filtered. /* catches all --> <!-- requests. Usually this filter mapping is defined first (before all others) to --> <!-- ensure that Shiro works in subsequent filters in the filter chain: --> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
然后就是shiro相关的spring配置参数文件了
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <!-- 缓存管理器 使用Ehcache实现--> <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> <property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/> </bean> <bean id="passwordHelper" class="com.shinowit.framework.security.PasswordHelper"> </bean> <!-- 凭证匹配器 --> <bean id="credentialsMatcher" class="com.shinowit.framework.security.credentials.RetryLimitSimpleCredentialsMatcher"> <constructor-arg ref="cacheManager"/> <property name="passwordHelper" ref="passwordHelper"/> </bean> <bean id="shiro_user_dao" class="com.shinowit.framework.security.dao.UserDAO"> <property name="jt" ref="jdbcTemplate"/> </bean> <!-- Realm实现 --> <bean id="userRealm" class="com.shinowit.framework.security.realm.UserRealm"> <property name="userDAO" ref="shiro_user_dao"/> <property name="credentialsMatcher" ref="credentialsMatcher"/> <!--密码校验接口--> <property name="cachingEnabled" value="true"/> <property name="authenticationCachingEnabled" value="true"/> <property name="authenticationCacheName" value="authenticationCache"/> <property name="authorizationCachingEnabled" value="true"/> <property name="authorizationCacheName" value="authorizationCache"/> </bean> <!-- 会话ID生成器 --> <bean id="sessionIdGenerator" class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator"/> <!-- 会话Cookie模板 --> <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie"> <constructor-arg value="sid"/> <property name="httpOnly" value="true"/> <property name="maxAge" value="180000"/> </bean> <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie"> <constructor-arg value="rememberMe"/> <property name="httpOnly" value="true"/> <property name="maxAge" value="2592000"/> <!-- 30天 --> </bean> <!-- rememberMe管理器 --> <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager"> <property name="cipherKey" value="#{T(org.apache.shiro.codec.Base64).decode('4AvVhmFLUs0KTA3Kprsdag==')}"/> <property name="cookie" ref="rememberMeCookie"/> </bean> <!-- 会话DAO --> <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO"> <property name="activeSessionsCacheName" value="shiro-activeSessionCache"/> <property name="sessionIdGenerator" ref="sessionIdGenerator"/> </bean> <!-- 会话验证调度器 --> <bean id="sessionValidationScheduler" class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler"> <property name="sessionValidationInterval" value="1800000"/> <property name="sessionManager" ref="sessionManager"/> </bean> <!-- 会话管理器 --> <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> <property name="globalSessionTimeout" value="1800000"/> <property name="deleteInvalidSessions" value="true"/> <property name="sessionValidationSchedulerEnabled" value="true"/> <property name="sessionValidationScheduler" ref="sessionValidationScheduler"/> <property name="sessionDAO" ref="sessionDAO"/> <property name="sessionIdCookieEnabled" value="true"/> <property name="sessionIdCookie" ref="sessionIdCookie"/> </bean> <!-- 安全管理器 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="userRealm"/> <property name="sessionManager" ref="sessionManager"/> <property name="cacheManager" ref="cacheManager"/> <property name="rememberMeManager" ref="rememberMeManager"/> </bean> <!-- 相当于调用SecurityUtils.setSecurityManager(securityManager) --> <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"/> <property name="arguments" ref="securityManager"/> </bean> <!--下面的loginUrl有两个必要条件,一个登陆校验失败以后会强制客户端redirect到这个url, 另外一个是登陆的表单(含有用户名及密码)必须action到这个url--> <!-- 自定义的能够接收校验码的身份验证过滤器 跳转问题太他妈诡异了,不用了,自己写代码控制如何跳转了 <bean id="formAuthenticationFilter" class="com.shinowit.framework.security.filter.ValidFormAuthenticationFilter"> <property name="usernameParam" value="loginName"/> <property name="passwordParam" value="loginPass"/> <property name="loginUrl" value="/login/"/> </bean> --> <!-- Shiro的Web过滤器 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"/> <property name="loginUrl" value="/login/"/> <property name="unauthorizedUrl" value="/unauthorized.jsp"/> <property name="filters"> <map> <entry key="authc"> <bean class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter"/> </entry> </map> <!-- <util:map> <entry key="authc" value-ref="formAuthenticationFilter"/> </util:map> --> </property> <property name="filterChainDefinitions"> <value> /index.jsp = anon /validcode.jsp = anon /login/ = anon /static/** = anon /js/** = anon /img/** = anon /unauthorized.jsp = anon #/login/checklogin = authc /login/checklogin = anon /login/logout = logout /** = user </value> </property> </bean> <!-- Shiro生命周期处理器--> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> </beans>
下面就是各种自己封装的java代码了
自定义的可以保存校验码的token类
package com.xxx.framework.security.token; import org.apache.shiro.authc.UsernamePasswordToken; /** * Created on 2014/11/11. */ public class CustomUsernamePasswordToken extends UsernamePasswordToken { //用于存储用户输入的校验码 private String validCode; public CustomUsernamePasswordToken(String username, char[] password,boolean rememberMe, String host, String validCode) { //调用父类的构造函数 super(username,password,rememberMe,host); this.validCode=validCode; } public String getValidCode() { return validCode; } public void setValidCode(String validCode) { this.validCode = validCode; } }
提供正确的登录用户信息的基于jdbc的realm
package com.xxx.framework.security.realm; import com.xxx.entity.SysUserEntity; import com.xxx.framework.security.dao.UserDAO; import com.xxx.framework.security.exception.ValidCodeException; import com.xxx.framework.security.token.CustomUsernamePasswordToken; import org.apache.log4j.Logger; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.*; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; public class UserRealm extends AuthorizingRealm { private static Logger logger = Logger.getLogger(UserRealm.class); private UserDAO userDAO; public void setUserDAO(UserDAO userDAO) { this.userDAO = userDAO; } @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { String username = (String) principals.getPrimaryPrincipal(); SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); authorizationInfo.setRoles(userDAO.getUserRoles(username)); authorizationInfo.setStringPermissions(userDAO.findPermissions(username)); return authorizationInfo; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { CustomUsernamePasswordToken login_token = (CustomUsernamePasswordToken) token; //校验码判断逻辑 //取得用户输入的校验码 String userInputValidCode = login_token.getValidCode(); //取得真实的正确校验码 String realRightValidCode = (String) SecurityUtils.getSubject().getSession().getAttribute("rand"); if (null == userInputValidCode || !userInputValidCode.equalsIgnoreCase(realRightValidCode)) { logger.debug("验证码输入错误"); throw new ValidCodeException("验证码输入不正确"); } //以上校验码验证通过以后,查数据库 String username = (String) token.getPrincipal(); SysUserEntity user = userDAO.findByUsername(username); if (user == null) { throw new UnknownAccountException();//没找到帐号 } if (Boolean.FALSE.equals(user.getValid())) { throw new LockedAccountException(); //帐号锁定 } //交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配,如果觉得人家的不好可以自定义实现 SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo( user.getLoginName(), //用户名 user.getLoginPass(), //密码 getName() //realm name ); return authenticationInfo; } @Override public void clearCachedAuthorizationInfo(PrincipalCollection principals) { super.clearCachedAuthorizationInfo(principals); } @Override public void clearCachedAuthenticationInfo(PrincipalCollection principals) { super.clearCachedAuthenticationInfo(principals); } @Override public void clearCache(PrincipalCollection principals) { super.clearCache(principals); } public void clearAllCachedAuthorizationInfo() { getAuthorizationCache().clear(); } public void clearAllCachedAuthenticationInfo() { getAuthenticationCache().clear(); } public void clearAllCache() { clearAllCachedAuthenticationInfo(); clearAllCachedAuthorizationInfo(); } }
一个简单的自定义的处理校验码异常的类
package com.xxx.framework.security.exception; import org.apache.shiro.authc.AuthenticationException; /** * Created on 2014/11/11. */ public class ValidCodeException extends AuthenticationException { public ValidCodeException(String msg){ super(msg); } }
查询用户信息及权限信息的dao
package com.xxx.framework.security.dao; import com.xxx.entity.SysUserEntity; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import java.util.HashSet; import java.util.List; import java.util.Set; /** * Created on 2014/11/10. */ public class UserDAO { private JdbcTemplate jt; public void setJt(JdbcTemplate jt) { this.jt = jt; } public Set<String> getUserRoles(String loginName) { String sql = "select role from sys_user u, sys_role r,sys_user_to_role ur where u.login_name=? and u.user_code=ur.user_code and r.role_code=ur.role_code"; return new HashSet(jt.queryForList(sql, String.class, loginName)); } public Set<String> findPermissions(String loginName) { String sql = "select permission from sys_user u, sys_role r, sys_menu p, sys_user_to_role ur, sys_role_to_menu rp where u.login_name=? and u.user_code=ur.user_code and r.role_code=ur.role_code and r.role_code=rp.role_code and p.menu_id=rp.menu_id"; return new HashSet(jt.queryForList(sql, String.class, loginName)); } public SysUserEntity findByUsername(String loginName) { String sql = "select id, user_code,login_name, login_pass, valid from sys_user where login_name=?"; List<SysUserEntity> userList = jt.query(sql, new BeanPropertyRowMapper(SysUserEntity.class), loginName); if (userList.size() == 0) { return null; } return userList.get(0); } }
这个翻译过来叫啥合适呢?反正就是根据自定义的加密规则去进行密码匹配验证的类,爱JB叫啥叫啥吧
package com.xxx.framework.security.credentials; import com.xxx.framework.security.PasswordHelper; import com.xxx.framework.security.token.CustomUsernamePasswordToken; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.ExcessiveAttemptsException; import org.apache.shiro.authc.credential.SimpleCredentialsMatcher; import org.apache.shiro.cache.Cache; import org.apache.shiro.cache.CacheManager; import java.util.concurrent.atomic.AtomicInteger; public class RetryLimitSimpleCredentialsMatcher extends SimpleCredentialsMatcher { private Cache<String, AtomicInteger> passwordRetryCache; private PasswordHelper passwordHelper; public RetryLimitSimpleCredentialsMatcher(CacheManager cacheManager) { passwordRetryCache = cacheManager.getCache("passwordRetryCache"); } public void setPasswordHelper(PasswordHelper passwordHelper) { this.passwordHelper = passwordHelper; } @Override public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { CustomUsernamePasswordToken login_token = (CustomUsernamePasswordToken) token; String username = (String) token.getPrincipal(); //retry count + 1 AtomicInteger retryCount = passwordRetryCache.get(username); if (retryCount == null) { retryCount = new AtomicInteger(0); passwordRetryCache.put(username, retryCount); } if (retryCount.incrementAndGet() > 5) { //if retry count > 5 throw throw new ExcessiveAttemptsException(); } String user_input_login_pass = passwordHelper.encryptPassword(login_token.getUsername(), String.valueOf(login_token.getPassword())); Object db_login_password = getCredentials(info); //将密码加密与系统加密后的密码校验,内容一致就返回true,不一致就返回false boolean matches = super.equals(user_input_login_pass, db_login_password); if (matches) { //clear retry count passwordRetryCache.remove(username); } return matches; } }
用户信息实体类
package com.xxx.entity; import javax.persistence.*; import java.util.List; /** * Created on 2014/11/7. * 系统用户信息 */ @Entity @Table(name = "sys_user") public class SysUserEntity { @GeneratedValue(strategy =GenerationType.IDENTITY) @Column(name = "id",insertable = false,updatable = false) private Integer id; @Id @Column(name = "user_code",length = 6) private String userCode; @Column(name = "login_name",length = 40,nullable = false,unique = true) private String loginName; @Column(name = "login_pass",length = 50) private String loginPass; @Column(name = "address",length = 200) private String address; @Column(name = "telphone",length = 30) private String telPhone; @Column(name = "qq",length = 15) private String qq; @Column(name = "email",length = 40) private String email; @Column(name = "mobile",length = 30) private String mobile; @Column(name = "sort_id") private Short sortId; @Column(name = "valid") private Boolean valid; @ManyToMany(fetch = FetchType.LAZY) @JoinTable(name="sys_user_to_role",joinColumns = { @JoinColumn(name = "user_code") }, inverseJoinColumns = { @JoinColumn(name = "role_code")}) private List<SysRoleEntity> roleList; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUserCode() { return userCode; } public void setUserCode(String userCode) { this.userCode = userCode; } public String getLoginName() { return loginName; } public void setLoginName(String loginName) { this.loginName = loginName; } public String getLoginPass() { return loginPass; } public void setLoginPass(String loginPass) { this.loginPass = loginPass; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getTelPhone() { return telPhone; } public void setTelPhone(String telPhone) { this.telPhone = telPhone; } public String getQq() { return qq; } public void setQq(String qq) { this.qq = qq; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } public Short getSortId() { return sortId; } public void setSortId(Short sortId) { this.sortId = sortId; } public Boolean getValid() { return valid; } public void setValid(Boolean valid) { this.valid = valid; } public List<SysRoleEntity> getRoleList() { return roleList; } public void setRoleList(List<SysRoleEntity> roleList) { this.roleList = roleList; } }
还有一个md5工具类
package com.xxx.framework.security; import java.security.MessageDigest; public class PasswordHelper { /** * 根据用户名与密码做md5单向hash加密 * * @param username 用户名 * @param password 用户密码明文 * @return md5(username+password) */ public String encryptPassword(String username, String password) { String inStr = username + password; MessageDigest md5 = null; try { md5 = MessageDigest.getInstance("MD5"); } catch (Exception e) { System.out.println(e.toString()); e.printStackTrace(); return ""; } char[] charArray = inStr.toCharArray(); byte[] byteArray = new byte[charArray.length]; for (int i = 0; i < charArray.length; i++) byteArray[i] = (byte) charArray[i]; byte[] md5Bytes = md5.digest(byteArray); StringBuffer hexValue = new StringBuffer(); for (int i = 0; i < md5Bytes.length; i++) { int val = ((int) md5Bytes[i]) & 0xff; if (val < 16) hexValue.append("0"); hexValue.append(Integer.toHexString(val)); } return hexValue.toString(); } }
好了,我们的springmvc controller类是这么写的
package com.xxx.web.login; import com.xxx.entity.SysUserEntity; import com.xxx.framework.dao.BaseDAO; import com.xxx.framework.security.PasswordHelper; import com.xxx.framework.security.exception.ValidCodeException; import com.xxx.framework.security.token.CustomUsernamePasswordToken; import org.apache.log4j.Logger; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.ExcessiveAttemptsException; import org.apache.shiro.authc.IncorrectCredentialsException; import org.apache.shiro.authc.UnknownAccountException; import org.apache.shiro.authz.annotation.RequiresUser; import org.apache.shiro.subject.Subject; import org.apache.shiro.web.filter.authc.FormAuthenticationFilter; import org.apache.shiro.web.util.WebUtils; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.util.HashMap; import java.util.Map; @Controller @RequestMapping(value = "/login") public class LoginController { private static final Logger logger = Logger.getLogger(LoginController.class); @Resource private BaseDAO<SysUserEntity> sys_user_dao; @RequestMapping(value = "/", method = RequestMethod.GET) public String login() { return "/login/login"; } @RequestMapping(value = "/checklogin", method = RequestMethod.POST) @ResponseBody public Map<String, Object> checkLogin(SysUserEntity login_user,HttpServletRequest request,@RequestParam("validCode")String validCode) { Map<String, Object> result = new HashMap<String, Object>(); result.put("msg", "用户名或者密码错误!"); result.put("success", "true"); result.put("status", false); boolean rememberMe = WebUtils.isTrue(request, FormAuthenticationFilter.DEFAULT_REMEMBER_ME_PARAM); String host = request.getRemoteHost(); //构造登陆令牌环 CustomUsernamePasswordToken token = new CustomUsernamePasswordToken(login_user.getLoginName(), login_user.getLoginPass().toCharArray(), rememberMe,host,validCode); try{ //发出登陆请求 SecurityUtils.getSubject().login(token); //登陆成功 HttpSession session = request.getSession(true); try { SysUserEntity user = sys_user_dao.findOneEntityByHql("from SysUserEntity where loginName=?", login_user.getLoginName()); if (null != user) { //根据输入的用户名和密码确实查到了用户信息 session.removeAttribute("rand"); session.setAttribute("current_login_user", user); result.put("msg", "登录成功!"); result.put("status", true); result.put("main_url", "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/main"); } } catch (Exception e) { logger.error(e.getMessage(), e); } return result; }catch (UnknownAccountException e){ result.put("msg", "账号不存在!"); }catch (IncorrectCredentialsException e){ result.put("msg", "用户名/密码错误!"); }catch (ExcessiveAttemptsException e) { result.put("msg", "账户错误次数过多,暂时禁止登录!"); }catch (ValidCodeException e){ result.put("msg", "验证码输入错误!"); }catch (Exception e){ result.put("msg", "未知错误!"); } return result; } @RequestMapping(value="/logout") public String logout(){ Subject currentUser = SecurityUtils.getSubject(); if (SecurityUtils.getSubject().getSession() != null) { currentUser.logout(); } return "redirect:/login/"; } @Resource private PasswordHelper passwordHelper; @RequestMapping(value = "/fuck") @ResponseBody public Map<String, Object> fuck() { Map<String, Object> result = new HashMap<String, Object>(); result.put("msg", "用户名或者密码错误!"); result.put("success", "true"); result.put("status", false); SysUserEntity user = sys_user_dao.findById(SysUserEntity.class, "0001"); user.setLoginPass("a"); String new_pass = passwordHelper.encryptPassword(user.getLoginName(), user.getLoginPass()); user.setLoginPass(new_pass); sys_user_dao.update(user); return result; } }
哦,对了,里面那个fuck那个url是用来改密码的,因为数据库里面的密码是加密的,不这么整总也不可能知道对的md5值是多少。
但愿没有忘记什么内容,挺墨迹的,不过能跑起来以后后边关于权限和安全的处理就简单多了,写写注解或者标签就搞定了,很爽。