All Apps and Add-ons

Passing Cookies From Custom Auth Handler In REST Modular Input

david_rose
Communicator

FULL DISCLOSURE: I have asked REST questions before, this is for a completely separate array vendor than my previous questions

I have a SAN that requires an api token to be posted to a URL to initiate a session before a REST query will run.

I have a custom authentication module configured. And if I dump the response value, I can see that it is initiating the session correctly. (I get a response 200 and the username of the token I supplied, which is what is expected)

However, I get a "401 Unauthorized" when I enable the input. So it looks like the authentication module is not passing the session cookie back to the modular input itself.

Here is what my auth module looks like:

class PureSessionKeyAuth(AuthBase):

        def __init__(self,**args):
                self.auth_url = args['auth_url']
                self.api_token= args['api_token']
                pass

        def __call__(self, r):

                #perform auth
                headers = {'content-type': 'application/json'}
                token = {"api_token":self.api_token}
                req_args = {"verify" : False}
                auth_response = requests.post(self.auth_url,data=json.dumps(token),headers=headers,**req_args)
                response_json = json.loads(auth_response.text)

#  Use this to dump the values to validate if it is working correctly
#               f = open( 'values.dump', 'w' )
#               f.write( 'dict = ' + repr(token)+ '\n' + repr(auth_response) + '\n' + repr(response_json)    +'\n' )
#               f.close()

# I have tried the below code send the cookies back, with no luck.
                cookies = auth_response.cookies
                if cookies:
                        r.cookies = cookies
                return r

I do not get any errors on run other than the "401 Unauthorized" in splunkd when the input is enabled.

Tags (1)
0 Karma
1 Solution

david_rose
Communicator

I was able to get around this issue excessive restarting issue by creating my own python script utilizing the Requests library outside of splunk and monitoring the output folder.

View solution in original post

0 Karma

datasearchninja
Communicator

I have just been looking at an issue to fetch data from an endpoint that requires this approach. What I found is that setting the r.cookies values does NOT work, but setting the cookie directly in the header does...

e..g: This doesn't work:

if cookies:
   r.cookies = cookies

but this does:

if cookies and "myauthcookiename" in cookies:
  r.headers['Cookie'] = "myauthcookiename=" + cookies["myauthcookiename"])

david_rose
Communicator

I was able to get around this issue excessive restarting issue by creating my own python script utilizing the Requests library outside of splunk and monitoring the output folder.

0 Karma

acharlieh
Influencer

One idea, have you tried wiring Splunk and Postman up to make requests through a recording HTTP reverse proxy (such as Charles Proxy ) to compare the actual over the wire requests and responses from both? I wonder if that could confirm if no cookie is being added, or maybe something is getting garbled in translation.

0 Karma

david_rose
Communicator

Ahh thats a good idea. I will give that a shot.

0 Karma

Damien_Dallimor
Ultra Champion

Are you also using a custom response handler in responsehandlers.py ? The default response handler is supposed to persist cookies for you.

0 Karma

david_rose
Communicator

I have locked down the issue to the

cookieheader = "session=" + auth_response.cookies['session']

Section of my code. If i change the first session to an invalid value, i get an unauthorized. If I leave it as is, it gets stuck in a loop.

I also noticed these in splunkd.log:

sNS/nobody/search/data/inputs/rest/Pure%20Test%20DAL/: Broken pipe
09-11-2015 15:15:42.295 -0500 WARN  HttpListener - Socket error from 127.0.0.1 while accessing /servicesNS/nobody/search/data/inputs/rest/Pure%20Test%20DAL/: Broken pipe
09-11-2015 15:15:42.924 -0500 WARN  HttpListener - Socket error from 127.0.0.1 while accessing /services/data/inputs/ta_ontap_collection_worker/Pure%20Test%20DAL: Broken pipe
09-11-2015 15:16:04.290 -0500 WARN  HttpListener - Socket error from 127.0.0.1 while accessing /servicesNS/nobody/search/data/inputs/rest/Pure%20Test%20DAL/: Broken pipe

