Apache Shiro 身份验证

来源:互联网 发布:四三九九网络 编辑:程序博客网 时间:2024/06/05 02:32

1、什么是Apache Shiro

Apache Shiro,Java的一个开源安全框架,类似的还有Spring Security,用于简洁地处理身份验证,授权,企业多个系统会话管理,加密服务等。

2、三大主要组件

Subject:代表了当前用户,与应用代码直接交互的shiro对外API;

SecurityManager:安全管理器,所有与安全有关的操作都会与SecurityManager交互,管理这所有的Subject,负责与其他shiro组件进行交互,是shiro的核心组件

Realm:域,Shiro从realm中获取安全数据(用户/角色/权限),即安全数据源,由开发人员自己注入。

3、其他组件

在shiro的用户权限认证过程中其通过两个方法来实现:

1、Authentication:是验证用户身份的过程。

2、Authorization:是授权访问控制,用于对用户进行的操作进行人证授权,证明该用户是否允许进行当前操作,如访问某个链接,某个资源文件等。

3、SessionManager :Shiro为任何应用提供了一个会话编程范式。
4、CacheManager :对Shiro的其他组件提供缓存支持。

4、Shiro标签

<shiro:guest> 验证未登录用户

<shiro:user>验证已登陆用户

<shiro:authenticated>已认证通过的用户。不包含已记住的用户,这是与user标签的区别所在。
<shiro:notAuthenticated>未认证通过用户,与authenticated标签相对应。与guest标签的区别是,该标签包含已记住用户。

 <shiro:principal/>输出当前用户信息,通常为登录帐号信息。Hello, <shiro:principal/>, how are you today?

<shiro:hasRole name="administrator"> 验证当前用户是否属于该角色。

<shiro:lacksRole name="administrator"> 与hasRole标签逻辑相反,当用户不属于该角色时验证通过。 

<shiro:hasAnyRoles name="developer, project manager, administrator">验证当前用户是否属于以下任意一个角色

<shiro:hasPermission name="user:create">验证当前用户是否拥有指定权限。

<shiro:hasPermission name="user:create"> 与hasPermission标签逻辑相反,当前用户没有制定权限时,验证通过。

注意:会进入授权方法一共有三种情况!

1、subject.hasRole(“admin”) 或 subject.isPermitted(“admin”):自己去调用这个是否有什么角色或者是否有什么权限的时候;

2、@RequiresRoles("admin") :在方法上加注解的时候;

3、[@shiro.hasPermission name = "admin"][/@shiro.hasPermission]:在页面上加shiro标签的时候,即进这个页面的时候扫描到有这个标签的时候。


5.配置(这里主要展示如何配置多个realm,支持用户名密码登陆和手机验证码登陆)

pom.xml

<!-- shiro start -->        <dependency>            <groupId>org.apache.shiro</groupId>            <artifactId>shiro-core</artifactId>        </dependency>        <dependency>            <groupId>org.apache.shiro</groupId>            <artifactId>shiro-web</artifactId>        </dependency>        <dependency>            <groupId>org.apache.shiro</groupId>            <artifactId>shiro-aspectj</artifactId>        </dependency>        <dependency>            <groupId>org.apache.shiro</groupId>            <artifactId>shiro-ehcache</artifactId>        </dependency>        <dependency>            <groupId>org.apache.shiro</groupId>            <artifactId>shiro-spring</artifactId>        </dependency>        <!-- shiro end -->

web.xml

