将 SAML 集成到 Rails 应用程序中

2023-12-26

我正在尝试添加ruby-saml https://github.com/onelogin/ruby-saml在我的项目中。但我对如何在我的场景中实现它有点困惑。我在一个网站上,比如说 abc.com,有一个按钮。当我单击该按钮时,我需要重定向到网站 xyz.com,在该网站中我需要传递 SAML XML 并将其发送到 xyz.com/SAML。 SAML 请求将由 xyz.com 处理,然后他们将向我发送响应。谁能给我一些想法如何实现它?

另外,我对这些领域感到困惑。有人可以给我一个快速总结吗?

settings.assertion_consumer_service_url
设置.sp_entity_id
设置.idp_entity_id
settings.idp_sso_service_url
settings.idp_slo_service_url

def init
  request = OneLogin::RubySaml::Authrequest.new
  saml_settings.name_identifier_value_requested = "[email protected] /cdn-cgi/l/email-protection"
  saml_settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
  redirect_to(request.create(saml_settings))
end



 def saml_settings
  settings = OneLogin::RubySaml::Settings.new

  settings.assertion_consumer_service_url = "http://#{request.host}/saml/consume"
  settings.idp_sso_service_url            = "https://app.onelogin.com/trust/saml2/http-post/sso/#{OneLoginAppId}"
  settings.idp_sso_service_binding        = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" # or :post, :redirect
  settings.idp_slo_service_binding        = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" # or :post, :redirect
  settings.idp_cert_fingerprint           = OneLoginAppCertFingerPrint
  settings.idp_cert_fingerprint_algorithm = "http://www.w3.org/2000/09/xmldsig#sha1"
  settings.name_identifier_format         = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"

  # Optional for most SAML IdPs
  settings.authn_context = "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"
  # or as an array
  settings.authn_context = [
    "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport",
    "urn:oasis:names:tc:SAML:2.0:ac:classes:Password"
  ]

  # Optional bindings (defaults to Redirect for logout POST for ACS)
  settings.single_logout_service_binding      = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" # or :post, :redirect
  settings.assertion_consumer_service_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" # or :post, :redirect

  settings
end

你想要_____吗:

  • a.) 启用来自其他服务的 SAML 登录,例如 Microsoft Azure Directory、OneLogin 等? (那么你就是SP=服务提供商)
  • b.) 您的应用程序拥有用户并为其他应用程序提供登录服务(IDP = 身份提供商)

我想这是一个)? 然后取决于:它是每个客户的提供商吗?它是动态的吗?每个客户都可以配置自己的 IDP,还是为整个应用程序固定一个? 如果是后者,那么我强烈建议使用omniauth-saml相反,这更容易配置。

但如果您想使用“按客户企业登录”,那么我们就是这样做的。

  • 首先:我从来没有纠结过所有的具体设置和 url,Saml 可以通过“元数据 url”自动配置自身,我们让客户指定一个元数据 uri,该 uri 包含我们需要的所有信息,因此我们可以使用提供的解析它班级:
idp_metadata_parser = OneLogin::RubySaml::IdpMetadataParser.new
settings = idp_metadata_parser.parse_remote(organisation.idp_meta_data_url)

然后我们添加自己的设置+路由信息:

   settings.assertion_consumer_service_url = "https://#{request.host}/saml/consume/#{organisation.id}"
        settings.issuer                         = "https://#{@request.host}/saml/metadata/#{organisation.id}"
        settings.name_identifier_format         = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
        # Optional for most SAML IdPs
        settings.authn_context = "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"
# You would need a normal certificate/private key to enable signature stuff
        settings.certificate = File.read('config/saml/certificate.crt')
        settings.private_key = File.read('config/saml/private_key.key')
# In our case customer can optional activate signature validation:
        if organisation.signature_enabled?
          settings.security[:authn_requests_signed]   = true     # Enable or not signature on AuthNRequest
          settings.security[:logout_requests_signed]  = true     # Enable or not signature on Logout Request
          settings.security[:logout_responses_signed] = true     # Enable or not signature on Logout Response
          settings.security[:want_assertions_signed]  = true     # Enable or not the requirement of signed assertion
          settings.security[:metadata_signed]         = true     # Enable or not signature on Metadata

          settings.security[:digest_method]    = XMLSecurity::Document::SHA1
          settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
        end

