Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

License

NotificationsYou must be signed in to change notification settings

fuzzygroup/saml_idp

 
 

Repository files navigation

Hello,

I've recently forked this gem fromhttps://github.com/sportngin/saml_idp to build an IdP integrated with devise as a backend (the devise portion is not open sourced). I also wrote thewiki for the version that I forked this from. A few things if you're here looking around:

  • Don't underestimate the effort of dealing with SAML; SAML is a powerful technology but frighteningly complex

  • ABSOLUTELY DO NOT expect that just because its all SAML that you can easily mix SP Init and IdP Init in the same project. You can but it is close todouble the effort.

  • The luck you have with your SAML SP vendors will vary dramatically. Here are some things I've learned:

    • MindTouch is, in my opinion, the gold standard for a vendor that supports SP init. Their product is excellent, their error messages are beyond good and their technical support is fantastic.
    • Other vendors will leave you dangling in mid air and have products that WILL NOT return error messages correctly unless you work with an engagement manager and ASK them for the error messages one by one. All the while you are being charged an hourly rate. I won't name names but if you email me I'm happy to discuss it with you over a voice connection.
    • SAML assertion building is tricky and the XML involved is as precise as anything you've ever done. Toss in X.509 certificates and your brain can begin to hurt.
    • Be very aware that the default configuration for this gem will NOT let you logout - it just plain crashes due toraise NotImplementedError left in production code; madness. I'm going to fix it but its not there yet.
    • The various ruby solutions for integrating SAML with devise don't help at all if you need to be an IdP; don't even bother.
    • Recent code commits from November 2016 have absolutely laughable description statements; I apologize for that. Doing better is a priority for me but I'm really trying hard to get this done.
    • Debugging SAML is as hard a debugging experience as I've ever had. Whatever your time estimate on a SAML project, I strongly recommend that you increase it due to the difficulty in debugging.

As with all things Open Source, I'm available to help with integration work. So if you're looking for someone that:

  • understands SAML
  • has integrated it with Ruby
  • can build you an IdP (or SP) based system

then you should get in touch with me. fuzzygroup a[t] gmail.com

More of my thoughts onSAML. There's more in the pipeline. Despite some atrocious experiences, I'm actually now quite the fan of SAML.

Prior to this is the previous readme left here for legacy purposes.-- Scott / fuzzygroup

Ruby SAML Identity Provider (IdP)

Forked fromhttps://github.com/lawrencepit/ruby-saml-idp

Build StatusGem Version

The ruby SAML Identity Provider library is for implementing the server side of SAML authentication. It allowsyour application to act as an IdP (Identity Provider) using theSAML v2.0protocol. It provides a means for managing authentication requests and confirmation responses for SPs (Service Providers).

This was originally setup by @lawrencepit to test SAML Clients. I took it closer to a realSAML IDP implementation.

Installation and Usage

Add this to your Gemfile:

gem 'saml_idp'

Not using rails?

IncludeSamlIdp::Controller and see the examples that use rails. It should be straightforward for you.

Basically you calldecode_request(params[:SAMLRequest]) on an incoming request and then use the valuesaml_acs_url to determine the source for which you need to authenticate a user. How you authenticatea user is entirely up to you.

Once a user has successfully authenticated on your system send the Service Provider a SAMLReponse byposting tosaml_acs_url the parameterSAMLResponse with the return value from a call toencode_response(user_email).

Using rails?

Add to yourroutes.rb file, for example:

get'/saml/auth'=>'saml_idp#new'get'/saml/metadata'=>'saml_idp#show'post'/saml/auth'=>'saml_idp#create'match'/saml/logout'=>'saml_idp#logout',via:[:get,:post,:delete]

Create a controller that looks like this, customize to your own situation:

classSamlIdpControllerincludeSamlIdp::IdpControllerdefidp_authenticate(email,password)# not using params intentionallyuser=User.by_email(email).firstuser &&user.valid_password?(password) ?user :nilendprivate:idp_authenticatedefidp_make_saml_response(found_user)# not using params intentionally# NOTE encryption is optionalencode_responsefound_user,encryption:{cert:saml_request.service_provider.cert,block_encryption:'aes256-cbc',key_transport:'rsa-oaep-mgf1p'}endprivate:idp_make_saml_responsedefidp_logoutuser=User.by_email(saml_request.name_id)user.logoutendprivate:idp_logoutend

Configuration

Be sure to load a file like this during your app initialization:

