二.四 自定义Realm
package com.yjl.shiro; import java.util.List; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.util.ByteSource; import com.yjl.dao.PrivilegeDao; import com.yjl.dao.RoleDao; import com.yjl.dao.UserDao; import com.yjl.dao.impl.PrivilegeDaoImpl; import com.yjl.dao.impl.RoleDaoImpl; import com.yjl.dao.impl.UserDaoImpl; import com.yjl.pojo.Privilege; import com.yjl.pojo.Role; import com.yjl.pojo.User; public class MyRealm extends AuthorizingRealm{ private UserDao userDao=new UserDaoImpl(); private PrivilegeDao privilegeDao=new PrivilegeDaoImpl(); private RoleDao roleDao=new RoleDaoImpl(); @Override public String getName() { return "MyRealm"; } //授权 @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; } //认证 @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(), //传入转换后的盐 ByteSource.Util.bytes(user.getSalt()),getName()); return simpleAuthenticationInfo; } }
二.五 配置文件 shiro.ini
用于注入自定义Realm, 添加拦截器规则, 加入密码验证
[main] #加密类 credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher #加密方式 credentialsMatcher.hashAlgorithmName=md5 #加密次数 credentialsMatcher.hashIterations=10 #存储散列后的密码是否为16进制 credentialsMatcher.storedCredentialsHexEncoded=false #配置自定义realm myRealm=com.yjl.shiro.MyRealm #配置加密 myRealm.credentialsMatcher=$credentialsMatcher #注入自定义的realm securityManager.realm=$myRealm #配置权限 authc.loginUrl=/User/toLogin #跳转到权限不足的路径 roles.unauthorizedUrl=/NoPermission/NoPermission perms.unauthorizedUrl=/NoPermission/NoPermission [urls] #静态页面可以访问 /static/**=anon #跳转到登录页面和登录方法可以访问 /User/toLogin=anon /User/login=anon #跳转到主页,需要认证 /Main/toMain=authc /Privilege/getPrivilegeByUId=authc #执行方法,不仅需要认证,还需要有相应的方法 /Dept/add=authc,perms["dept:add"] /Dept/update=authc,perms["dept:update"] /Dept/list=authc,perms["dept:list"] /Dept/delete=authc,perms["dept:delete"] #退出登录 /User/logout=logout #其他的一切资源,都需要认证 /**=authc
二.六 前端处理
以前的各个页面,不需要做太大的改变, 只需要将 以前的 ?jsp=toLogin, ?method=login, 这样的链接改变即可。(不能用传参的方式进行控制拦截)
只讲解一下 部门表里面关于 添加,删除,修改 三个按钮的控制和隐藏. 这个也与前面是一致的。
二.六.一 部门表 jsp页面 设置标识
<!-- 查看明细部门 --> <shiro:hasPermission name="dept:add"> <script> sessionStorage.setItem("dept:add",true); </script> </shiro:hasPermission> <shiro:hasPermission name="dept:update"> <script> sessionStorage.setItem("dept:update",true); </script> </shiro:hasPermission> <shiro:hasPermission name="dept:delete"> <script> sessionStorage.setItem("dept:delete","true") </script> </shiro:hasPermission> <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/dept.js"></script>
二.六.二 部门表 js 脚本通过标识控制按钮的显示和隐藏
//看是否有添加的权限 var add=sessionStorage.getItem("dept:add"); if(add){ $("#add").show(); }else{ $("#add").hide(); } //看修改和删除是否显示和隐藏 function operateFormatter(value, row, index) { var update=sessionStorage.getItem("dept:update"); var del=sessionStorage.getItem("dept:delete"); //console.log("update:"+update+",del:"+del); var udpateIcon=""; if(update){ udpateIcon='<a class="update text-primary" href="javascript:void(0)" data-toggle="tooltip" title="修改">' +'<i class="fa fa-pencil"></i> 修改 </a>'; } var delIcon=""; if(del){ delIcon='<shiro:hasPermission name="dept:delete"><a class="delete text-danger" href="javascript:void(0)" data-toggle="tooltip" title="撤销">' +'<i class="fa fa-minus"></i> 删除 </a></shiro:hasPermission">'; } return udpateIcon+delIcon; }
二.七 测试整合
二.七.一 admin 用户登录测试
输入网址: http://localhost:8080/Shiro_Servlet/User/toLogin
进入登录页面, 填写用户名 admin, 密码 12345, 错误的密码
填写正确的用户名和密码 admin, 1234
用户对部门没有添加和修改的权限,只有删除的权限, 故 显示删除的按钮,不显示添加和修改的按钮。
手动输入网址: localhost:8080/Shiro_Servlet/Dept/add, 进行添加
提示没有权限,跳转到没有权限的页面,拦截add 成功。
手动输入网址: http://localhost:8080/Shiro_Servlet/Dept/delete, 进行删除
能够正确的进行删除。
当用户点击退出之后,再输入刚才的那个 删除网址, 会跳转到退出的页面
二.七.二 yuejl 用户登录测试
输入用户名, yuejl, 密码 1234
没有部门的权限,所以不显示部门的相关信息。
点击用户管理,可以正常的显示
二.七.三 yuezl 用户登录测试
输入用户名 yuezl, 密码 1234
当用户输入 查询员工的链接, http://localhost:8080/Shiro_Servlet/User/toList, yuezl没有这个权限
是正常的, 这个为什么呢? 因为没有在 shiro.ini 里面配置,配置上就好了。
/User/toList=authc,perms["user:toList"]
发现,在 shiro.ini 里面配置拦截 每一个url, 是不是特别麻烦呢?
可以用注解方式,进行配置拦截的每一个url, 后面 Spring 整合时会讲到。
本章节代码链接为:
链接:https://pan.baidu.com/s/1s19kY7k5f4GHvHecy0CcfQ 提取码:6pig
谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!