将SAML集成到Rails应用程序中 [英] Integrate SAML in rails application

查看:25
本文介绍了将SAML集成到Rails应用程序中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将ruby-saml添加到我的项目中。但我对如何在我的场景中实现它感到有点困惑。我在一个网站上,比如说abc.com,有一个按钮。当我点击按钮时,我需要重定向到网站XYZ.com,在那里我需要传递SAML XML并将其发送到XYZ.com/saml。XYZ.com将处理SAML请求,然后他们会向我发送响应。有谁能告诉我怎么做到这一点吗?

此外,我对这些字段感到困惑。有人能给我做个简短的总结吗?

Settings.assertion_Consumer_service_url
Settings.sp_entity_id
Settings.idp_实体_id
Settings.idp_sso_service_url
Settings.idp_slo_service_url

def init
  request = OneLogin::RubySaml::Authrequest.new
  saml_settings.name_identifier_value_requested = "testuser@example.com"
  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目录、OneLogin等?(那么您就是服务提供商)
  • b.)您的应用程序拥有用户,并为其他应用程序(IdP=身份提供商)提供登录服务

我想是a)? 然后取决于:它是每个客户的提供商,所以它是动态的吗?每个客户可以配置自己的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

元数据

大多数客户也想要元数据URI,以便将SP添加到他们的IdP中(并自动配置该部分),因此您还需要提供元数据,例如";/saml/#{org.id}/METADATA&QOOT;并返回元数据:

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

更新:使用omniauth-sal

我们还在应用程序中使用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的GoodReadme doc以获取所有选项的列表。您还可以使用request_attributes

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

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

在Omniauth-SAML中似乎没有使用动态参数的选项,因此您可以尝试修补/覆盖该行为。Omniauth-SAML是一个机架中间件,因此您只能访问请求对象,而不能访问普通的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

这篇关于将SAML集成到Rails应用程序中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