【问题标题】:assigning roles in devise/cancan/deviseldap/rolify and using ldap_param_value在 devise/cancan/deviseldap/rolify 中分配角色并使用 ldap_param_value
【发布时间】:2013-07-10 01:04:27
【问题描述】:

前面的底线: 如何在用户登录时立即从 ldap 分配角色。

我正在使用 devise/cancan/deviseldap/rolify 对用户进行身份验证,然后希望分配一个角色。我很接近我认为让这个工作。我所拥有的是一个自定义初始化程序,只有当他们的 ldap 条目中有特定的 memberOf 时,它才允许用户进入应用程序。

感谢这个帖子中的人的慷慨帮助:

checking groups at runtime with devise and devise_ldap_authenticatable

所以现在是我分配角色的时候了,在网上搜索之后,我认为最好的方法可能是来自 devise 的 user.rb 中的 after_create。我在 config/initializer 中有这些 memberOf,但以后无法像在 user.rb 中那样访问它们,如下面我在 user.rb 中尝试的描述:

 class User < ActiveRecord::Base
     after_create :assign_role
     ...
     ...
  private
  def assign_role
   puts "Assigning role!"
   member_of = self.ldap_param_value("memberOf")  #get array #i know self here is wrong
   member_of.each do |str|
   if str.include? 'Help Desk Admin'
      self.roles << "admin"
   end
   if str.include? 'Password Manager'
      self.roles << "password_manager"
   end
   if str.include? 'Security'
     self.roles << "security"
   end
   if str.include? 'Help Desk'
     self.roles << "help_desk"
   end
  end

 puts "roles assigned!"
 self.update
end

最大的问题(有很多我仍然是一个 ruby​​ noobie)是我调用了一个方法 ldap_param_value 并且我知道在 self 上调用它是不正确的,我让这段代码在 config/initializer 中工作在同一行/customdevise.rb(这是我的前门全部检查):(我知道我需要实例化正确的对象才能访问上面的 ldap_param_value,但不确定它是什么)。我以为自己是:Devise::LdapAdapter,但我在上面试过了,还是不行:

Devise::LdapAdapter.ldap_param_value(...)

为了完整起见,我的config/initializer/customedevise.rb

Devise::LdapAdapter::LdapConnect.class_eval do
  def user_group_test
  member_of = self.ldap_param_value("memberOf") #self works here...
  checkgroups member_of # your group test method  end

 def checkgroups(members)
  retVal = false
  members.each do |str|
    if str.include? 'Help Desk Admin' or str.include? 'Password Manager' or  str.include? 'Security' or str.include? 'Help Desk'
        retVal = true;
    end
  end
  return retVal
end
#    'CN=Password Manager'
#    'CN=Help Desk'
#    'CN=Help Desk Admin'
#    'CN=Security'


def authorized?
DeviseLdapAuthenticatable::Logger.send("Authorizing user #{dn}")
  if !user_group_test
    DeviseLdapAuthenticatable::Logger.send("Not authorized because custom authentication failed.")
    return false
  elsif !authenticated?
    DeviseLdapAuthenticatable::Logger.send("Not authorized because not authenticated.")
    return false
  elsif !in_required_groups?
    DeviseLdapAuthenticatable::Logger.send("Not authorized because not in required groups.")
    return false
  elsif !has_required_attribute?
    DeviseLdapAuthenticatable::Logger.send("Not authorized because does not have required attribute.")
    return false
  else
    return true
  end
 end
end

注意:上面的另一个缺陷是设计不知道身份验证失败的确切原因......我为此受苦并更改了devise.en.yml 文件invalid: 以包含更多信息:

en:
  devise:
   confirmations:
    confirmed: "Your account was successfully confirmed. You are now signed in."
    send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes."
    send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions about how to confirm your account in a few minutes."
   failure:
     already_authenticated: "You are already signed in."
     inactive: "Your account was not activated yet."
     invalid: "Invalid email or password.  Or not a member of the correct group"

      ..etc...

【问题讨论】:

  • 我能理解你想要做什么。但我不明白你如何/为什么在这里使用 LDAP。
  • 因为我们正在针对 ldap 进行身份验证,并且角色存储在 ldap 中。活动目录更具体。
  • 太好了...我将我的角色存储在一个 mysql 表中。我将与执行此操作的代码共享。你和我的区别应该是角色检索机制。想解释一下为什么角色存储在 LDAP 中?
  • 好吧,我认为角色检索机制在这里几乎是关键。虽然角色在那里,因为我正在构建的是一个替换旧站点的站点……这个旧站点在 AD 中做了所有事情。所以用户可以访问新站点,我希望它是透明的:他们登录并且他们的角色转移。

标签: ruby ruby-on-rails-3 devise ldap cancan


【解决方案1】:

这很简单,

  1. 一个表 Permissions 将包含用户可以执行的所有模型和操作。
  2. 权限 HABTM 用户和用户 HABTM 权限
  3. 角色 has_many 用户,用户属于_to 角色
  4. 角色 HABTM 权限和权限 HABTM 角色
  5. 如果你建立了以上所有关联,并且基于 current_user id,你可以检索用户的角色并检索他们的权限,这些权限将通过以下方法在能力类中实例化,

         def initialize(user)   
            user.role.permissions.each do |permission|
              if permission.subject_class == "all"
                can permission.action.to_sym, permission.subject_class.to_sym
              else
                can permission.action.to_sym, permission.subject_class.constantize
            end
          end
         end
    

此链接显示如何操作,

http://blog.joshsoftware.com/2012/10/23/dynamic-roles-and-permissions-using-cancan/

【讨论】:

  • 那里有很多东西。我真的认为我只需要能够获取 ldap 角色,然后将它们保存到数据库中。在确保我的 application.yml 在那里设置了我要保存到数据库中的角色(在阅读和测试 ldap 中发现的内容之后)并且我计划在用户创建期间执行此操作......我最大的问题不是在 after_create 期间可以从 ldap 访问角色
  • 我对此表示赞同,因为这是一个很好的回应,但我没有接受作为答案,因为它没有解决我的特定问题的症结所在,即让 memberOf 在某个地方退出 ldap不是配置/初始化程序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-08
  • 2014-05-28
  • 1970-01-01
  • 2012-08-09
  • 2017-06-04
  • 2021-09-13
  • 1970-01-01
相关资源
最近更新 更多