shiro-異常處理


@Override
    public int saveObject(SysUser entity, Integer[] roleIds) {
        // 1.參數(shù)合法驗(yàn)證
        if (entity == null)
            throw new IllegalArgumentException("保存對應(yīng)不能為空");
        if (StringUtils.isEmpty(entity.getUsername()))
            throw new ServiceException("用戶名不能為空");
        if (StringUtils.isEmpty(entity.getPassword()))
            throw new ServiceException("密碼不能為空");
        if (roleIds == null || roleIds.length == 0)
            throw new IllegalArgumentException("必須為用戶分配角色");
        // 2.保存數(shù)據(jù)
        // 2.1 創(chuàng)建一個鹽值(用于輔助加密,保證密碼更加安全的一種手段)
        String salt = UUID.randomUUID().toString();
        System.out.println(salt);
        String pwd = entity.getPassword();
        // 2.3 對密碼進(jìn)行加密,加密算法md5
        SimpleHash sh = // 這個api屬于shiro框架,后續(xù)需要引入shiro依賴
                new SimpleHash("MD5", // algorithmName 表示加密算法
                        pwd, // source 為要加密的對象
                        salt);// salt 加密鹽值
        entity.setPassword(sh.toHex());
        System.out.println(salt);
        entity.setSalt(salt);
        // 2.4設(shè)置對象其它屬性默認(rèn)值
        entity.setCreatedTime(new Date());
        entity.setModifiedTime(new Date());
        // 2.5保存用戶自身信息
        int rows = sysUserDao.insertObject(entity);
        // 2.6保存用戶與角色的關(guān)系數(shù)據(jù)
        sysUserRoleDao.insertObjects(entity.getId(), roleIds);
        // 3.返回結(jié)果
        return rows;
    }

方案一:只處理一種異常昧诱,其他異常拋出

@Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("==doGetAuthenticationInfo===");
        // 獲取用戶身份信息(如用戶名)
        String userName = (String) token.getPrincipal();
        // 1.從token對象獲取用戶名(用戶輸入的)
        // 基于用戶名訪問數(shù)據(jù)庫獲取用戶信息
        SysUser user = sysUserDao.findUserByUserName(userName);
        // 對用戶信息進(jìn)行驗(yàn)證
        // 2.基于用戶名查詢用戶信息并進(jìn)行身份校驗(yàn)
        if (user == null)// 驗(yàn)證用戶名是否為空
            throw new AuthenticationException("此用戶不存在");
        if (user.getValid() == 0)// 驗(yàn)證用戶是否被禁用
            throw new AuthenticationException("此用戶已被禁用");
        // 3.對用戶信息進(jìn)行封裝(基于業(yè)務(wù)封裝用戶數(shù)據(jù))
        ByteSource credentialsSalt = ByteSource.Util.bytes(user.getSalt());
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, // principal
                                                                            // 用戶->身份
                user.getPassword(), // hashedCredentials已加密的憑證
                credentialsSalt, // credentialsSalt 密碼加密時使用的鹽
                this.getName());// realmName 當(dāng)前方法所在類的名字
        return info;// 返回給誰?認(rèn)證管理器
    }
@ExceptionHandler(IncorrectCredentialsException.class)
    @ResponseBody
    public JsonResult doHandleShiroException(IncorrectCredentialsException e){
        JsonResult result=new JsonResult();
        result.setState(0);
        result.setMessage("密碼不正確");
        return result;
        
    }

方案二:處理多種異常心褐,ShiroException作為異常的父類

@Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("==doGetAuthenticationInfo===");
        // 獲取用戶身份信息(如用戶名)
        String userName = (String) token.getPrincipal();
        // 1.從token對象獲取用戶名(用戶輸入的)
        // 基于用戶名訪問數(shù)據(jù)庫獲取用戶信息
        SysUser user = sysUserDao.findUserByUserName(userName);
        // 對用戶信息進(jìn)行驗(yàn)證
        // 2.基于用戶名查詢用戶信息并進(jìn)行身份校驗(yàn)
        if (user == null)// 驗(yàn)證用戶名是否為空
            throw new UnknownAccountException();
        if (user.getValid() == 0)// 驗(yàn)證用戶是否被禁用
            throw new LockedAccountException();
        // 3.對用戶信息進(jìn)行封裝(基于業(yè)務(wù)封裝用戶數(shù)據(jù))
        ByteSource credentialsSalt = ByteSource.Util.bytes(user.getSalt());
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, // principal
                                                                            // 用戶->身份
                user.getPassword(), // hashedCredentials已加密的憑證
                credentialsSalt, // credentialsSalt 密碼加密時使用的鹽
                this.getName());// realmName 當(dāng)前方法所在類的名字
        return info;// 返回給誰?認(rèn)證管理器
    }

@ExceptionHandler(ShiroException.class)
    @ResponseBody
    public JsonResult doHandleShiroException(ShiroException e){
        JsonResult result=new JsonResult();
        result.setState(0);
        if(e instanceof IncorrectCredentialsException)
        result.setMessage("密碼不正確");
        else if(e instanceof UnknownAccountException)
            result.setMessage("此賬戶不存在");
        else if(e instanceof LockedAccountException)
            result.setMessage("賬戶已被禁用");
        return result;
        
    }

方案二:完整代碼

package com.jt.service.realm;


import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jt.dao.SysUserDao;
import com.jt.entity.SysUser;

/**
 * 此對象中要完成用戶認(rèn)證信息,授權(quán)信息的獲取和封裝等業(yè)務(wù)操作
 * 
 * @author Administrator
 *
 */
@Service
public class ShiroUserRealm extends AuthorizingRealm {
    @Autowired
    private SysUserDao sysUserDao;

    /**
     * 設(shè)置憑證(Credentials)匹配器
     * 指定加密算法和加密次數(shù)榛做,默認(rèn)加密一次
     */
    @Override
    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
        HashedCredentialsMatcher cMatcher = new HashedCredentialsMatcher("MD5");
        // 設(shè)置加密的次數(shù)(這個次數(shù)應(yīng)該與保存密碼時那個加密次數(shù)一致)
        // cMatcher.setHashIterations(5);
        super.setCredentialsMatcher(cMatcher);
    }

    /**
     * 負(fù)責(zé)用戶認(rèn)證信息的獲取及封裝
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("==doGetAuthenticationInfo===");
        // 獲取用戶身份信息(如用戶名)
        String userName = (String) token.getPrincipal();
        // 1.從token對象獲取用戶名(用戶輸入的)
        // 基于用戶名訪問數(shù)據(jù)庫獲取用戶信息
        SysUser user = sysUserDao.findUserByUserName(userName);
        // 對用戶信息進(jìn)行驗(yàn)證
        // 2.基于用戶名查詢用戶信息并進(jìn)行身份校驗(yàn)
        if (user == null)// 驗(yàn)證用戶名是否為空
            throw new UnknownAccountException();
        if (user.getValid() == 0)// 驗(yàn)證用戶是否被禁用
            throw new LockedAccountException();
        // 3.對用戶信息進(jìn)行封裝(基于業(yè)務(wù)封裝用戶數(shù)據(jù))
        ByteSource credentialsSalt = ByteSource.Util.bytes(user.getSalt());
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, // principal
                                                                            // 用戶->身份
                user.getPassword(), // hashedCredentials已加密的憑證
                credentialsSalt, // credentialsSalt 密碼加密時使用的鹽
                this.getName());// realmName 當(dāng)前方法所在類的名字
        return info;// 返回給誰?認(rèn)證管理器
    }

    /**
     * 負(fù)責(zé)用戶授權(quán)信息的獲取及封裝
     * */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(
        PrincipalCollection principals) {
            return null;
        
    }
}
package com.jt.common.web;

