shiro-异常处理


@Override
    public int saveObject(SysUser entity, Integer[] roleIds) {
        // 1.参数合法验证
        if (entity == null)
            throw new IllegalArgumentException("保存对应不能为空");
        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.保存数据
        // 2.1 创建一个盐值(用于辅助加密,保证密码更加安全的一种手段)
        String salt = UUID.randomUUID().toString();
        System.out.println(salt);
        String pwd = entity.getPassword();
        // 2.3 对密码进行加密,加密算法md5
        SimpleHash sh = // 这个api属于shiro框架,后续需要引入shiro依赖
                new SimpleHash("MD5", // algorithmName 表示加密算法
                        pwd, // source 为要加密的对象
                        salt);// salt 加密盐值
        entity.setPassword(sh.toHex());
        System.out.println(salt);
        entity.setSalt(salt);
        // 2.4设置对象其它属性默认值
        entity.setCreatedTime(new Date());
        entity.setModifiedTime(new Date());
        // 2.5保存用户自身信息
        int rows = sysUserDao.insertObject(entity);
        // 2.6保存用户与角色的关系数据
        sysUserRoleDao.insertObjects(entity.getId(), roleIds);
        // 3.返回结果
        return rows;
    }

方案一:只处理一种异常,其他异常抛出

@Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("==doGetAuthenticationInfo===");
        // 获取用户身份信息(如用户名)
        String userName = (String) token.getPrincipal();
        // 1.从token对象获取用户名(用户输入的)
        // 基于用户名访问数据库获取用户信息
        SysUser user = sysUserDao.findUserByUserName(userName);
        // 对用户信息进行验证
        // 2.基于用户名查询用户信息并进行身份校验
        if (user == null)// 验证用户名是否为空
            throw new AuthenticationException("此用户不存在");
        if (user.getValid() == 0)// 验证用户是否被禁用
            throw new AuthenticationException("此用户已被禁用");
        // 3.对用户信息进行封装(基于业务封装用户数据)
        ByteSource credentialsSalt = ByteSource.Util.bytes(user.getSalt());
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, // principal
                                                                            // 用户->身份
                user.getPassword(), // hashedCredentials已加密的凭证
                credentialsSalt, // credentialsSalt 密码加密时使用的盐
                this.getName());// realmName 当前方法所在类的名字
        return info;// 返回给谁?认证管理器
    }
@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对象获取用户名(用户输入的)
        // 基于用户名访问数据库获取用户信息
        SysUser user = sysUserDao.findUserByUserName(userName);
        // 对用户信息进行验证
        // 2.基于用户名查询用户信息并进行身份校验
        if (user == null)// 验证用户名是否为空
            throw new UnknownAccountException();
        if (user.getValid() == 0)// 验证用户是否被禁用
            throw new LockedAccountException();
        // 3.对用户信息进行封装(基于业务封装用户数据)
        ByteSource credentialsSalt = ByteSource.Util.bytes(user.getSalt());
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, // principal
                                                                            // 用户->身份
                user.getPassword(), // hashedCredentials已加密的凭证
                credentialsSalt, // credentialsSalt 密码加密时使用的盐
                this.getName());// realmName 当前方法所在类的名字
        return info;// 返回给谁?认证管理器
    }

@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;

/**
 * 此对象中要完成用户认证信息,授权信息的获取和封装等业务操作
 * 
 * @author Administrator
 *
 */
@Service
public class ShiroUserRealm extends AuthorizingRealm {
    @Autowired
    private SysUserDao sysUserDao;

    /**
     * 设置凭证(Credentials)匹配器
     * 指定加密算法和加密次数,默认加密一次
     */
    @Override
    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
        HashedCredentialsMatcher cMatcher = new HashedCredentialsMatcher("MD5");
        // 设置加密的次数(这个次数应该与保存密码时那个加密次数一致)
        // cMatcher.setHashIterations(5);
        super.setCredentialsMatcher(cMatcher);
    }

    /**
     * 负责用户认证信息的获取及封装
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("==doGetAuthenticationInfo===");
        // 获取用户身份信息(如用户名)
        String userName = (String) token.getPrincipal();
        // 1.从token对象获取用户名(用户输入的)
        // 基于用户名访问数据库获取用户信息
        SysUser user = sysUserDao.findUserByUserName(userName);
        // 对用户信息进行验证
        // 2.基于用户名查询用户信息并进行身份校验
        if (user == null)// 验证用户名是否为空
            throw new UnknownAccountException();
        if (user.getValid() == 0)// 验证用户是否被禁用
            throw new LockedAccountException();
        // 3.对用户信息进行封装(基于业务封装用户数据)
        ByteSource credentialsSalt = ByteSource.Util.bytes(user.getSalt());
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, // principal
                                                                            // 用户->身份
                user.getPassword(), // hashedCredentials已加密的凭证
                credentialsSalt, // credentialsSalt 密码加密时使用的盐
                this.getName());// realmName 当前方法所在类的名字
        return info;// 返回给谁?认证管理器
    }

    /**
     * 负责用户授权信息的获取及封装
     * */
    @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 {
    /**
     * 处理运行时异常
     * @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);
    /**
     * 根据用户id查询用户以及用户对应的部门信息
     * @param id (用户id)
     * @return
     */
    SysUserDeptResult findObjectById(Integer id);
    /**
     * 
     * @param deptId 部门id
     * @return
     */
    int getUserCountByDeptId(Integer deptId);
    
    /**
     * 根据用户名查找用户信息
     * @param username
     * @return
     */
     SysUser findUserByUserName(String username);
    
     /**
      * 负责将用户信息写入到数据库
      * @param entity
      * @return
      */
     int insertObject(SysUser entity);
    
     /**
      * 赋值执行禁用和启用操作
      * @param id 要禁用或启用的记录id
      * @param valid 禁用或启用的标识
      * @return
      */
     int validById(@Param("id")Integer id,
                   @Param("valid")Integer valid,
                   @Param("modifiedUser") String modifiedUser);
    /**
     * 依据条件分页查询操作
     * @param username
     * @param startIndex
     * @param pageSize
     * @return
     */
     List findPageObjects(
             @Param("username")String username,
             @Param("startIndex")Integer startIndex,
             @Param("pageSize")Integer pageSize);
     
     /**
      * 依据条件统计记录总数
      * @param username
      * @return
      */
     int getRowCount(@Param("username")String username);

}






    

    
        update sys_users
        
            
                username=#{username},
            
            
                email=#{email},
            
            
                mobile=#{mobile},
            
            
                deptId=#{deptId},
            
            
                modifiedUser=#{modifiedUser},
            
            modifiedTime=now()
        
        where id=#{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}
        )
    

    
    
        update sys_users
        set
        valid=#{valid},
        modifiedTime=now(),
        modifiedUser=#{modifiedUser}
        where id=#{id}
    


    
        
        
        
    
     
    
        
            
                username like concat("%",#{username},"%")
            
        
    
    
    

你可能感兴趣的:(shiro-异常处理)