三. 自定义Realm 获取数据库里真实的认证和授权数据
采用 Servlet实现RBAC权限管理(二) 的代码结构,
数据库仍然是 rbac 数据库, 没有看到的读者,一定要先看这一章节的内容。
dao,pojo,utils 包,还有数据库 jdbc.properties,数据库内容 均使用以前的内容。
三.一 创建自定义的Realm
MyDBRealm ,继承 AuthorizingRealm 抽象类
public class MyDBRealm extends AuthorizingRealm{ private UserDao userDao=new UserDaoImpl(); private PrivilegeDao privilegeDao=new PrivilegeDaoImpl(); private RoleDao roleDao=new RoleDaoImpl(); @Override public String getName() { return "MyDBRealm"; } //授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection paramPrincipalCollection) { return null; } //认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken paramAuthenticationToken) throws AuthenticationException { return null; } }
三.二 编写配置文件 customerdb.ini
[main] #配置自定义realm myRealm=com.yjl.customer.MyDBRealm #注入自定义的realm securityManager.realm=$myRealm
三.三 在MyDBRealm 编写认证操作
//认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken paramAuthenticationToken) throws AuthenticationException { System.out.println("进入认证"); String code=(String)paramAuthenticationToken.getPrincipal(); //根据用户名,去查询相应的数据 User user=userDao.getInfoByNameAndValue("select * from user","code", code); if(user==null){ //没有查询出来 return null; } SimpleAuthenticationInfo simpleAuthenticationInfo= new SimpleAuthenticationInfo(user,user.getPassword(),getName()); return simpleAuthenticationInfo; }
注意,这个时候身份并不是以前的用户名,而是整个查询出来的对象, 把数据库中完整的对象当成一个身份,传入进去。 认证通过后,获取时,获取的则是整个完整的对象。
三.四 在MyDBRealm 中编写授权操作
//授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection paramPrincipalCollection) { System.out.println("进入授权"); User user=(User)paramPrincipalCollection.getPrimaryPrincipal(); System.out.println("输出登录的用户编号:"+user.getCode()); //查询权限 String priSql="select a.* from privilege a where a.id in ( select rp.pid from user_role ur " + " left join role_privilege rp " +"on ur.rid=rp.rid where ur.uid=? ) and a.type=?"; List<Privilege> privilegeList= privilegeDao.findInfosBySql(priSql,user.getId(),2); SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo(); for(Privilege pri:privilegeList){ if(pri.getPercode()!=null&&!("".equals(pri.getPercode()))){ simpleAuthorizationInfo.addStringPermission(pri.getPercode()); } } //查询角色 String roleSql="select a.* from role a left join user_role b on a.id=b.rid " +" where b.uid=?"; List<Role> roleList=roleDao.findInfosBySql(roleSql, user.getId()); for(Role role:roleList){ simpleAuthorizationInfo.addRole(role.getId()+""); } return simpleAuthorizationInfo; }
三.五 编写测试 MyRealmDBTest
package com.yjl.customer; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.Factory; import com.yjl.pojo.User; import com.yjl.utils.MD5Utils; public class MyRealmDBTest { public static void main(String[] args) throws Exception{ //1. 创建factory Factory<SecurityManager> factory=new IniSecurityManagerFactory("classpath:customerdb.ini"); //2 获取实例 SecurityManager securityManager=factory.getInstance(); //3 设置 SecurityUtils.setSecurityManager(securityManager); //4. 获取 Subject Subject subject=SecurityUtils.getSubject(); //5. 设置token UsernamePasswordToken token=new UsernamePasswordToken("admin",MD5Utils.md5("1234")); //6. 执行登录操作 try{ subject.login(token); User user=(User)subject.getPrincipal(); //可以将这个user 设置到session 里面 System.out.println(user.toString()+"登录成功"); //admin 是管理员 boolean flag=subject.hasRole("1"); System.out.println("是否拥有角色 管理员:"+flag); //关于角色验证的那些方法,都可以使用 flag=subject.hasRole("2"); System.out.println("是否拥有角色 经理:"+flag); //admin有删除权限,没有添加权限 flag=subject.isPermitted("dept:add"); System.out.println("是否拥有权限 dept:add "+flag); flag=subject.isPermitted("dept:delete"); System.out.println("是否拥有权限 dept:delete "+flag); }catch(Exception e){ e.printStackTrace(); System.out.println("用户名或者密码不正确"); } } }
控制台打印输出:
提示警告 SSL, 只要不使用 ssl 即可。
只需要改变数据库的 url 配置, 添加上 useSSL=false 即可。(在jdbc.properties 文件里面)
url=jdbc:mysql://localhost:3306/rbac?characterEncoding=UTF-8&useSSL=false
这样就不会有 ssl 警告了。
本章节代码链接为:
链接:https://pan.baidu.com/s/1pNSP33IhUL1hoD6wD4_1fw 提取码:6ep5
谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!