Ruby on rails 4 设计可锁定和自定义策略
我正在为LDAP身份验证开发一个自定义策略,并且我已经实现了Ruby on rails 4 设计可锁定和自定义策略,ruby-on-rails-4,authentication,devise,Ruby On Rails 4,Authentication,Devise,我正在为LDAP身份验证开发一个自定义策略,并且我已经实现了valid?和身份验证根据和本设计的方法。我的自定义策略本身就起作用 我还想使用该模块(以及其他Desive模块),但它们似乎只有在同时存在时才起作用。我一直在阅读Desive源代码,但我不明白Lockable是如何找到用户(资源)以增加:failed_尝试次数的。如何使用自定义策略将用户记录或资源传递给Lockable 下面是我的定制策略。我正在使用Desive 3.5和Rails 4.2 require 'net/ldap' req
valid?
和身份验证代码>根据和本设计的方法。我的自定义策略本身就起作用
我还想使用该模块(以及其他Desive模块),但它们似乎只有在同时存在时才起作用。我一直在阅读Desive源代码,但我不明白Lockable是如何找到用户(资源)以增加:failed_尝试次数的。如何使用自定义策略将用户记录或资源传递给Lockable
下面是我的定制策略。我正在使用Desive 3.5和Rails 4.2
require 'net/ldap'
require 'devise/strategies/authenticatable'
module Devise
module Strategies
class LdapAuthenticatable < Authenticatable
def valid?
params[:user] && login.present? && password.present?
end
def authenticate!
resource = mapping.to.find_for_authentication(email: params[:user][:email])
if params[:user]
begin
ldap = Net::LDAP.new
ldap.auth(my_ldap_service, my_ldap_service_password)
ldap.encryption(:simple_tls)
ldap.base = "base_here"
ldap.host = my_ldap_host
ldap.port = "636"
result_attrs = ["employeenumber", "givenname", "sn", "mail", "department"]
result = ldap.bind_as(base: "base_here", filter: "(mail=#{login})", attributes: result_attrs, password: password, time: 3)
if result
#valid ldap credentials
user = get_user_from_database(result)
if user
success!(user)
else
fail!(:invalid_login)
end
else
fail!(:invalid_login)
end
rescue => e
Rails.logger.error e.message
fail!(:invalid_login)
end
end
end
def login
params[:user][:email]
end
def password
params[:user][:password]
end
end
end
end
需要“net/ldap”
要求“设计/策略/可验证”
模块设计
模块策略
类LdapAuthenticatablee
Rails.logger.error e.消息
失败!(:无效的_登录)
结束
结束
结束
def登录
参数[:用户][:电子邮件]
结束
def密码
参数[:用户][:密码]
结束
结束
结束
结束
Active Directory应具有可锁定功能。通过在自定义策略中使用LDAP,您可以将该功能的责任从应用程序转移到LDAP/Active Directory。可锁定应该可以防止恶棍强行访问您的应用程序。如果Active Directory对此没有限制,他可以直接对其运行攻击,如果成功,可以使用应用程序中的凭据
但是,您应该使应用程序能够显示远程服务器返回的错误消息,如“重试次数太多,请在5分钟内重试”。我最后将其与原始问题上发布的资源结合使用。要使可锁定工作,必须存在可验证的数据库。如果您可以控制LDAP,那么Toni的上述方法应该会起作用,我在提出问题时没有这样做。您无法调用验证方法,该方法是您继承的可验证类的一部分。validate
方法从可锁定模块调用valid\u for\u authentication?
方法,然后该模块负责增加尝试次数并锁定帐户
在database_authenticatable中,通过使用返回布尔值的valid_password?
解决此问题。在本例中,如果bind_
不返回结果,则需要添加validate(resource){false}
已修复的完整身份验证代码>方法如下所示
def authenticate!
resource = mapping.to.find_for_authentication(email: params[:user][:email])
if params[:user]
begin
ldap = Net::LDAP.new
ldap.auth(my_ldap_service, my_ldap_service_password)
ldap.encryption(:simple_tls)
ldap.base = "base_here"
ldap.host = my_ldap_host
ldap.port = "636"
result_attrs = ["employeenumber", "givenname", "sn", "mail", "department"]
result = ldap.bind_as(base: "base_here", filter: "(mail=#{login})", attributes: result_attrs, password: password, time: 3)
if result
#valid ldap credentials
user = get_user_from_database(result)
if user
success!(user)
else
fail!(:invalid_login)
end
else
# no result -> wrong password
validate(resource) { false }
fail!(:invalid_login)
end
rescue => e
Rails.logger.error e.message
fail!(:invalid_login)
end
end
end
“你找到解决这个问题的办法了吗?”拉维卡在下面看到了我的答案。