import java.util.logging.Logger;

import org.apache.shiro.ShiroException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import com.jt.common.vo.JsonResult;
@ControllerAdvice
public class GlobalExceptionHandler {
    /**
     * 處理運(yùn)行時異常
     * @return
     */
    //jdk中自帶的日志api
    private Logger log=Logger.getLogger(GlobalExceptionHandler.class.getName());
    @ExceptionHandler(RuntimeException.class)
    @ResponseBody
    public JsonResult doHandleRuntimeException(RuntimeException e){
        /**
         * 封裝異常信息
         */
        //e.printStackTrace();
        log.info(e.getMessage());
        return new JsonResult(e);
    }
    @ExceptionHandler(ShiroException.class)
    @ResponseBody
    public JsonResult doHandleShiroException(ShiroException e){
        JsonResult result=new JsonResult();
        result.setState(0);
        if(e instanceof IncorrectCredentialsException)
        result.setMessage("密碼不正確");
        else if(e instanceof UnknownAccountException)
            result.setMessage("此賬戶不存在");
        else if(e instanceof LockedAccountException)
            result.setMessage("賬戶已被禁用");
        return result;
        
    }
}
package com.jt.dao;
import java.util.List;

import org.apache.ibatis.annotations.Param;

import com.jt.common.vo.SysUserDeptResult;
import com.jt.entity.SysUser;


public interface SysUserDao {
    
    /**
     * 更新用戶信息
     * @param entity
     * @return
     */
    int updateObject(SysUser entity);
    /**
     * 根據(jù)用戶id查詢用戶以及用戶對應(yīng)的部門信息
     * @param id (用戶id)
     * @return
     */
    SysUserDeptResult findObjectById(Integer id);
    /**
     * 
     * @param deptId 部門id
     * @return
     */
    int getUserCountByDeptId(Integer deptId);
    
    /**
     * 根據(jù)用戶名查找用戶信息
     * @param username
     * @return
     */
     SysUser findUserByUserName(String username);
    
     /**
      * 負(fù)責(zé)將用戶信息寫入到數(shù)據(jù)庫
      * @param entity
      * @return
      */
     int insertObject(SysUser entity);
    
     /**
      * 賦值執(zhí)行禁用和啟用操作
      * @param id 要禁用或啟用的記錄id
      * @param valid 禁用或啟用的標(biāo)識
      * @return
      */
     int validById(@Param("id")Integer id,
                   @Param("valid")Integer valid,
                   @Param("modifiedUser") String modifiedUser);
    /**
     * 依據(jù)條件分頁查詢操作
     * @param username
     * @param startIndex
     * @param pageSize
     * @return
     */
     List<SysUserDeptResult> findPageObjects(
             @Param("username")String username,
             @Param("startIndex")Integer startIndex,
             @Param("pageSize")Integer pageSize);
     
     /**
      * 依據(jù)條件統(tǒng)計記錄總數(shù)
      * @param username
      * @return
      */
     int getRowCount(@Param("username")String username);

}


