1

I'm trying to establish a connection using kerberos authentication. I think the question I have does not depend on the type of server (in my case it's a cognos tm1 server) nor the language (in my case R with use of the package httr (or RCurl)) since it's more a general http(s) thing.

I do not have much experience using kerberos. According to my understanding there is some negotiation between the client and server following the following steps (here get-requests). The only thin I need to pass is a username, no password is needed.

  1. get(url) -> returning a "WWW-Authenticate: Kerberos" header telling this authmethod is supported.
  2. get(url, header = Authentification: "Negotiate" + token) --> second request, this time with header information "Negotiate" plus token
  3. Server returns some authentification details.
  4. Received details can be sent in the header again and the requested data is sent back

httr (type = gssnegotiate) or curl (4 = CURLAUTH_NEGOTIATE) allow to enter negotiation types. I thought, this should do the negotiation process described above and return the requested data straight ahead. This does not seem to be the case:

library(httr)
httr::set_config(config( ssl_verifypeer = 0L))
httr::set_config(config( ssl_verifyhost = 0L))
GET(url, authenticate(user = "user", password = "", type = "gssnegotiate"), verbose = TRUE)

does not return the desired result. The log says:

-> GET /api/v1/Dimensions('Time')/Hierarchies('Time')/Subsets('Yesterday')/Elements HTTP/1.1
-> Host: myhostaddress.com:20049
-> User-Agent: libcurl/7.47.1 r-curl/1.2 httr/1.2.1
-> Accept-Encoding: gzip, deflate
-> Cookie: TM1SessionId=tbQcdXh4PsIHUQdkW_UyNQ
-> Accept: application/json, text/xml, application/xml, */*
-> 
<- HTTP/1.1 401 Unauthorized
<- Content-Type: text/plain
<- Content-Length: 0
<- Connection: keep-alive
<- OData-Version: 4.0
<- WWW-Authenticate: Kerberos
<- 
*  Connection #0 to host myhostaddress.com left intact

I tried the same using (R)curl

library(RCurl)
getURL(url, user = "username", userpwd="", httpauth = 4, verbose = TRUE, ssl.verifypeer = FALSE, ssl.verifyhost = FALSE)

Unfortunately, this wasn't successful as well:

< HTTP/1.1 401 Unauthorized
< Content-Type: text/plain
< Content-Length: 0
< Connection: keep-alive
< OData-Version: 4.0
< Set-Cookie: TM1SessionId=WMSrJHGTps0RIbmjCCaW5w; Path=/api/; HttpOnly; Secure
< WWW-Authenticate: Kerberos

Do you have any hints how I could get the desired data? I was also thinking about implementing the steps described above manually. By I'm stuck in step 2, because I do not have a token to send in the negotiation header (and do also not know where to get it from).

Cœur
  • 37,241
  • 25
  • 195
  • 267
Fabian Gehring
  • 1,133
  • 9
  • 24
  • Kerberos does not care about User / Password. You must first obtain a Kerberos ticket *(e.g. with `kinit` command on Linux which stores the ticket in a file cache)* so that your HTTP client has the ticket available for SPNEGO. – Samson Scharfrichter Jan 31 '17 at 15:40
  • You may also suffer from bugs if your package invokes an older version of `libcurl`, cf. https://curl.haxx.se/mail/tracker-2015-03/0030.html – Samson Scharfrichter Jan 31 '17 at 15:56
  • The real question is: are you working on Windows, with the Microsoft implementation of Kerberos (SSPI), or on Linux / OSX, with the "regular" implementation (GSSAPI)? – Samson Scharfrichter Jan 31 '17 at 16:55
  • On Linux you should try `curl --negotiate -u ':' --trace-ascii - (your-URL-here)` to see how things work i.e. the initial attempt, triggering a 401 reply with "WWW-Authenticate: Negotiate", then the second attempt with "Authorization: Negotiate (token-in-Base64-encoding)". Provided that your Kerberos config is valid, that you have a valid Kerberos ticket in the cache, and that your version of curl supports `GSS-Negotiate` (check with `curl -V`) – Samson Scharfrichter Jan 31 '17 at 17:02
  • @Samson Scharfrichter Thanks for your answers. Actually I am using Windows 7. So might be that all my attempts will only work using linux? Is there a way to do all this in Windows? – Fabian Gehring Jan 31 '17 at 18:13
  • Ahhhhhh... the Windows ecosystem is a very different beast. Does your R package use a version of `libcurl` that was compiled specifically for Windows, and supports `SSPI Kerberos SPNEGO`??? – Samson Scharfrichter Jan 31 '17 at 19:22
  • Plus, does the web server support the Microsoft implementation of Kerberos? I never had any success using curl-for-Windows-with-SSPI to connect to a kerberized Hadoop service, for instance. Had to develop a custom Java app instead. But maybe it was because of that curl bug mentioned in the link above... – Samson Scharfrichter Jan 31 '17 at 19:32

2 Answers2

0

This won't work because the server requires WWW-Authenticate: Kerberos, but curl only talks SPNEGO. Modify your server to request WWW-Authenticate: Negotiate and it will work.

Note: no major browser supports pure Kerberos over HTTP, so don't expect any other library to do so.

Michael-O
  • 18,123
  • 6
  • 55
  • 121
0

On Windows, you can use

library(httr)
GET(url, authenticate(user=":", password="", type="gssnegotiate"), verbose = TRUE)

Or if no proxy is required for an internal website, state no proxy explictly as follows:

library(httr)
GET(url, use_proxy(""), authenticate(user=":", password="", type="gssnegotiate"), verbose = TRUE)
chinsoon12
  • 25,005
  • 4
  • 25
  • 35