<filter>        <filter-name>shiroFilter</filter-name>        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>        <init-param>            <param-name>targetFilterLifecycle</param-name>            <param-value>true</param-value>        </init-param>    </filter>    <filter-mapping>        <filter-name>shiroFilter</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping>
applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" 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-4.0.xsd" default-lazy-init="true">    <!-- shiro集群改造,参考:http://git.oschina.net/zhmlvft/spring_shiro_redis http://git.oschina.net/1231/spinach --><bean id="modelAuthricator" class="com.jusfoun.socialgrid.shiro.DefaultModularRealm"> <property name="definedRealms">                <map>                    <entry key="shiroDbRealm" value-ref="shiroDbRealm" />                    <entry key="shiroVertifyRealm" value-ref="shiroVertifyRealm" />                </map>            </property>    </bean>    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">        <property name="realms">           <list>             <ref bean="shiroDbRealm" />              <ref bean="shiroVertifyRealm" />            </list>        </property>        <property name="authenticator" ref="modelAuthricator"/>        <property name="sessionManager" ref="sessionManager" />        <property name="cacheManager" ref="redisCacheManager" />    </bean>    <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">        <property name="sessionDAO" ref="sessionDAO" />        <property name="sessionIdCookieEnabled" value="true" />        <property name="sessionIdCookie" ref="sessionIdCookie" />        <property name="deleteInvalidSessions" value="true" />        <property name="sessionValidationSchedulerEnabled" value="true" />    </bean>    <bean id="redisCacheManager" class="com.itmuch.core.shiro.RedisCacheManager">        <property name="redisManager" ref="redisManager" />    </bean>    <bean id="redisManager" class="com.itmuch.core.shiro.RedisManager">        <property name="expire" value="${redis.expireTime}" />        <property name="host" value="${redis.host}" />        <property name="password" value="${redis.pass}" />        <property name="port" value="${redis.port}" />        <property name="timeout" value="${redis.maxWait}" />    </bean>        <!-- session 保存到cookie,关闭浏览器下次可以直接登录认证,当maxAge为-1不会写cookie。 -->    <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">        <constructor-arg value="sid" />        <property name="httpOnly" value="true" />        <!-- 浏览器关闭session失效,不计入cookie -->        <property name="maxAge" value="-1" />    </bean>    <bean id="shiroDbRealm" class="com.jusfoun.socialgrid.shiro.ShiroDbRealm">        <property name="credentialsMatcher" ref="credentialsMatcher"></property>    </bean><bean id="shiroVertifyRealm" class="com.jusfoun.socialgrid.shiro.ShiroVertifyRealm">    </bean>    <!-- 自定义身份验证器,用于限制用户尝试次数,防止暴力登陆 -->    <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">        <property name="hashAlgorithmName" value="md5"></property>        <!-- true means hex encoded, false means base64 encoded -->        <property name="storedCredentialsHexEncoded" value="true" />        <!-- <property name="hashIterations" value="1" /> -->    </bean>    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">        <property name="securityManager" ref="securityManager" />        <property name="loginUrl" value="/login" />        <!-- <property name="unauthorizedUrl" value="${adminPath}" /> -->        <property name="successUrl" value="/" />        <property name="filters">            <map>                <entry key="authc" value-ref="authcFilter" />            </map>        </property>        <property name="filterChainDefinitions">            <value>            /*.json = anon                /common/upload = anon                /static/** = anon                /druid/* = perms[sys:datasource:view]                /vertificate/sendDxCode = anon                /sendDxCode = anon                /login = anon                /logout = logout                /getVerifyCode = anon                /loginByVertifyCode = anon                /** = user            </value>        </property>    </bean><bean id="authcFilter" class="com.jusfoun.socialgrid.shiro.MyFormAuthenticationFilter"></bean>    <!-- 自定义shiro的sessionDao,把session写入redis -->    <bean id="sessionDAO" class="com.itmuch.core.shiro.RedisSessionDao">        <constructor-arg ref="redisTemplate" />        <constructor-arg value="${redis.expireTime}" />    </bean>    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /></beans>


自定义异常类CaptchaException

package com.jusfoun.socialgrid.shiro;import org.apache.shiro.authc.AuthenticationException;/** * 验证码异常类 * @author user * */public class CaptchaException extends AuthenticationException{/** *  */private static final long serialVersionUID = 1L;public CaptchaException() {super();}public CaptchaException(String message, Throwable cause) {super(message, cause);}public CaptchaException(String message) {super(message);}public CaptchaException(Throwable cause) {super(cause);}}

DefaultModularRealm类

