splunk / splunk-sdk-python

Splunk Software Development Kit for Python
http://dev.splunk.com
Apache License 2.0
687 stars 369 forks source link

Support for authorization tokens read from .splunkrc #388

Closed UnitedMarsupials closed 2 years ago

UnitedMarsupials commented 3 years ago

Is your feature request related to a problem? Please describe. Our Splunk-administrators here issue authorization-tokens to application-maintainers, instead of user/password credentials. For example, the HTTP-request in our current Python code (using "requests" API) begins with:

                req = requests.Request(
                        'POST',
                        'https://%s:%s/services/collector/event' % (host, port),
                        headers = {
                                'Authorization': 'Splunk %s' % SplunkToken
                        },
                        json = body
                )

Unfortunately, the documented .splunkrc syntax does not allow to specify token and, presumably, the code, which reads the file, would not make use of it either.

Describe the solution you'd like Allow users to use the token (or authtoken), whether read from .splunkrc, or command-line, or passed as a function-argument.

Describe alternatives you've considered I may give some other -- unofficial -- Splunk client Python-libraries a shot, until this is implemented. Or -- continue using our own :(

lrsmith commented 3 years ago

@UnitedMarsupials I recently ran into this. The Splunk Python SDK does support tokens ( https://github.com/splunk/splunk-sdk-python/pull/282/files ) but the examples and utils do not.

https://github.com/splunk/splunk-sdk-python/blob/master/utils/__init__.py#L26 is used by all the examples to parse arguments and if it doesn't define splunkToken it will throw an error. The examples pass in an empty dict so it uses the default SPLUNK_RULES. https://github.com/splunk/splunk-sdk-python/blob/master/examples/oneshot.py#L42

I was able to define my own 'rules,' pass it into the util.parse method, and authenticate using a splunkToken specified in .splunkrc.

Another issue though is that it looks like the utils is purely for the examples and tests, and it is not bundled up in the install packages.

hogoboom commented 3 years ago

I ran into the same issue. As @lrsmith mentions, it basically comes down to the utils/init.py. I modified a forked branch to include splunkToken as a valid argument. Once done, you can specify splunkToken=[token] in your .splunkrc or config file and it should work. Works for me at least.

See: https://github.com/hogoboom/splunk-sdk-python/commit/d573c6f25c5f5e0e83847fd45c57c8112fa88b20

ashah-splunk commented 3 years ago

Hi @UnitedMarsupials , latest Python SDK supports authorisation by passing session-key or bearer-token as arguments to the client.connect method. Please find below code snippets for authorisation using tokens

#Using bearer token
import splunklib.client as client
service = client.connect(host='localhost',
                         splunkToken=<bearer-token>,
                         autologin=True)
#Using session token
import splunklib.client as client
service = client.connect(host='localhost',
                         token=<session-key>,
                         autologin=True)
ncanumalla-splunk commented 3 years ago

As mentioned in above comment, authorization tokens are supported in the SDK as function arguments. Renaming this issue to provide enhancement for reading the auth tokens from a .splunkrc file.

akaila-splunk commented 2 years ago

Hi @UnitedMarsupials , We have added support for reading authorization token from .splunkrc file. Use bearerToken flag for Bearer token and sessionKey for Session Key and also we can pass them as argument to run examples. PR for reference - Add Support for authorization tokens read from .splunkrc #409

UnitedMarsupials commented 1 year ago

Use bearerToken flag for Bearer token and sessionKey for Session Key

Neither of the above verbs worked -- but specifying token in the form of Splunk our-submit-only-token does result in the Authorization-header being of exactly the form, that our own code uses (see ticket-description).

Unfortunately, although the splunklib.client.connect() works now, the subsequent attempts to submit an actual event all fail. The code like:

from splunklib import client
...
service = client.connect(**splunkrc.defaults())
service.indexes[index].submit(message, **conf)

causes the following GET-request sent to the server:

GET /services/data/indexes/FOO HTTP/1.1
Accept-Encoding: identity
Content-Length: 0
Host: localhost
User-Agent: splunk-sdk-python/1.7.2
Accept: */*
Connection: Close
Authorization: Splunk our-submit-only-token

which invariably fails with a 404.

Neither our current Python code (which uses the standard requests module directly), nor the Java Splunk library attempt such a GET-request as above -- they simply POST the event to /services/collector/event/1.0, where the same index is specified inside the JSON-body.

Why does Python SDK implementation insist on verifying the index first? And why does the verification fail?

Although I filed the splunk/splunk-app-examples#34, I suspect, the support for tokens is still incomplete.