首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Pundit策略阻止ActiveAdmin登录

使用Pundit策略阻止ActiveAdmin登录
EN

Stack Overflow用户
提问于 2014-08-11 01:16:19
回答 2查看 736关注 0票数 2

我已经设置好了ActiveAdmin和Pundit,并且可以正常工作了。我的用户模型有一个角色属性(rails 4.1枚举)。如何仅允许具有管理员角色的用户登录/admin?

EN

回答 2

Stack Overflow用户

发布于 2015-02-04 21:14:01

这是另一种不需要接触ActiveAdmin::BaseController的方法。

在AA初始值设定项中,添加

代码语言:javascript
复制
# config/initializers/active_admin.rb
config.on_unauthorized_access = :user_not_authorized

并实现ApplicationController#user_not_authorized

代码语言:javascript
复制
# app/controllers/application_controller.rb
:
def user_not_authorized(exception)
  sign_out # or user will end up in a redirection loop
  flash[:error] = "Access has been denied because ..."
  redirect_to new_user_session_path
end

最后,更新AA页面(或仪表板等)的策略

代码语言:javascript
复制
# app/policies/active_admin/page_policy.rb
module ActiveAdmin
  class PagePolicy < ::ActiveAdminPolicy
    def show?
      User.roles[user.role] >= User.roles['manager']
    end
  end
end

完成后,只有经理及以上人员才能登录。

票数 1
EN

Stack Overflow用户

发布于 2015-02-04 20:29:54

我也面临着同样的问题,下面是我是如何解决的:

角色在User#role中定义。

代码语言:javascript
复制
class User < ActiveRecord::Base
  enum role: [ :client, :reseller, :manager, :admin, :super ]
end

以下是如何限制所有作为客户或经销商的用户访问AA的/admin

首先,将before_filter添加到AA的BaseController中,如here所述。

代码语言:javascript
复制
# lib/active_admin/deny_unprivileged/usage.rb
module ActiveAdmin
  ##
  # Only users showing a minimum user level (role)
  # should be allowed to access the administration interface.
  module DenyUnprivilegedUsage
    extend ActiveSupport::Concern

    included do
      before_filter :deny_unprivileged_usage
    end

    private

    ##
    # Deny access to /admin, unless user is, at least, a manager.
    #
    # This does the same as Devise::Controllers::Helpers#sign_out_and_redirect,
    # but adds a flash message explaining why access has been denied.
    #
    # See Devise::Controllers::Helpers#sign_out_and_redirect
    def deny_unprivileged_usage
      if current_user and not User.roles[current_user.role] >= User.roles['manager']
        resource_or_scope = current_user
        scope = ::Devise::Mapping.find_scope!(resource_or_scope)
        redirect_path = new_user_session_path
        ::Devise.sign_out_all_scopes ? sign_out : sign_out(scope)
        flash[:error] = "!!!"
        redirect_to redirect_path
      end
    end
  end
end

创建一个初始化器。

代码语言:javascript
复制
# config/initializers/active_admin_extensions.rb
require 'active_admin/deny_unprivileged_usage'
ActiveAdmin::BaseController.send(:include, ActiveAdmin::DenyUnprivilegedUsage)

重新启动服务器。

现在,不是经理的用户将被拒绝访问/admin。用户实际上将成功登录,但是,在登录之后,上面定义的筛选器将立即注销用户,并重定向回登录页面。

deny_unprivileged_usage方法几乎是Devise::Controllers::Helpers#sign_out_and_redirect的副本-只是它添加了一条flash消息,向用户解释登录被拒绝的原因。如果没有此更改,用户将只能返回到登录页面,而不知道登录被拒绝的原因。

更新

转念一想,如果用户注册了,很难想象他们永远都不能登录。

因此,对不同的名称空间使用不同的授权适配器和策略来实现基于角色的访问限制可能会更简洁。如here所述。

然后,/reseller将能够登录,例如,更改其密码,而/manager将被呈现更多的功能。这样,策略和AA资源将被清楚地分开。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25231109

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档