请求/响应

这些或多或少来自 ruby​​-saml 示例:

控制器:

  skip_before_action :verify_authenticity_token

  def init
    @saml_request = OneLogin::RubySaml::Authrequest.new
    redirect_url = @saml_request.create(saml_settings)
    if redirect_uri
      redirect_to(redirect_uri)
    else
      @error = t('saml_controller.error')
      render 'error'
    end
  end

  def consume
    @saml_response = OneLogin::RubySaml::Response.new(params[:SAMLResponse])
    @saml_response.settings = saml_settings
  
    if @saml_response.is_valid?
      # do application logic, create user/update user sign in user
      sign_in(....) 
      session[:session_valid_for] = 12.hours.from_now.to_i
      redirect_to '/'
      else
        redirect_to '/watcher/profile'
      end
    else
      @error = @saml_response.errors
      render 'error'
    end
  end

Metadata

大多数客户也需要元数据 uri,以将 SP 添加到他们的 IDP 中(并自动配置该部分),因此您还需要提供元数据,例如“/saml/#{org.id}/metadata”并返回元数据:

def metadata
  meta = OneLogin::RubySaml::Metadata.new
  render xml: meta.generate(saml_settings), content_type: "application/samlmetadata+xml"
end

更新:使用omniauth-saml

我们还在应用程序中使用 Omniauth saml。它非常简单,但配置取决于您要集成的服务器。为了安全起见,您将需要一个 sso 目标 url(来自另一端的使用 url)和证书指纹或证书。您还可以指定“名称标识符”、电子邮件或用户名或类似的内容。

Rails.application.config.middleware.use OmniAuth::Builder do
  use OmniAuth::Strategies::SAML,
    idp_sso_target_url: "??",
    idp_slo_target_url: "??",
    idp_cert_fingerprint: "??",
    name_identifier_format: "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", 
    # or "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" for E-Mail
    issuer: "YourAppName.com"

看看omniauth-saml 的不错自述文件 https://github.com/omniauth/omniauth-saml#usage查看所有选项的列表。您还可以使用 OneLogin/IDP 请求更多属性request_attributes:

:request_attributes - 用于构建元数据文件以通知 IdP 将某些属性与 SAMLResponse 消息一起发送。 默认为请求姓名、名字、姓氏和电子邮件 属性。请参阅 OneLogin::RubySaml::AttributeService 类 每个属性的可用选项的 Ruby SAML gem。

更新:将动态参数传递给omniauth saml的重定向到Idp:

Omniauth-saml 中似乎没有提供动态参数的选项,因此您可以尝试修补/覆盖该行为。 Omniauth-SAML 是一个 Rack 中间件,因此您只能访问请求对象,而不能访问普通的 Rails 内容。如果您信任您的用户(您不应该信任),那么您可以将信息放入omniauth的参数中:/auth/saml?something1=foo&bar=2,或者您可以使用 ActiveSupport Message Encryptor 加密参数。

如果您知道如何从请求中提取动态参数,则可以动态应用此补丁,因为 Ruby!

# put this into
#
# config/initializers/omniauth_patch.rb
#
module OmniauthPatch
  def additional_params_for_authn_request
    # here you should have access to the current request
    # try around with binding.irb what you can do
    binding.irb
    # return parameters you want to pass to the saml redirect
    {
      email: email,
      # ...
    }
  end
end