package com.jusfoun.socialgrid.shiro;import java.util.Collection;import java.util.Map;import org.apache.shiro.ShiroException;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.authc.pam.ModularRealmAuthenticator;import org.apache.shiro.realm.Realm;import org.apache.shiro.util.CollectionUtils;public class DefaultModularRealm extends ModularRealmAuthenticator {      private Map<String, Object> definedRealms;        /**      * 多个realm实现      */      @Override      protected AuthenticationInfo doMultiRealmAuthentication(              Collection<Realm> realms, AuthenticationToken token) {          return super.doMultiRealmAuthentication(realms, token);      }        /**      * 调用单个realm执行操作      */      @Override      protected AuthenticationInfo doSingleRealmAuthentication(Realm realm,              AuthenticationToken token) {            // 如果该realms不支持(不能验证)当前token          if (!realm.supports(token)) {              throw new ShiroException("token错误!");          }          AuthenticationInfo info = null;          try {              info = realm.getAuthenticationInfo(token);                if (info == null) {                  throw new ShiroException("token不存在!");              }          } catch (Exception e) {              throw new ShiroException("用户名或者密码错误!");          }          return info;      }        /**      * 判断登录类型执行操作      */      @Override      protected AuthenticationInfo doAuthenticate(              AuthenticationToken authenticationToken)              throws AuthenticationException {          this.assertRealmsConfigured();            Realm realm = null;            if(authenticationToken instanceof UsernamePasswordToken){        realm = (Realm) this.definedRealms.get("shiroDbRealm");        }        if(authenticationToken instanceof UsernamePasswordCaptchaToken){        realm = (Realm) this.definedRealms.get("shiroVertifyRealm");        }        if (realm == null) {              return null;          }            return this.doSingleRealmAuthentication(realm, authenticationToken);      }        /**      * 判断realm是否为空      */      @Override      protected void assertRealmsConfigured() throws IllegalStateException {          this.definedRealms = this.getDefinedRealms();          if (CollectionUtils.isEmpty(this.definedRealms)) {              throw new ShiroException("值传递错误!");          }      }        public Map<String, Object> getDefinedRealms() {          return this.definedRealms;      }        public void setDefinedRealms(Map<String, Object> definedRealms) {          this.definedRealms = definedRealms;      }  } 
MyFormAuthenticationFilter类

package com.jusfoun.socialgrid.shiro;import java.io.PrintWriter;import java.util.Date;import javax.annotation.Resource;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.subject.Subject;import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;import org.apache.shiro.web.util.WebUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import com.fasterxml.jackson.annotation.JsonInclude.Include;import com.fasterxml.jackson.databind.ObjectMapper;import com.itmuch.core.constants.CodeConstant;import com.itmuch.core.util.ErrorMsgUtil;import com.itmuch.core.web.converter.Result;import com.jusfoun.socialgrid.admin.service.UserService;import com.jusfoun.socialgrid.util.common.IPUtil;public class MyFormAuthenticationFilter extends FormAuthenticationFilter {    private static final Logger LOGGER = LoggerFactory.getLogger(MyFormAuthenticationFilter.class);    public static final String DEFAULT_CAPTCHA_PARAM = "captcha"; private String captchaParam = DEFAULT_CAPTCHA_PARAM; public String getCaptchaParam() { return captchaParam; } protected String getCaptcha(ServletRequest request) { return WebUtils.getCleanParam(request, getCaptchaParam()); }    @Resource    private UserService userService;    @Override    protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception {        String principal = (String) subject.getPrincipal();        com.jusfoun.socialgrid.admin.domain.User currUser = this.userService.selectByUsername(principal);        if (currUser != null) {            // 最后一次登陆ip 与时间等等            String ip = IPUtil.getIpAddr((HttpServletRequest) request);            LOGGER.info("用户:{}登陆成功, IP:{}, 当前时间:{}.", currUser.getUsername(), ip, new Date());        }        return super.onLoginSuccess(token, subject, request, response);    }    /**     * 适应ajax情况下用户访问不允许访问的页面时的情况     * 参考: http://my.oschina.net/WMSstudio/blog/162594     * 参考: http://ketayao.com/view/9     * 参考: http://blog.csdn.net/shadowsick/article/details/39021265     */    @Override    protected boolean onAccessDenied(ServletRequest req, ServletResponse response) throws Exception {        HttpServletRequest request = (HttpServletRequest) req;        String accept = request.getHeader("accept");        String header = request.getHeader("X-Requested-With");        // ajax 请求        if (((accept != null) && (accept.indexOf("application/json") > -1)) || ((header != null) && (header.indexOf("XMLHttpRequest") > -1))) {            if (!this.isLoginRequest(req, response)) {                Result result = ErrorMsgUtil.error("用户未登录", "用户未登录, 或用户登录已超时, 请重新登录", CodeConstant.UNKNOW_ERROR_CODE);                ObjectMapper om = new ObjectMapper();                om.setSerializationInclusion(Include.NON_NULL);                String writeValueAsString = om.writeValueAsString(result);                response.setContentType("text/json; charset=UTF-8");                response.setCharacterEncoding("UTF-8");                PrintWriter out = response.getWriter();                out.println(writeValueAsString);                out.flush();                out.close();                return false;            } else {                return true;            }        } else {            return super.onAccessDenied(request, response);        }    }}

ShiroDbRealm类,第一个realm用于用户名密码登陆;这里变态的要求三个用户表,用时按照自己的需求修改即可

package com.jusfoun.socialgrid.shiro;import java.util.List;import java.util.Set;import javax.annotation.Resource;import org.apache.commons.collections.CollectionUtils;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo;import org.apache.shiro.cache.Cache;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.session.Session;import org.apache.shiro.subject.PrincipalCollection;import org.apache.shiro.subject.SimplePrincipalCollection;import org.apache.shiro.subject.Subject;import org.apache.shiro.util.ByteSource;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import com.itmuch.core.constants.SessionConstants;import com.itmuch.core.util.SubjectUtil;import com.jusfoun.socialgrid.admin.domain.CommissionUser;import com.jusfoun.socialgrid.admin.domain.CompanyUser;import com.jusfoun.socialgrid.admin.domain.User;import com.jusfoun.socialgrid.admin.persistence.CommissionUserMapper;import com.jusfoun.socialgrid.admin.persistence.CompanyUserMapper;import com.jusfoun.socialgrid.admin.service.RoleService;import com.jusfoun.socialgrid.admin.service.UserService;import com.jusfoun.socialgrid.gridManager.domain.GridManager;import com.jusfoun.socialgrid.gridManager.persistence.GridManagerMapper;public class ShiroDbRealm extends AuthorizingRealm {    @Resource    private UserService userService;    @Resource    private RoleService roleService;    @Autowired    public GridManagerMapper gridMp;    @Autowired    public CommissionUserMapper commMp;    @Autowired    public CompanyUserMapper comUserMp;        private static final Logger LOGGER = LoggerFactory.getLogger(ShiroDbRealm.class);    /**     * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用.     */    @Override    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {        SimpleAuthorizationInfo auth = new SimpleAuthorizationInfo();        // 1. 通过用户id,查询用户具有的角色(查询sys_admin_role)        Long id = SubjectUtil.getUser().getId();        // 如果是超级管理员, 则拥有所有权限, 不受角色约束        List<String> permissions = null;        if (1L == id) {            permissions = this.userService.selectAllPermissions();        }        // 并非超管        else {            List<Long> roleIds = this.userService.selectRoleIdListByUserId(id);            if ((roleIds != null) && !roleIds.isEmpty()) {                // 2. 通过角色id, 查询角色具有的权限                permissions = this.userService.selectPermissionsByRoleIds(roleIds);            }        }        if ((permissions != null) && !permissions.isEmpty()) {            auth.addStringPermissions(permissions);            return auth;        }        return null;    }    /**     * 认证回调函数,登录时调用.     */    @Override    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;        String userName = token.getUsername();        LOGGER.info("用户:{}尝试登陆.", userName);        String roleId = (String)SecurityUtils.getSubject().getSession().getAttribute("role_id");        User user = null;        if("1".equals(roleId)){        user = this.userService.selectByUsername(userName);        }else if("2".equals(roleId)){        //委办局人员登录        List<CommissionUser> list = commMp.selectCommByName(userName);        if(list!=null&&list.size()!=0){        CommissionUser commUser = list.get(0);        user = new User();        user.setUsername(commUser.getUsername());        user.setMobile(commUser.getMobile());        user.setId(commUser.getId());        user.setPassword(commUser.getPassword());        user.setSalt(commUser.getSalt());        }        }else if("3".equals(roleId)||"4".equals(roleId)){        //网格长和网格员登录        List<GridManager> list = gridMp.selectGridMgrByName(userName);        if(list!=null&&list.size()!=0){        GridManager gridMgr = list.get(0);        user = new User();        user.setUsername(gridMgr.getUsername());        user.setMobile(gridMgr.getMobile());        user.setId(gridMgr.getId());        user.setPassword(gridMgr.getPassword());        user.setSalt(gridMgr.getSalt());        }        }else if("5".equals(roleId)){        //企业用户登录        CompanyUser comUser = comUserMp.selectByUsername(userName);        if(comUser!=null){        user = new User();        user.setUsername(comUser.getUsername());        user.setMobile(comUser.getMobile());        user.setId(comUser.getId());        user.setPassword(comUser.getPassword());        user.setSalt(comUser.getSalt());        }        }//        User user = this.userService.selectByUsername(username);        if (user != null) {            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(userName, user.getPassword(),ByteSource.Util.bytes(user.getSalt()),this.getName());            com.itmuch.core.util.User currUser = new com.itmuch.core.util.User();            currUser.setUsername(user.getUsername());            currUser.setMobile(user.getMobile());            currUser.setId(user.getId());            this.setSession(SessionConstants.USER, currUser);            return info;        } else {            return null;        }    }    /**     * 设置session     * @param key key     * @param value value     */    private void setSession(Object key, Object value) {        Subject currentUser = SecurityUtils.getSubject();        if (null != currentUser) {            Session session = currentUser.getSession();            if (null != session) {                session.setAttribute(key, value);            }        }    }    /**     * 参考文档: http://www.tuicool.com/articles/rEvqym     * 参考文档: http://sishuok.com/forum/blogPost/list/7461.html     * 参考文档: http://m.blog.csdn.net/blog/LHacker/19340757     */    public void clearCache() {        Subject subject = SecurityUtils.getSubject();        super.clearCachedAuthorizationInfo(subject.getPrincipals());    }    /**     * 通过身份信息, 清空该用户的权限缓存     * 参考: http://m.blog.csdn.net/blog/LHacker/19340757     * @param principle 身份信息     */    public void clearAuthorizationCacheByPrinciple(String principle) {        String cacheName = this.getAuthorizationCacheName();        Cache<Object, Object> cache = this.getCacheManager().getCache(cacheName);        Set<Object> keys = cache.keys();        if (CollectionUtils.isNotEmpty(keys)) {            for (Object key : keys) {                SimplePrincipalCollection spc = (SimplePrincipalCollection) key;                if (principle.equals(spc.toString())) {                    cache.remove(key);                    break;                }            }        }    }}

ShiroVertifyRealm类

package com.jusfoun.socialgrid.shiro;import java.util.List;import java.util.Set;import javax.annotation.Resource;import org.apache.commons.collections.CollectionUtils;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.IncorrectCredentialsException;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo;import org.apache.shiro.cache.Cache;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.session.Session;import org.apache.shiro.subject.PrincipalCollection;import org.apache.shiro.subject.SimplePrincipalCollection;import org.apache.shiro.subject.Subject;import org.apache.shiro.util.ByteSource;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import com.itmuch.core.constants.SessionConstants;import com.itmuch.core.util.SubjectUtil;import com.jusfoun.socialgrid.admin.domain.CommissionUser;import com.jusfoun.socialgrid.admin.domain.User;import com.jusfoun.socialgrid.admin.persistence.CommissionUserMapper;import com.jusfoun.socialgrid.admin.service.RoleService;import com.jusfoun.socialgrid.admin.service.UserService;import com.jusfoun.socialgrid.gridManager.domain.GridManager;import com.jusfoun.socialgrid.gridManager.persistence.GridManagerMapper;public class ShiroVertifyRealm  extends AuthorizingRealm{final static Logger LOGGER = LoggerFactory.getLogger(ShiroVertifyRealm.class);  @Resource    private UserService userService;    @Resource    private RoleService roleService;    @Autowired    public GridManagerMapper gridMp;    @Autowired    public CommissionUserMapper commMp;@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { SimpleAuthorizationInfo auth = new SimpleAuthorizationInfo();        // 1. 通过用户id,查询用户具有的角色(查询sys_admin_role)        Long id = SubjectUtil.getUser().getId();        // 如果是超级管理员, 则拥有所有权限, 不受角色约束        List<String> permissions = null;        if (1L == id) {            permissions = this.userService.selectAllPermissions();        }        // 并非超管        else {            List<Long> roleIds = this.userService.selectRoleIdListByUserId(id);            if ((roleIds != null) && !roleIds.isEmpty()) {                // 2. 通过角色id, 查询角色具有的权限                permissions = this.userService.selectPermissionsByRoleIds(roleIds);            }        }        if ((permissions != null) && !permissions.isEmpty()) {            auth.addStringPermissions(permissions);            return auth;        }        return null;}@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {UsernamePasswordCaptchaToken token = (UsernamePasswordCaptchaToken)authenticationToken;String userName = token.getUsername();        LOGGER.info("用户:{}尝试登陆.", userName);        String roleId = (String)SecurityUtils.getSubject().getSession().getAttribute("role_id");     // 增加判断验证码逻辑        String captcha = token.getCaptcha();        String verCode = (String)SecurityUtils.getSubject().getSession().getAttribute("loginCode");        if (null == captcha || !captcha.equals(verCode)) {throw new CaptchaException("验证码错误");}        User user = null;        if("1".equals(roleId)){        user = this.userService.selectByUsername(userName);        }else if("2".equals(roleId)){        //委办局人员登录        List<CommissionUser> list = commMp.selectCommByName(userName);        if(list!=null&&list.size()!=0){        CommissionUser commUser = list.get(0);        user = new User();        user.setUsername(commUser.getUsername());        user.setMobile(commUser.getMobile());        user.setId(commUser.getId());        user.setPassword(commUser.getPassword());        user.setSalt(commUser.getSalt());        }        }else if("3".equals(roleId)||"4".equals(roleId)){        //网格长和网格员登录        List<GridManager> list = gridMp.selectGridMgrByName(userName);        if(list!=null&&list.size()!=0){        GridManager gridMgr = list.get(0);        user = new User();        user.setUsername(gridMgr.getUsername());        user.setMobile(gridMgr.getMobile());        user.setId(gridMgr.getId());        user.setPassword(gridMgr.getPassword());        user.setSalt(gridMgr.getSalt());        }        }        //        User user = this.userService.selectByUsername(userName);        if (user != null) {            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(userName, user.getPassword(), ByteSource.Util.bytes(user.getSalt()),                    this.getName());            com.itmuch.core.util.User currUser = new com.itmuch.core.util.User();            currUser.setUsername(user.getUsername());            currUser.setMobile(user.getMobile());            currUser.setId(user.getId());            this.setSession(SessionConstants.USER, currUser);            return info;        } else {            return null;        }} /**     * 设置session     * @param key key     * @param value value     */    private void setSession(Object key, Object value) {        Subject currentUser = SecurityUtils.getSubject();        if (null != currentUser) {            Session session = currentUser.getSession();            if (null != session) {                session.setAttribute(key, value);            }        }    }    /**     * 参考文档: http://www.tuicool.com/articles/rEvqym     * 参考文档: http://sishuok.com/forum/blogPost/list/7461.html     * 参考文档: http://m.blog.csdn.net/blog/LHacker/19340757     */    public void clearCache() {        Subject subject = SecurityUtils.getSubject();        super.clearCachedAuthorizationInfo(subject.getPrincipals());    }    /**     * 通过身份信息, 清空该用户的权限缓存     * 参考: http://m.blog.csdn.net/blog/LHacker/19340757     * @param principle 身份信息     */    public void clearAuthorizationCacheByPrinciple(String principle) {        String cacheName = this.getAuthorizationCacheName();        Cache<Object, Object> cache = this.getCacheManager().getCache(cacheName);        Set<Object> keys = cache.keys();        if (CollectionUtils.isNotEmpty(keys)) {            for (Object key : keys) {                SimplePrincipalCollection spc = (SimplePrincipalCollection) key;                if (principle.equals(spc.toString())) {                    cache.remove(key);                    break;                }            }        }    }//自定义认证授权,替代默认的用户名密码验证@Overrideprotected void assertCredentialsMatch(AuthenticationToken token, AuthenticationInfo info)throws AuthenticationException {UsernamePasswordCaptchaToken captchaToken = (UsernamePasswordCaptchaToken)token;if(!captchaToken.getUsername().equals(info.getPrincipals().toString())){String msg = "Submitted credentials for token [" + token + "] did not match the expected credentials.";            throw new IncorrectCredentialsException(msg);}}}
UsernamePasswordCaptchaToken类

package com.jusfoun.socialgrid.shiro;import org.apache.shiro.authc.UsernamePasswordToken;public class UsernamePasswordCaptchaToken  extends UsernamePasswordToken{/** *  */private static final long serialVersionUID = 1L;/** * 验证码 */private String captcha; /**      * 用户名      */      private String username;        /**      * 密码, in char[] format      */      private char[] password;      /**      * 主机名称或ip      */      private String host;       /**      * 是否记住我      * 默认值:<code>false</code>      */      private boolean rememberMe = false;            /**     * 构造方法     * @param captcha验证码     * @param username用户名     */    public UsernamePasswordCaptchaToken(String username,String captcha) {super();this.captcha = captcha;this.username = username;}public String getCaptcha() {return captcha;}public void setCaptcha(String captcha) {this.captcha = captcha;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public char[] getPassword() {return password;}public void setPassword(char[] password) {this.password = password;}public void setRememberMe(boolean rememberMe) {this.rememberMe = rememberMe;}public void setHost(String host) {this.host = host;}@Overridepublic Object getPrincipal() {return getUsername();}@Overridepublic Object getCredentials() {return getPassword();}@Overridepublic boolean isRememberMe() {// TODO Auto-generated method stubreturn rememberMe;}@Overridepublic String getHost() {return host;}}





0 0
原创粉丝点击