Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Force rebuild of soap_header between calls #371

Closed
joh-klein opened this issue Jan 23, 2013 · 3 comments
Closed

Force rebuild of soap_header between calls #371

joh-klein opened this issue Jan 23, 2013 · 3 comments

Comments

@joh-klein
Copy link

My SOAP-Server expects every request to have a valid token in the soap-header to authenticate the soap-client. This token is only valid for a certain period of time, so I have to expect it to be invalid in every call.

I am trying to find a way to force savon to rebuild the SOAP-Header (i.e. use the new auth-token) after I (re)authenticate with the SOAP-Server.
Here is a (somewhat lengthy) example:

class Soapservice
  extend Savon::Model

  # load stored auth-token
  @@header_data = YAML.load_file "settings.yaml"

  client wsdl: 'locally-cached-wsdl.xml'
  soap_header: {'verifyingToken' => @@header_data}

  operations :get_authentification_token, :get_server_time

  # request a new auth-token and store it
  def get_authentification_token
    response = super(:message => {
      'Username' => 'username', 
      'Userpass' => 'password'
    })

    settings = {
      'UserID' => response[:user_id].to_i,
      'Token' => response[:token], 
    }

    File.open("settings.yaml", "w") do |file|
      file.write settings.to_yaml
    end

    @@header_data = settings
  end

  def get_server_time
    return super()
    rescue Savon::SOAPFault => error
      fault_code = error.to_hash[:fault][:faultstring]
      if fault_code == 'Unauthorized Request - Invalide Token'
        get_authentification_token
        retry
      end
  end
end

When I call

webservice = Soapservice.new
webservice.get_server_time

with an invalid Token, it reauthenticates and saves the new Token successfully, but the retry doesn't load the new header (the result is an infinite loop).

@rubiii
Copy link
Contributor

rubiii commented Jan 26, 2013

thanks for reporting this. i think there's a somewhat "dirty" workaround for this that might work:

class Soapservice

  # load stored auth-token
  @@header_data = YAML.load_file "settings.yaml"

  def initialize
    @client = Savon.client(wsdl: 'locally-cached-wsdl.xml')
  end

  def call(operation_name, locals = {})
    @client.globals[:soap_header] = {'verifyingToken' => @@header_data}
    @client.call(operation_name, locals)
  end

  # request a new auth-token and store it
  def get_authentification_token
    message = {
      'Username' => 'username', 
      'Userpass' => 'password'
    }
    response = call(:get_authentification_token, :message => message)

    settings = {
      'UserID' => response[:user_id].to_i,
      'Token'  => response[:token], 
    }

    File.open("settings.yaml", "w") do |file|
      file.write settings.to_yaml
    end

    @@header_data = settings
  end

  def get_server_time
    call(:get_server_time)
  rescue Savon::SOAPFault => error
    fault_code = error.to_hash[:fault][:faultstring]
    if fault_code == 'Unauthorized Request - Invalide Token'
      get_authentification_token
      retry
    end
  end

end

notice that i removed Savon::Model, as you actually don't need it and i don't know if it supports this workaround.
if you look at the #call method, it accesses and changes the globals before every request.

the code could be full of typos, but i hope it helps solving your problem.

@joh-klein
Copy link
Author

Works beautifully. Thanks!

@rubiii
Copy link
Contributor

rubiii commented Jan 28, 2013

you're welcome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants