shiro在springmvc里面的集成使用。
原文地址: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/logoutlogout = 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值是多少。
但愿没有忘记什么内容,挺墨迹的,不过能跑起来以后后边关于权限和安全的处理就简单多了,写写注解或者标签就搞定了,很爽。
- ossmvc.rar (641.7 KB)
- 下载次数: 10