ASP.NET Zero宿主侧创建租户OU提示缺少Managing organization tree权限如何解决
报错原因
- ASP.NET Zero 封装的
IOrganizationUnitAppService.CreateOrganizationUnit方法默认标记了[AbpAuthorize("Managing organization tree")]权限校验注解,ABP 框架的拦截器会在方法执行前检查当前会话用户是否持有对应权限,校验不通过就会抛出你遇到的报错。 - 你的代码本身存在语法bug:
_userManager.FindByNameAsync(TenantName)是异步方法,你没有加await关键字,拿到的user实际是Task<User>类型的对象而非真实用户实体,后续取到的user.Id是无效值,相当于你切换的会话用户根本不存在,自然无法通过权限校验。 - 就算你修正了异步调用的问题,如果你指定的租户用户本身没有被分配「管理组织树」的权限,调用应用服务依然会触发权限报错。
解决方法
推荐两种可落地的方案,按需选择即可:
方案1:改用领域层OrganizationUnitManager创建(更推荐)
领域层服务不会触发应用服务层的权限校验逻辑,非常适合后台系统内部跨租户操作的场景,代码示例:
// 修正异步调用,加await拿到真实用户实体 var user = await _userManager.FindByNameAsync(TenantName); using (_session.Use(TenantID, user.Id)) { try { // 提前注入IOrganizationUnitManager领域服务直接创建OU // 第三个参数为父级OU的ID,无父级则传null var newOu = new OrganizationUnit(TenantID, OUCode, null); await _organizationUnitManager.CreateAsync(newOu); } catch(Exception ex) { var errorMsg = ex.Message; } }
方案2:保留使用应用服务,临时绕过权限校验
如果你一定要继续使用IOrganizationUnitAppService,可以临时禁用当前请求的权限校验,同时修正异步调用问题即可:
CreateOrganizationUnitInput organizationUnitDto = new CreateOrganizationUnitInput() { DisplayName = OUCode }; // 修正异步调用 var user = await _userManager.FindByNameAsync(TenantName); using (_session.Use(TenantID, user.Id)) { // 提前注入IPermissionChecker服务,临时禁用权限校验 using (_permissionChecker.Disable()) { try { await _organizationUnitAppService.CreateOrganizationUnit(organizationUnitDto); } catch(Exception ex) { var errorMsg = ex.Message; } } }
内容的提问来源于stack exchange,提问作者Justin Rumpf
相关产品推荐
相关产品推荐

