Shiro_项目_权限判断&菜单配置

本文详细介绍了使用Shiro进行权限判断的步骤,包括获取所有权限进行判断,重写权限拦截器,配置自定义拦截器以及在MyRealm中进行权限判断。此外,还阐述了如何设计和实现菜单操作,包括domain层的设计,如menu类和Permission类的配置,以及通过MenuRepository和MenuServiceImpl完成菜单显示功能,并在Controller层进行控制。最后,讨论了页面按钮的权限控制,确保只有拥有相应权限的用户才能看到按钮。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 权限判断

1.1 获取到所有的权限进行判断

//这个值之后从数据库中查询到【用户-角色-权限-资源】
//map.put("/s/permission.jsp","perms[user:*]");
List<Permission> permissions = permissionService.findAll();
for (Permission permission : permissions) {
    String url = permission.getUrl();
    String sn = permission.getSn();
    map.put(url, "yxbPerms["+sn+"]");
}

1.2 重写权限拦截器

在这里插入图片描述
重写shiro 的权限拦截器 PermissionsAuthorizationFilter
写一个类去继承PermissionsAuthorizationFilter

public class ItsourceYxbPermissionsAuthorizationFilter extends PermissionsAuthorizationFilter {
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
        Subject subject = this.getSubject(request, response);
        if (subject.getPrincipal() == null) {
            //没有登录成功后的操作
            this.saveRequestAndRedirectToLogin(request, response);
        } else {
            //登录成功后没有权限的操作
            //1.转成http的请求与响应操作
            HttpServletRequest httpRequest = (HttpServletRequest) request;
            HttpServletResponse httpResponse = (HttpServletResponse) response;
            //2.根据请求确定是什么请求
            String xRequestedWith = httpRequest.getHeader("X-Requested-With");
            if (xRequestedWith != null &&"XMLHttpRequest".equals(xRequestedWith)) {
                //3.在这里就代表是ajax请求
                //表示ajax请求 {"success":false,"message":"没有权限"}
                httpResponse.setContentType("text/json; charset=UTF-8");
                httpResponse.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;
    }
}

1.3 applicationContext-shiro.xml配置自定义拦截器

<!-- 引用自定义的权限过滤器 -->
	<property name="filters">
        <map>
            <entry key="yxbPerms" value-ref="yxbPermissionsAuthorizationFilter" />
        </map>
    </property>
</bean>

<!-- 配置自定义权限过滤器 -->
<bean id="yxbPermissionsAuthorizationFilter" class="cn.itsource.shiro.ItsourceYxbPermissionsAuthorizationFilter" />

1.4 MyRealm 进行权限判断

//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    //当前用户的权限你弄出来 给 shiro
    //得到主体用户
    Employee employee = (Employee) principalCollection.getPrimaryPrincipal();
 
    Set<String> permissions = permissionService.findPermissionssnsByLoginUser(employee.getId());
    SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
    simpleAuthorizationInfo.addStringPermissions(permissions);
    //返回权限里面  判断
    return simpleAuthorizationInfo;
}

2 菜单操作

2.1 设计domain层

2.1.1 配置menu类
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
@JsonIgnore
private Menu parent;

@Transient//临时属性
private List<Menu> children = new ArrayList<>();

public String getText(){
   return name;
}
2.1.2 配置Permission类
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "menu_id")
private Menu menu;

2.2 完成菜单显示功能

2.2.1 MenuRepository类
@Query("select distinct m from Employee e join e.roles r join r.permissions p join p.menu m where e.id = ?1")
List<Menu> findMenuByLoginUser(Long userId);
2.2.2 MenuServiceImpl类覆写方法
//自己构造需要的菜单出来
@Override
public List<Menu> findMenuByLoginUser(Long userId) {
    //所有的子菜单
    List<Menu> childrenList = menuRepository.findMenuByLoginUser(userId);
    //创建父级合存放父菜单
    List<Menu> parentList = new ArrayList<>();
    for (Menu childrenMenu : childrenList) {
        //得到父菜单
        Menu parent = childrenMenu.getParent();
        if(!parentList.contains(parent)){
            parentList.add(parent);
        }
        //存在父菜单
        parent.getChildren().add(childrenMenu);
    }
    return parentList;
}
2.2.3 Controller层
@RequestMapping("/findMenuByLoginUser")
@ResponseBody
public List<Menu> findMenuByLoginUser(){
    Employee employee = UserContext.getUser();
    return menuService.findMenuByLoginUser(employee.getId());
}

3 页面按钮权限控制

用户对应的有相应的权限时,该按钮才显示出来

<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<shiro:hasPermission name="employee:save">
    <a href="#"  data-method="add" class="easyui-linkbutton" iconCls="icon-add" plain="true">添加</a>
</shiro:hasPermission>
<shiro:hasPermission name="employee:update">
    <a href="#"  data-method="edit" class="easyui-linkbutton" iconCls="icon-edit" plain="true">修改</a>
</shiro:hasPermission>
<shiro:hasPermission name="employee:delete">
    <a href="#"  data-method="del" class="easyui-linkbutton" iconCls="icon-remove" plain="true">删除</a>
</shiro:hasPermission>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值