OmniAuth::Strategies::SAML.include OmniauthPatch
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 SAML 集成到 Rails 应用程序中 的相关文章

  • Ruby:在 Ubuntu 上安装 rmagick

    我正在尝试在 Ubuntu 10 04 上安装 RMagick 看起来here https stackoverflow com questions 1482823 is there an easy way to install rmagic
  • 如何跳过 Devise SessionsController 的 before_filter ?

    我有一个before filter in my ApplicationController 也就是说 对于我的项目中的每个控制器 我怎么能够skip before filter对于设计的SessionsController创造行动 这是我的
  • Rails 中的并行方法

    我的 Rails Web 应用程序有数十种方法 从调用 API 到处理查询结果 这些方法具有以下结构 def method one batch query API process data end def method nth batch
  • 如何从数组中删除空白元素?

    我有以下数组 cities Kathmandu Pokhara Dharan Butwal 我想从数组中删除空白元素并想要以下结果 cities Kathmandu Pokhara Dharan Butwal 有没有类似的方法compact
  • 使用Rails UJS,如何从函数提交远程表单

    我正在使用Rails UJS 我有一个表单设置来进行远程提交 如下所示
  • Ruby on Rails 最酷的功能是什么,为什么选择它? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 在我问这个问题之前 我浏览了 SO 上 Ruby on Rails 的搜索结果 找不到太多 但以下 在此页面上找到 https stackove
  • gem install rmagick 在 OS X El Capitan 上失败

    几天前我升级到 El Capitan 并运行了 brew update brew upgrade 它更新了 imagemagick 导致 ruby 的 rmagick gem 停止工作 我想没问题 我就跑 gem install rmagi
  • (在 Ruby 中)允许混合类方法访问类常量

    我有一个为其定义常量的类 然后我定义了一个类方法来访问该类常量 这很好用 一个例子 usr bin env ruby class NonInstantiableClass Const hello world class lt lt self
  • 用于 RESTful 轨道应用程序的简单面包屑

    是否有任何辅助方法 除了默认 Rails 面包屑导航 http wiki rubyonrails org rails pages Breadcrumbs 为特定页面动态生成面包屑导航 而无需在 RESTful 应用程序中传递琐碎的参数 也就
  • 错误“未初始化常量 AWS (NameError)”

    它说 AWS 未初始化 我正在使用 aws sdk core gem 我尝试使用 aws sdk gem 代替 问题仍然存在 这是initializers aws rb 文件 AWS config access key id gt ENV
  • Rails Searchkick / Elasticsearch has_many 和belongs_to 关联

    我尝试使用 Searchkick 运行搜索并基于多个模型返回 我的书本模型包含这个 class Book lt ActiveRecord Base searchkick has many book subjects has many sub
  • 方法调用中是否有记忆约定?

    我想避免在方法调用中重新评估值 直到现在 我一直在这样做 def some method some method begin lot s of code end end 但它最终变得非常丑陋 在一些代码中 我看到类似以下内容 def som
  • 使用 Minitest 测试自定义验证器

    我有多个带有电子邮件验证的模型 因此 我将验证提取到自定义验证器中 我按照以下教程做到了这一点导轨指南 http guides rubyonrails org active record validations html custom va
  • 自定义变形在rails3上不起作用?

    我正在使用 Rails 3 0 1 并在initializers inflections rb 中有以下代码 ActiveSupport Inflector inflections do inflect inflect irregular
  • ruby 的 String .hash 方法如何工作?

    我只是红宝石的新手 我见过一个字符串方法 String hash 例如 在irb 我试过了 gt gt mgpyone hash returns gt 144611910 这个方法是如何工作的 The hash方法是为所有对象定义的 看文档
  • 带有附加参数的redirect_to

    我是一个菜鸟 redirect to users url notice Succeed p p 然后我添加一个message它失败了 redirect to users url notice Succeed message test p p
  • 在 CircleCI 中设置 Elasticsearch 和 Ruby on Rails

    我正在尝试在 Rails 应用程序中使用 Elasticsearch 设置 CircleCI 我想已经配置了镜像 但是如何在 CI 中连接到它 到目前为止我已经尝试过 https github com elastic elasticsear
  • Ruby 的字符串并置功能的官方文档在哪里?

    我最近意识到 如果你并置一系列 Ruby 字符串文字 例如 a b c 它相当于这些字符串文字的串联 但是 我在任何地方都找不到这种语言功能的记录 我使用术语 并置 和 串联 进行搜索 但只在几个 StackOverflow 响应中找到了对
  • 自定义通用 Rails 错误消息

    我们的 Rails 应用程序被设计为链接到多个客户端数据库的单个代码库 根据子域 应用程序确定要连接到哪个数据库 我们使用液体模板为每个客户定制演示文稿 我们无法为每个客户定制通用的 我们很抱歉 出了点问题 消息 谁能推荐一种方法让我们能够
  • 通过 ESI:include 设置 Cookie,如何?

    我正在尝试使用 esi 在我的网站上创建忍者缓存 这个想法是 该网站大部分是静态的 我只需要在用户是否登录时做一些花哨的事情 所以我试图在页面A上放置一个 并在页面B的应用程序中设置触发器 这样我就可以将页面 A 缓存在 varnish 上

随机推荐