Especially strange is the listener warning that references ta-ontap-collection-worker. That seams to change. It said snmp earlier...

0 Karma

david_rose
Communicator

Looking at my inputs.conf, the cookie is not getting written back. There is no cookie field at all for this particular rest endpoint. I do see a cookie entry for other endpoints that don't require a custom auth handler.

The cookie I captured is in the following format if it helps. I'll keep trying in the mean time:

eJxFjMsKgzAQAH-l7NnDqlVqwEuhv9AeJftoKRgjm3gS_71WCj0OM8wKw6wW_KRTBpdt0QJGn_KgZtHA4Q9NOZocbHFUcCucCBzcH41R6Gp69T1sBaS3HG7ZXHrlXEqWqlE-Iz4JywqlrYUaj9x1335JapMP_yFXt8z1Nck-hm37ACghMaA.CNH60A.OfsdfgghosQol-GjpfDncvj5YuVs

0 Karma

david_rose
Communicator

PROGRESS!

While I could never get the cookie to pass back with the code above, i was able to get it by manually passing the cookie back in the header via this code:

def __call__(self, r):

        #perform auth
        headers = {'content-type': 'application/json'}
        token = {"api_token":self.api_token}
        req_args = {"verify" : False}
        s=requests.session()
        auth_response = s.post(self.auth_url,data=json.dumps(token),headers=headers,**req_args)
        cookieheader = 'session=' + auth_response.cookies['session']
        r.headers['Cookie'] = cookieheader
        return r

I get the response indexed just fine, BUT, it runs every second, which of course is a no go. Looking at the splunkd log, the output looks similar to when you save changes to the input.

Any Thoughts?

0 Karma

david_rose
Communicator

Not using a custom response handler.

0 Karma

david_rose
Communicator

Is my custom auth configured correctly for returning the cookie?

0 Karma

Damien_Dallimor
Ultra Champion

Looks fine to me.

0 Karma

rmdfrb
Explorer

Are you sure you aren't supposed to be sending that token as a header?

Here is an example of a working token auth handler I've written:

class TokenAuth(AuthBase):
  def __init__(self, username, password, domain, url, **kwargs):
    headers={'Content-Type':'application/json'}
    body=json.dumps({'userName':username, 'password':password, 'authLoginDomain': domain})
    r = requests.post(verify=False, url=url, headers=headers, data=body)
    if r.status_code==200 and 'sessionID' in r.json():
      self.sessionID = r.json()['sessionID']
    else:
      raise RequestException('Could not authenticate')
    pass

  def __call__(self, r):
    r.headers.update({'auth':self.sessionID, 'Content-Type':'application/json'})
    return r
0 Karma

david_rose
Communicator

Yes Im sure its not added as a header. When you post with the api token in the body, it replies with a cookie with a 30 minute expiration which contains the session information. I need to forward that cookie back to the input from the custom auth handler.

0 Karma

mreynov_splunk
Splunk Employee
Splunk Employee

Are you sure you have the right permissions setup in the target system? Just the fact that login work, does not guarantee access to a specific resource.

0 Karma

david_rose
Communicator

Yes. I can duplicate the steps in Postman which I use to validate my REST calls. It is not a permissions issue.

0 Karma
Get Updates on the Splunk Community!

Extending Observability Content to Splunk Cloud

Register to join us !   In this Extending Observability Content to Splunk Cloud Tech Talk, you'll see how to ...

What's new in Splunk Cloud Platform 9.1.2312?

Hi Splunky people! We are excited to share the newest updates in Splunk Cloud Platform 9.1.2312! Analysts can ...

What’s New in Splunk Security Essentials 3.8.0?

Splunk Security Essentials (SSE) is an app that can amplify the power of your existing Splunk Cloud Platform, ...