Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
349 views
in Technique[技术] by (71.8m points)

ruby on rails - Omniauth-Saml with Devise - mapping and using an attribute

I'm pretty new to Rails but we have an app using Devise and Omniauth for authentication and have recently integrated Omniauth-Saml by following the Omniauth documentation for Devise integration: https://github.com/omniauth/omniauth-saml#devise-integration The authentication works and we can create users and use these accounts without any issues.

In the SAML response attributes is an lacode (4-digit string). We want to check this user attribute against a reference lacode. If their cag matches the reference cag we want to set the verified_at attribute in the user.rb model.

I've updated the user model and to test if I set the oauth_lacode to "9064" to match the oauth_lacode_ref then the code works and the user's verified_at time and date are set at point of account creation.

app/models/user.rb

  # Get the existing user by email if the provider gives us a verified email.
  def self.first_or_initialize_for_oauth(auth)
    oauth_email           = auth.info.email
    oauth_email_confirmed = oauth_email.present? && (auth.info.verified || auth.info.verified_email)
    oauth_lacode              = auth.extra.raw_info.lacode
    oauth_lacode_ref          = "9064"
    oauth_lacode_confirmed    = oauth_lacode == oauth_lacode_ref
    oauth_user            = User.find_by(email: oauth_email) if oauth_email_confirmed

    oauth_user || User.new(
      username:  auth.info.name || auth.uid,
      email: oauth_email,
      oauth_email: oauth_email,
      password: Devise.friendly_token[0, 20],
      terms_of_service: "1",
      confirmed_at: oauth_email_confirmed ? DateTime.current : nil,
      verified_at: oauth_lacode_confirmed ? DateTime.current : nil
    )
  end

I'm not mapping and calling the lacode from the hash correctly as I see this error in the log "NoMethodError (undefined method `lacode' for #OneLogin::RubySaml::Attributes:0x00007f7a5040ad40):"

This is how I'm mapping the attributes in config/initializers/devise.rb

 attribute_statements: { email: ['urn:oid:0.9.2342.19200300.100.1.22'],
                                        lacode: ['urn:oid:0.9.2342.19200300.100.1.17']}

I have confirmed with the IDP that 'urn:oid:0.9.2342.19200300.100.1.17' is mapped to the lacode in the SAML response.

As in the User model above, this is how I'm trying to access the lacode from within the User model. "saml_cag = auth.extra.raw_info.lacode"

This is the guidance from Omniauth Saml:

:attribute_statements - Used to map Attribute Names in a SAMLResponse to entries in the OmniAuth info hash. For example, if your SAMLResponse contains an Attribute called 'EmailAddress', specify {:email => ['EmailAddress']} to map the Attribute to the corresponding key in the info hash. URI-named Attributes are also supported, e.g. {:email => ['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress']}. Note: All attributes can also be found in an array under auth_hash[:extra][:raw_info], so this setting should only be used to map attributes that are part of the OmniAuth info hash schema.

Does this sentence at the end mean I don't need to/can't map the attribute. Can anyone help or point me in the right direction?

question from:https://stackoverflow.com/questions/65887360/omniauth-saml-with-devise-mapping-and-using-an-attribute

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I managed to get this working. Only attribute names specified in the Omniauth Hash Schema can be used.

Mapping the lacode to description in the attribute statement, I was able to access it using "auth.info.description"


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...