SamlIdp.configuredo |config|base="http://example.com"config.x509_certificate=<<-CERT-----BEGIN CERTIFICATE-----CERTIFICATE DATA-----END CERTIFICATE-----CERTconfig.secret_key=<<-CERT-----BEGIN RSA PRIVATE KEY-----KEY DATA-----END RSA PRIVATE KEY-----CERT# config.password = "secret_key_password"# config.algorithm = :sha256# config.organization_name = "Your Organization"# config.organization_url = "http://example.com"# config.base_saml_location = "#{base}/saml"# config.reference_id_generator                   # Default: -> { UUID.generate }# config.attribute_service_location = "#{base}/saml/attributes"# config.single_service_post_location = "#{base}/saml/auth"# Principal (e.g. User) is passed in when you `encode_response`## config.name_id.formats # =>#   {                         # All 2.0#     email_address: -> (principal) { principal.email_address },#     transient: -> (principal) { principal.id },#     persistent: -> (p) { p.id },#   }#   OR##   {#     "1.1" => {#       email_address: -> (principal) { principal.email_address },#     },#     "2.0" => {#       transient: -> (principal) { principal.email_address },#       persistent: -> (p) { p.id },#     },#   }# If Principal responds to a method called `asserted_attributes`# the return value of that method will be used in lieu of the# attributes defined here in the global space. This allows for# per-user attribute definitions.### EXAMPLE **# class User#   def asserted_attributes#     {#       phone: { getter: :phone },#       email: {#         getter: :email,#         name_format: Saml::XML::Namespaces::Formats::NameId::EMAIL_ADDRESS,#         name_id_format: Saml::XML::Namespaces::Formats::NameId::EMAIL_ADDRESS#       }#     }#   end# end## If you have a method called `asserted_attributes` in your Principal class,# there is no need to define it here in the config.# config.attributes # =>#   {#     <friendly_name> => {                                                  # required (ex "eduPersonAffiliation")#       "name" => <attrname>                                                # required (ex "urn:oid:1.3.6.1.4.1.5923.1.1.1.1")#       "name_format" => "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", # not required#       "getter" => ->(principal) {                                         # not required#         principal.get_eduPersonAffiliation                                # If no "getter" defined, will try#       }                                                                   # `principal.eduPersonAffiliation`, or no values will#    }                                                                      # be output### EXAMPLE ### config.attributes = {#   GivenName: {#     getter: :first_name,#   },#   SurName: {#     getter: :last_name,#   },# }## EXAMPLE ### config.technical_contact.company = "Example"# config.technical_contact.given_name = "Jonny"# config.technical_contact.sur_name = "Support"# config.technical_contact.telephone = "55555555555"# config.technical_contact.email_address = "example@example.com"service_providers={"some-issuer-url.com/saml"=>{fingerprint:"9E:65:2E:03:06:8D:80:F2:86:C7:6C:77:A1:D9:14:97:0A:4D:F4:4D",metadata_url:"http://some-issuer-url.com/saml/metadata"},}# `identifier` is the entity_id or issuer of the Service Provider,# settings is an IncomingMetadata object which has a to_h method that needs to be persistedconfig.service_provider.metadata_persister=->(identifier,settings){fname=identifier.to_s.gsub(/\/|:/,"_")`mkdir -p#{Rails.root.join("cache/saml/metadata")}`File.openRails.root.join("cache/saml/metadata/#{fname}"),"r+b"do |f|Marshal.dumpsettings.to_h,fend}# `identifier` is the entity_id or issuer of the Service Provider,# `service_provider` is a ServiceProvider object. Based on the `identifier` or the# `service_provider` you should return the settings.to_h from aboveconfig.service_provider.persisted_metadata_getter=->(identifier,service_provider){fname=identifier.to_s.gsub(/\/|:/,"_")`mkdir -p#{Rails.root.join("cache/saml/metadata")}`full_filename=Rails.root.join("cache/saml/metadata/#{fname}")ifFile.file?(full_filename)File.openfull_filename,"rb"do |f|Marshal.loadfendend}# Find ServiceProvider metadata_url and fingerprint based on our settingsconfig.service_provider.finder=->(issuer_or_entity_id)doservice_providers[issuer_or_entity_id]endend

Keys and Secrets

To generate the SAML Response it uses a default X.509 certificate and secret key... which isn't so secret.You can find them inSamlIdp::Default. The X.509 certificate is valid until year 2032.Obviously you shouldn't use these if you intend to use this in production environments. In that case,within the controller set the propertiesx509_certificate andsecret_key using aprepend_before_filtercallback within the current request context or set them globally via theSamlIdp.config.x509_certificateandSamlIdp.config.secret_key properties.

The fingerprint to use, if you use the default X.509 certificate of this gem, is:

9E:65:2E:03:06:8D:80:F2:86:C7:6C:77:A1:D9:14:97:0A:4D:F4:4D

Service Providers

To act as a Service Provider which generates SAML Requests and can react to SAML Responses use theexcellentruby-saml gem.

Author

Jon Phenow,me@jphenow.com

Lawrence Pit,lawrence.pit@gmail.com, lawrencepit.com, @lawrencepit

Copyright

Copyright (c) 2012 Sport Ngin.Portions Copyright (c) 2010 OneLogin, LLCPortions Copyright (c) 2012 Lawrence Pit (http://lawrencepit.com)

See LICENSE for details.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Ruby90.6%
  • HTML8.6%
  • Other0.8%

[8]ページ先頭

©2009-2025 Movatter.jp