<select id="findUserByUserName" resultType="com.jt.entity.SysUser">
select *
from sys_users
where username=#{username}
</select>

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jt.dao.SysUserDao">

    <!-- 更新用戶自身信息 -->

    <update id="updateObject" parameterType="com.jt.entity.SysUser">
        update sys_users
        <set>
            <if test="username!=null and username!=''">
                username=#{username},
            </if>
            <if test="email!=null and email!=''">
                email=#{email},
            </if>
            <if test="mobile!=null and mobile!=''">
                mobile=#{mobile},
            </if>
            <if test="deptId!=null and deptId!=''">
                deptId=#{deptId},
            </if>
            <if test="modifiedUser!=null and modifiedUser!=''">
                modifiedUser=#{modifiedUser},
            </if>
            modifiedTime=now()
        </set>
        where id=#{id}
    </update>



    <select id="findObjectById" resultMap="sysUserResult">
        select *
        from sys_users
        where id=#{id}
    </select>

    <!-- 基于用戶名查詢當(dāng)前用戶對象 -->
    <select id="findUserByUserName" resultType="com.jt.entity.SysUser">
        select *
        from sys_users
        where username=#{username}
    </select>

    <insert id="insertObject" parameterType="com.jt.entity.SysUser"
        useGeneratedKeys="true" keyProperty="id">
        insert into sys_users
        (username,password,salt,email,mobile,valid,deptId,
        createdTime,modifiedTime,createdUser,modifiedUser)
        values
        (#{username},#{password},#{salt},
        #{email},#{mobile},#{valid},#{deptId},
        now(),now(),#{createdUser},#{modifiedUser}
        )
    </insert>

    <!-- 禁用或啟用用戶對象 -->
    <update id="validById">
        update sys_users
        set
        valid=#{valid},
        modifiedTime=now(),
        modifiedUser=#{modifiedUser}
        where id=#{id}
    </update>


    <resultMap id="sysUserResult" type="com.jt.common.vo.SysUserDeptResult">
        <!--直接量類型的屬性自動映射-->
        <!--關(guān)聯(lián)映射-->
        <association property="sysDept" column="deptId"
            select="com.jt.dao.SysDeptDao.findById" />
    </resultMap>
    <select id="getUserCountByDeptId" resultType="int">
        select count(*)
        from sys_users
        where deptId=#{deptId}
    </select> 
    <sql id="queryWhereId">
        <where>
            <if test="username!=null and username!=''">
                username like concat("%",#{username},"%")
            </if>
        </where>
    </sql>
    <select id="findPageObjects" resultMap="sysUserResult">
        select *
        from sys_users
        <include refid="queryWhereId" />
        limit #{startIndex},#{pageSize}
    </select>
    <select id="getRowCount" resultType="int">
        select count(*)
        from sys_users
        <include refid="queryWhereId" />
    </select>
</mapper>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子这弧,更是在濱河造成了極大的恐慌,老刑警劉巖虚汛,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件匾浪,死亡現(xiàn)場離奇詭異,居然都是意外死亡卷哩,警方通過查閱死者的電腦和手機(jī)蛋辈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來将谊,“玉大人冷溶,你說我怎么就攤上這事∽鹋ǎ” “怎么了逞频?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長栋齿。 經(jīng)常有香客問我苗胀,道長襟诸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任基协,我火速辦了婚禮歌亲,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘澜驮。我一直安慰自己陷揪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布杂穷。 她就那樣靜靜地躺著悍缠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪亭畜。 梳的紋絲不亂的頭發(fā)上扮休,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天,我揣著相機(jī)與錄音拴鸵,去河邊找鬼玷坠。 笑死,一個胖子當(dāng)著我的面吹牛劲藐,可吹牛的內(nèi)容都是我干的八堡。 我是一名探鬼主播,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼聘芜,長吁一口氣:“原來是場噩夢啊……” “哼兄渺!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起汰现,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤挂谍,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后瞎饲,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體口叙,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年嗅战,在試婚紗的時候發(fā)現(xiàn)自己被綠了妄田。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡驮捍,死狀恐怖疟呐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情东且,我是刑警寧澤启具,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站珊泳,受9級特大地震影響富纸,放射性物質(zhì)發(fā)生泄漏囤踩。R本人自食惡果不足惜旨椒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一晓褪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧综慎,春花似錦涣仿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至米罚,卻和暖如春钧汹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背录择。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工拔莱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人隘竭。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓塘秦,卻偏偏與公主長得像锅知,于是被迫代替她去往敵國和親氯材。 傳聞我的和親對象是個殘疾皇子刻帚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評論 2 355

推薦閱讀更多精彩內(nèi)容