shiro实现权限管理时遇到的坑
2018-01-25 10:45
246 查看
最近在一个项目中应用到了shiro框架实现权限管理,也是一边在网上查资料一边实现,对shiro的细节的李姐可能不够深入,所以都在项目中遇到了挺多麻烦。现在说一下我遇到的情况
//1. 把 AuthenticationToken 转换为 UsernamePasswordToken
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
//2. 从 UsernamePasswordToken 中来获取 username
String username = upToken.getUsername();
System.out.println("doGetAuthenticationInfo---username:"+username);
//3. 调用数据库的方法, 从数据库中查询 username 对应的用户记录
System.out.println("2222");
TManagerUser managerUser = sysUserManagerService.queryUserByLoginName(username);
System.out.println("3333");
System.out.println("doGetAuthenticationInfo---managerUser:"+JSONObject.toJSON(managerUser));
//4. 若用户不存在, 则可以抛出 UnknownAccountException 异常
System.out.println("1111");
if(managerUser==null){
throw new UnknownAccountException("用户不存在!");
}else {
//5. 根据用户信息的情况, 决定是否需要抛出其他的 AuthenticationException 异常.
if("locked".equals(managerUser.getUserStatus())){
throw new LockedAccountException("用户被锁定");
}
//6. 根据用户的情况, 来构建 AuthenticationInfo 对象并返回. 通常使用的实现类为: SimpleAuthenticationInfo
//以下信息是从数据库中获取的.
//1). principal: 认证的实体信息. 可以是 username, 也可以是数据表对应的用户的实体类对象.
Object principal = username;
//2). credentials: 密码.
Object credentials = managerUser.getUserPassword();
System.out.println("credentials:"+credentials);
//3). realmName: 当前 realm 对象的 name. 调用父类的 getName() 方法即可
String realmName = getName();
//4). 盐值. 将用户名作为盐
ByteSource credentialsSalt = ByteSource.Util.bytes(username);
SimpleAuthenticationInfo info = null; //new SimpleAuthenticationInfo(principal, credentials, realmName);
info = new SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName);
System.out.println("info:"+JSONObject.toJSON(info));
return info;
}上面是我配置的自定义的realm。运行发现能够进入到自定义的realm,但只能打印出“2222”及以上的部分,queryUserByLoginName方法以下的都无法运行的到,但很奇怪的是后台还不报错,还可以继续运行其他相关程序。
在网上查找了很长时间,发现网上有很多说是service未能正常引入的问题。所以我就在service方法中添加了try-catch代码,后来发现他会抓取到空指针异常。如下图:
接下来就根据这个提示解决问题。该项目是由ssm框架搭建的,所以结合网上的提示,想到是不是因为service没有在realm之前引入。结果在spring的相关配置文件引入相关配置还是没有实现(本人小白,刚工作不久,对spring理解及应用不是很熟悉,希望有大神指点一二)。最后通过一个很笨的方法实现了,就是替换service的queryUserByLoginName方法。将其改为下面的代码实现即可
SqlSession openSession = sqlSessionFactory.openSession();
TManagerUserMapper userMapper = openSession.getMapper(TManagerUserMapper.class);
TManagerUserExample example = new TManagerUserExample();
example.createCriteria().andUserLoginNameEqualTo(username);
List<TManagerUser> managerUsers = userMapper.selectByExample(example);如果网友有更好的方式,麻烦指点一二
//1. 把 AuthenticationToken 转换为 UsernamePasswordToken
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
//2. 从 UsernamePasswordToken 中来获取 username
String username = upToken.getUsername();
System.out.println("doGetAuthenticationInfo---username:"+username);
//3. 调用数据库的方法, 从数据库中查询 username 对应的用户记录
System.out.println("2222");
TManagerUser managerUser = sysUserManagerService.queryUserByLoginName(username);
System.out.println("3333");
System.out.println("doGetAuthenticationInfo---managerUser:"+JSONObject.toJSON(managerUser));
//4. 若用户不存在, 则可以抛出 UnknownAccountException 异常
System.out.println("1111");
if(managerUser==null){
throw new UnknownAccountException("用户不存在!");
}else {
//5. 根据用户信息的情况, 决定是否需要抛出其他的 AuthenticationException 异常.
if("locked".equals(managerUser.getUserStatus())){
throw new LockedAccountException("用户被锁定");
}
//6. 根据用户的情况, 来构建 AuthenticationInfo 对象并返回. 通常使用的实现类为: SimpleAuthenticationInfo
//以下信息是从数据库中获取的.
//1). principal: 认证的实体信息. 可以是 username, 也可以是数据表对应的用户的实体类对象.
Object principal = username;
//2). credentials: 密码.
Object credentials = managerUser.getUserPassword();
System.out.println("credentials:"+credentials);
//3). realmName: 当前 realm 对象的 name. 调用父类的 getName() 方法即可
String realmName = getName();
//4). 盐值. 将用户名作为盐
ByteSource credentialsSalt = ByteSource.Util.bytes(username);
SimpleAuthenticationInfo info = null; //new SimpleAuthenticationInfo(principal, credentials, realmName);
info = new SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName);
System.out.println("info:"+JSONObject.toJSON(info));
return info;
}上面是我配置的自定义的realm。运行发现能够进入到自定义的realm,但只能打印出“2222”及以上的部分,queryUserByLoginName方法以下的都无法运行的到,但很奇怪的是后台还不报错,还可以继续运行其他相关程序。
在网上查找了很长时间,发现网上有很多说是service未能正常引入的问题。所以我就在service方法中添加了try-catch代码,后来发现他会抓取到空指针异常。如下图:
接下来就根据这个提示解决问题。该项目是由ssm框架搭建的,所以结合网上的提示,想到是不是因为service没有在realm之前引入。结果在spring的相关配置文件引入相关配置还是没有实现(本人小白,刚工作不久,对spring理解及应用不是很熟悉,希望有大神指点一二)。最后通过一个很笨的方法实现了,就是替换service的queryUserByLoginName方法。将其改为下面的代码实现即可
SqlSession openSession = sqlSessionFactory.openSession();
TManagerUserMapper userMapper = openSession.getMapper(TManagerUserMapper.class);
TManagerUserExample example = new TManagerUserExample();
example.createCriteria().andUserLoginNameEqualTo(username);
List<TManagerUser> managerUsers = userMapper.selectByExample(example);如果网友有更好的方式,麻烦指点一二
相关文章推荐
- springmvc+shiro+maven 实现登录认证与权限授权管理
- 【权限管理】基于shiro的权限管理开发实现
- shiro实现APP、web统一登录认证和权限管理
- C/S,APP架构中,通过shiro重写session,用shiro实现权限管理?
- shiro实现APP、web统一登录认证和权限管理
- shiro实现APP、web统一登录认证和权限管理
- spring boot mybatis 整合shiro简单实现登陆权限管理
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例(转)
- 【权限管理】基于shiro的权限管理开发实现
- 框架 day54 BOS项目练习(权限/角色/用户管理(CRUD),基于数据库实现动态授权,ehcache缓存权限,shiro标签,菜单权限展示)
- springmvc+shiro+maven 实现登录认证与权限授权管理
- shiro实现APP、web统一登录认证和权限管理
- Shiro 整合SpringMVC 并实现权限管理,登录和注销
- Shiro 整合SpringMVC 并且实现权限管理,登录和注销
- Spring Boot + Spring Cloud 实现权限管理系统 后端篇(十一):集成 Shiro 框架
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- shiro实现APP保持登录状态,以及web统一登录认证和权限管理,会话保持在web和APP之间。
- 本文主要介绍使用SpringBoot与shiro实现基于数据库的细粒度动态权限管理系统实例。
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例