You need to enable JavaScript to run this app. Rails使用CanCan配置权限后RSpec越权创建AcademicHistory测试失败
优惠活动
大模型
产品
解决方案
定价
更多

Rails使用CanCan配置权限后RSpec越权创建AcademicHistory测试失败

越权创建问题的根因定位

其他账号可无权限创建AcademicHistory,是两处配置与CanCanCan默认逻辑不匹配,导致权限校验链路完全放行:

  • 父资源权限校验错位
    load_and_authorize_resource :account 处理嵌套子资源的create动作时,默认对父资源Account执行:read权限校验。但Ability中配置了无限制的can :read, Account 规则,意味着任何账号都可读取任意Account,即使路由传入其他用户的Account ID,这步检查也会直接放行,不会触发403拦截。
  • 子资源权限校验被shallow模式绕过
    给AcademicHistory配置的shallow: true 选项,会在嵌套路由场景下跳过父资源关联校验:
    • 新建的AcademicHistory对象不会自动绑定路由传入的Account ID
    • 权限检查时,CanCan无法匹配can :manage, AcademicHistory, account_id: account.id 的条件规则,最终因无法识别越权行为直接放行
修复方案
  1. 调整控制器资源加载配置
    移除shallow模式的绕过逻辑,强制走完整的关联加载和权限校验流程:
    # frozen_string_literal: true
    module V1
      # AcademicHistoriesController
      class AcademicHistoriesController < ApplicationController
        load_and_authorize_resource :account
        # 禁用shallow模式,强制通过Account关联加载AcademicHistory资源
        load_and_authorize_resource through: :account, shallow: false
    
        def create
          @academic_history.save!
          render json: @academic_history, status: :created
        end
    
        private
    
        def resource_params
          params.require(:academic_history).permit(
            :name,
            :faculty,
            :since_date,
            :until_date,
            :type
          )
        end
      end
    end
    
  2. 强化Ability的权限匹配规则
    补充关联级的权限校验逻辑,适配嵌套路由下的新建资源校验场景,避免仅靠外键属性匹配因资源未绑定而失效:
    # frozen_string_literal: true
    # Ability
    class Ability
      include CanCan::Ability
    
      def initialize(account)
        account ||= Account.new
        can :read, Account
        can :manage, Account, id: account.id
        can :manage, Profile, account_id: account.id
        can :read, AcademicHistory
        # 补充关联级校验,确保仅所属账号可管理自身的AcademicHistory
        can :manage, AcademicHistory, account: { id: account.id }
      end
    end
    
修复后校验逻辑
  • 当用户尝试访问其他账号的创建接口时:先加载目标Account资源,因当前用户仅能管理自己的Account,权限检查失败,直接返回403,不会执行资源保存
  • 当用户访问自身账号的创建接口时:资源自动绑定当前登录账号ID,权限检查通过,正常完成创建流程
  • 其他用户读取AcademicHistory的规则不受影响,保持原有开放读取的逻辑

内容的提问来源于stack exchange,提问作者Nozomi Iida

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.02 06:36:09