概述
1.在项目添加权限
shiro处理权限流程:
(1)把所有的权限交给shiro管理 --createFilterChainDefinitionMap 可以体现处理
(2)在realm里面 就要查询当前用户的权限,如果这个权限在shiro管理返回之内,这个用户就有响应的权限
否则就没有
1.1 从数据库查询所有权限交个shiro管理
// 从数据库啊查询到所有的权限 交给shiro管理
List<Permission> all = iPermissionService.findAll();
for (Permission Permission : all) {
// 权限对应的资源请求地址
String url = Permission.getUrl();
//权限
String sn = Permission.getSn();
// 放进map交给shiro管理
aisellPerms去找我们自己写的自定义的过滤器
Perms默认值找的是shiro的过滤器我们继承复写后需要改成我们自己的
mp.put(url, "aisellPerms[" + sn + "]");
}
如何体现将 map里面的权限交给shiro管理呢:
配置自定义权限过滤器
自定义权限过滤必须有
使用自定义的权限过滤器必须有工厂bena的支持才能使用
<!-- 真实的过滤器处理 id这个名字 必须和web.xml里面配置的代理的过滤器的名称一样,才行-->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"></property>
<!-- 如果没有认证,会跳转该页面-->
<property name="loginUrl" value="/login"></property>
<!--认证成功,跳转的页面-->
<property name="successUrl" value="/main"></property>
<!--没有权限-->
<property name="unauthorizedUrl" value="/s/unauthorized.jsp"></property>
<!--配置自定义过滤器-->
<property name="filters">
<map>
<entry key="aisellPerms" value-ref="aisellPermsFilter">
</entry>
</map>
</property>
<!--拦截配置-->
<property name="filterChainDefinitionMap" ref="filterChainDefinitionMap1"></property>
</bean>
<!-- 定义自定义过滤器-->
<bean id="aisellPermsFilter"
class="cn.itsource.aisell.shiro.AisellFilterChainDefinitionMapBuilder"></bean>
<!-- 配置两个bean
引用map这个类 就动态的拿到了每个用户的权限-->
<bean id="filterChainDefinitionMap1" factory-bean="filterMapFactoyBean" factory-method="createFilterChainDefinitionMap">
</bean>
<!--
引用map这个类 就动态的拿到了每个用户的权限就能进行拦截和放行-->
<bean id="filterMapFactoyBean" class="cn.itsource.aisell.shiro.AisellFilterChainDefinitionMap"></bean>
1.2 查询当前用户具备权限
--sql语句查询当前用户的权限
select p.* from employee e
join employee_role er on e.id = er.employee_id
join role r on er.role_id = r.id
join role_permission rp on rp.role_id = r.id
join permission p on p.id = rp.permission_id
where e.id = 2
jpql查询语句
@Query("select p.sn from Employee e join e.roles er join er.permissions p where e.id = ?1 ")
public Set<String> findPermissionsByLoginUser(Long id);
当你前台登录后就会将登陆对象传到后台来验证
验证结束后进入如此方法授权
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//授权方法
Employee employee =(Employee) principalCollection.getPrimaryPrincipal();
/*根据用户名得到权限代码
从数据库查询当前用户的所有的权限
三层架构通过用户id去查询 用户权限 连表查寻*/
// Set<String> permissions = getPermissionsByUsername(employee.getUsername());
Set<String> permissionSet = permissionService.findPermissionByEmployeeId(employee.getId());
//shiro就会自己取进行权限的比较
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.setStringPermissions(permissionSet);
return authorizationInfo;
}
1.3 权限出问题之后,ajax怎么返回
为什么会出现这个问题 shiro底层不会处理你ajax请求 所以你发送ajax请求若是权限不够则 会弹出框 Undefined (该提示并不能满足我们的需求)
解决方式:
(1)写一个过滤器 覆写PermissionsAuthorizationFilter
(2)重写 onAccessDenied方法
方法里面 就判断如果是ajax请求 就直接返回json格式,
否则就走原来的格式,返回页面
public class AisellFilterChainDefinitionMapBuilder extends PermissionsAuthorizationFilter {
//没有权限的时候 返回的方法
/**
*
判断请求是否是ajax请求。如果是ajax请求,直接返回json格式
*
否则走它以前的返回页面的代码
*
就是一个自定义的拦截器的类
*/
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
// 通过请求拿到主体对象
Subject subject = this.getSubject(request, response);
// System.out.println(subject.getPrincipal());
//
得到的用户若是为空则表示没有登录
if (subject.getPrincipal()==null){
//没有登录成功后的操作
this.saveRequestAndRedirectToLogin(request, response);
}else {
// 强转为子类方法多啊
HttpServletRequest req=
(HttpServletRequest)request;
HttpServletResponse resp=(HttpServletResponse) response;
// 判断是否使ajax请求该方法会得到一个返回值
若是ajax请求的话再请求头里面会有这个key属性呢 X-Requested-With
String header = req.getHeader("X-Requested-With");
// 判断返回的是否是ajax的请求 XMLHttpRequest 是ajax请求的value
if (header!=null && "XMLHttpRequest".equals(header)){
// 说明就是ajax请求 返回json格式
//响应的格式类型
resp.setContentType("text/json; charset=UTF-8");
// 直接输出到请求的页面
resp.getWriter().print("{"success":false,"msg":"哥!你暂时没有权限"}");
}else {
String unauthorizedUrl = this.getUnauthorizedUrl();
if (StringUtils.hasText(unauthorizedUrl)) {
WebUtils.issueRedirect(request, response, unauthorizedUrl);
} else {
WebUtils.toHttp(response).sendError(401);
}
}
}
return false;
}
}
将自定义的过滤器配置到 applicationcontext-shiro.xml 里面
<!--配置自定义过滤器-->
<property name="filters">
<map>
<entry key="aisellPerms" value-ref="aisellPermsFilter">
</entry>
</map>
<!-- 定义自定义过滤器-->
<bean id="aisellPermsFilter"
class="cn.itsource.aisell.shiro.AisellFilterChainDefinitionMapBuilder"></bean>
配置完毕后 还需要再发送请求的时候找到自定义过滤器: 参见map里面的配置
1.4 页面权限的按钮控制
添加标签来控制页面的按钮是否显示 shiro会通过这个标签自己判断是否有权限
//
引入标签库支持
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<shiro:hasPermission name="employee:delete">
<a href="#" data-method="delete" plain="true"
class="easyui-linkbutton" iconCls="icon-remove">删除</a>
</shiro:hasPermission>
2 左侧树形菜单
需求:动态获取菜单根据用户权限显示菜单
2.1 menu对象的确定
写了Menu domain对象
public class Menu extends BaseDomain {
private String name;//菜单名称
private String url; //路径
private String icon; //图标
//配置懒加载
@ManyToOne(fetch = FetchType.LAZY)
// 表名
@JoinColumn(name="parent_id")
@JsonIgnore //忽略json 在展示json格式的 parent不会展示出来 会造成死循环
private Menu parent;
@Transient //这个是临时属性,不交给jpa管理 ,自己来维护 -- 手动添加子菜单
private List<Menu> children = new ArrayList();
//兼容esayui的菜单树[id:1,text:'xxx'] esayui的格式是text
public String getText(){
return this.name;
}
//setget...
}
2.2 service构造json的方法
public List<Menu> findMenuByLoginUser(Long employeeId) {
List<Menu> menus = new ArrayList();
//查询当前用户的所有的子菜单
List<Menu> subMenus = menuRepository.findByLoginUser(employeeId);
//循环子菜单
2,3,4,5
1
(7 8)
6
for (Menu subMenu : subMenus) {
//从子菜单里面拿到父菜单 6
Menu parentMenu = subMenu.getParent();
// 判断集合里面是否有这个对象
if(!menus.contains(parentMenu)) {
//若是没有则添加一个
menus.add(parentMenu);
}
//通过父菜单查询出子菜单 放到对象里面去
parentMenu.getChildren().add(subMenu);//[1,[2,3,4,5],6 [7,8]]
}
return menus;
}
最后
以上就是和谐学姐为你收集整理的登陆权限设置 根据权限设置菜单1.在项目添加权限2 左侧树形菜单的全部内容,希望文章能够帮你解决登陆权限设置 根据权限设置菜单1.在项目添加权限2 左侧树形菜单所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复