@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},"%")