Rails:从ActiveResource调用设计身份validation

我的两个rails应用程序(app1,app2)正在使用活动资源进行通信。

app1调用app2在app2中创建一个用户。 app2将创建用户,并希望app1然后将用户重定向到app2的经过身份validation的页面。

从app1到app2会不断要求用户登录。

我正在寻找一种方法来避免在app2中执行此登录步骤,而是让用户在第一次活动资源调用期间登录以创建用户,并以某种方式获取写入的身份validation令牌。

使用Devise完成身份validation。 Devise中有什么内容可以支持这个吗?

传递身份validation令牌的方式是什么?

您正在尝试实施单点登录服务(SSO)的forms(使用app1登录,并使用app2,app3自动进行身份validation…)。 遗憾的是,这不是一项微不足道的任务。 你可以让它工作(也许你已经这样做了),但是为什么不集成一个现有的解决方案,而不是试图重新发明轮子呢? 或者甚至更好, 标准协议 ? 这实际上相对容易。

CAS服务器

RubyCAS是一个Ruby服务器,它实现了耶鲁大学的CAS(中央认证服务)协议。 我用它取得了很大的成功。

棘手的部分是让它与您现有的Devise身份validation数据库一起使用。 我们遇到了同样的问题,经过一些代码潜水后,我想出了以下内容,这对我们来说就像是一种魅力。 这在你的RubyCAS服务器配置中,默认为/etc/rubycas-server/config.yml 。 当然,根据需要进行调整:

 authenticator: class: CASServer::Authenticators::SQLEncrypted database: adapter: sqlite3 database: /path/to/your/devise/production.sqlite3 user_table: users username_column: email password_column: encrypted_password encrypt_function: 'require "bcrypt"; user.encrypted_password == ::BCrypt::Engine.hash_secret("#{@password}", ::BCrypt::Password.new(user.encrypted_password).salt)' enter code here 

那个encrypt_function ……我对在那里嵌入一个require语句不太高兴,但是嘿,它有效。 不过,任何改进都会受到欢迎。

CAS客户

对于客户端(您希望集成到app2,app3中的模块……), RubyCAS-client gem提供了一个Rails插件。

你需要一个初始化程序rubycas_client.rb ,例如:

 require 'casclient' require 'casclient/frameworks/rails/filter' CASClient::Frameworks::Rails::Filter.configure( :cas_base_url => "https://cas.example.com/" ) 

最后,您可以重新连接几个Devise调用以使用CAS,这样您的当前代码几乎可以正常工作:

 # Mandatory authentication def authenticate_user! CASClient::Frameworks::Rails::Filter.filter(self) end # Optional authentication (not in Devise) def authenticate_user CASClient::Frameworks::Rails::GatewayFilter end def user_signed_in? session[:cas_user].present? end 

不幸的是,没有直接的方法来替换current_user ,但您可以尝试以下建议:

具有直接数据库访问权限的current_user

如果您的客户端应用程序可以访问后端用户数据库,则可以从那里加载用户数据:

 def current_user return nil if session[:cas_user].nil? return User.find_by_email(session[:cas_user]) end 

但是对于更具可扩展性的体系结构,您可能希望将应用程序与后端分开。 对于,您可以尝试以下两种方法。

current_user使用CAS extra_attributes

使用CAS协议提供的extra_attributes:基本上,将所有必要的用户数据作为extra_attributes传递给CAS令牌(在config.yml中添加一个extra_attributes键,列出所需的属性到您的身份validationconfig.yml ),然后重建一个虚拟用户。客户端。 代码看起来像这样:

 def current_user return nil if session[:cas_user].nil? email = session[:cas_user] extra_attributes = session[:cas_extra_attributes] user = VirtualUser.new(:email => email, :name => extra_attributes[:name], :mojo => extra_attributes[:mojo], ) return user end 

VirtualUser类定义留作练习。 提示:使用无表格的ActiveRecord(请参阅Railscast#193 )应该让您编写一个直接替换,它应该与现有代码一样工作。

current_user在后端使用XML API和ActiveResource

另一种可能性是在用户后端准备XML API,然后使用ActiveResource检索用户模型。 在这种情况下,假设您的XML API接受一个电子邮件参数来过滤用户列表,代码将如下所示:

 def current_user return nil if session[:cas_user].nil? email = session[:cas_user] # Here User is an ActiveResource return User.all(:params => {:email => email}).first end 

虽然这种方法需要额外的请求,但我们发现它是最灵活的。 只需确保保护您的XML API,否则您可能会在系统中打开一个安全漏洞。 SSL,HTTP身份validation,并且由于它仅供内部使用,因此请考虑使用IP限制。

额外奖励:其他框架也可以加入乐趣!

由于CAS是标准协议,因此您可以获得允许使用其他技术的应用程序使用单点登录服务的额外好处。 有Java , PHP , .Net和Apache的官方客户端。

如果这有任何帮助,请告诉我,如果您有任何疑问,请随时询问。