You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CanCanCan权限控制:如何限制非管理员访问/admin/applications?

Fixing Unauthorized Access to /admin/applications in Rails with CanCanCan

Hey there! This is a common hiccup when using CanCanCan with multiple routes interacting with the same underlying model. The issue arises because your manage oauth applications permission grants broad access to the Doorkeeper::Application model, which both /oauth/applications/* and /admin/applications rely on. Here are a few straightforward solutions to lock down the admin route exclusively to admins:

1. Quick Fix: Add a Before-Action to the Admin Controller

This is the simplest, most direct approach if the admin section should be strictly off-limits to non-admins.

Open your Admin::ApplicationsController and add a before-action that checks for admin status:

class Admin::ApplicationsController < ApplicationController
  # Run this check before any action in the controller
  before_action :require_admin

  # Your existing controller actions go here...

  private

  def require_admin
    # Redirect or deny access if the user isn't an admin
    unless current_user&.admin?
      redirect_to root_path, alert: "You don't have permission to access this page."
      # Alternatively, return a 403 forbidden response:
      # head :forbidden
    end
  end
end

2. Integrate with CanCanCan's Ability System

If you prefer to keep all permission logic centralized in your Ability model, adjust your rules to explicitly restrict admin access:

First, update app/models/ability.rb:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # Handle guest users

    if user.admin?
      # Admins get full access to everything
      can :manage, :all
    else
      # Non-admins can only manage OAuth applications via the Doorkeeper routes
      can :manage, Doorkeeper::Application
      # Explicitly block access to the admin section
      cannot :access, :admin
    end
  end
end

Then, add an authorization check in your Admin::ApplicationsController:

class Admin::ApplicationsController < ApplicationController
  before_action :authorize_admin_access

  private

  def authorize_admin_access
    # Use CanCanCan's authorize! method to enforce the :access, :admin rule
    authorize! :access, :admin
  end
end

3. Granular Control: Scope Abilities by Controller

If you need more nuanced permissions (e.g., some non-admins might have limited admin access), you can scope your abilities to specific controllers:

Update app/models/ability.rb:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new

    if user.admin?
      # Admins can manage applications through both controllers
      can :manage, Doorkeeper::Application
    else
      # Non-admins only get access to the Doorkeeper controller actions
      can [:index, :show, :new, :create, :edit, :update, :destroy], Doorkeeper::Application, controller: 'doorkeeper/applications'
      # Block all actions on the admin controller for non-admins
      cannot [:index, :show, :new, :create, :edit, :update, :destroy], Doorkeeper::Application, controller: 'admin/applications'
    end
  end
end

Then ensure your admin controller uses CanCanCan's resource loading:

class Admin::ApplicationsController < ApplicationController
  load_and_authorize_resource class: Doorkeeper::Application
end

Testing the Fix

After implementing any of these solutions, verify by:

  • Logging in as a non-admin user with manage oauth applications permission: They should be blocked from /admin/applications but still access /oauth/applications/*.
  • Logging in as an admin: They should have full access to both paths.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:14:18