adding NTLM authentication support

Adding support for NTLM authentication. Relies on https://github.com/bnoordhuis/python-ntlm.


This looks rather elegant.


This works for me unless I attempt to download with prefetch=False, at which point I get 401 - Unauthorized.


I'm not able to replicate this:

```
>>> requests.get('http://192.168.172.134:8080/NANS1dT4').headers
{'connection': 'close', 'content-type': 'text/html', 'www-authenticate': 'NTLM', 'content-length': '0', 'server': 'Apache'}
>>> requests.get('http://192.168.172.134:8080/NANS1dT4',auth=requests.auth.HttpNtlmAuth('dfghdfgh\\sdfg','asdfasdf'))
<Response [200]>
>>> requests.get('http://192.168.172.134:8080/NANS1dT4',auth=requests.auth.HttpNtlmAuth('dfghdfgh\\sdfg','asdfasdf'),prefetch=True)
<Response [200]>
>>> requests.get('http://192.168.172.134:8080/NANS1dT4',auth=requests.auth.HttpNtlmAuth('dfghdfgh\\sdfg','asdfasdf'),prefetch=False)
<Response [200]>
```

Can you give more details?


I see a difference in usage that may account for you not being able to reproduce it like that. Possibly an incorrect usage - I don't know the internals of requests well enough yet. I have patched support for this into my copy of the 'easywebdav' library. If you look at the original code (it's short, and my only change from that is to patch in the HttpNtmlAuth) at https://github.com/amnong/easywebdav/blob/master/easywebdav/client.py you'll see that it creates a session, sets the auth on that, and then repeatedly makes direct requests against that session. In your example, you're passing the auth details directly with the request. Could that be the difference?


That shouldn't be an issue:

```
>>> s = requests.session()
>>> s.auth = requests.auth.HttpNtlmAuth('dfghdfgh\\sdfg','asdfasdf')
>>> s.get('http://192.168.172.134:8080/NANS1dT4')
<Response [200]>
>>> s.get('http://192.168.172.134:8080/NANS1dT4',prefetch=True)
<Response [200]>
>>> s.get('http://192.168.172.134:8080/NANS1dT4',prefetch=False)
<Response [200]>
```

I am not using a proper Windows server to test this against because I don't have one. It could be an issue resulting from the janky server I am using... Is there any way you could send the requests through a proxy and paste in the request/response headers from the logs?


well, looking at your code again, you don't apear to be using the NTLM authentication. It looks like you are trying to do basic auth. 


Yep, that's not my code, I've just patched one of your auth objects into my local copy of that in the hope of getting it working. (A remote server we've been using happily for years has suddenly turned off all auth options except ntlm).

I'm looking into my options for getting some better diagnostics, headers, etc. I don't think a proxy is an option for us.


gotcha


Unrelated to this bug, depending on your situation, you could probably get away with something like this for faking NTLM auth http://ntlmaps.sourceforge.net/


This looks good and it worked perfectly for me. However, the link to the python-ntlm library isn't correct. The most updated source of the library is on [Google Code](http://code.google.com/p/python-ntlm) not Github. A fairly recent version can be fetched from pypi.

With that said, I have no strong opinion about whether this should be in requests proper or in a separate add-on library.


Yeah. I just committed some changes to the google code one today. I just
hate svn so I have been using the GitHub one for testing. Pip one works
too.

I too would be fine with putting it in a separate project if people think
that would be better. Pros? Cons?

Ben Toews

On Nov 12, 2012, at 18:45, David Fischer notifications@github.com wrote:

This looks good and it worked perfectly for me. However, the link to the
python-ntlm library isn't correct. The most updated source of the library
is on Google Code http://code.google.com/p/python-ntlm not Github. A
fairly recent version can be fetched from pypi.

With that said, I have no strong opinion about whether this should be in
requests proper or in a separate add-on library.

—
Reply to this email directly or view it on
GitHubhttps://github.com/kennethreitz/requests/pull/934#issuecomment-10311211.


Use git-svn @mastahyeti ;)


In the past I would have said let other libraries handle this, but lately there's been a push to include other authentication mechanisms (Kerberos, OAuth, etc) into requests proper even if they have dependencies. If that's the route the library is going then I say include this patch.

There are no tests that go with this patch, but there aren't any that go with the Kerberos auth either. I'm not sure how easy an authentication handler like this is to test since setting up a simple test server for NTLM auth is probably more complicated than it is worth.


That has been my feeling also.

Ben Toews

On Nov 14, 2012, at 12:46, David Fischer notifications@github.com wrote:

In the past I would have said let other libraries handle this, but lately
there's been a push to include other authentication mechanisms (Kerberos,
OAuth, etc) into requests proper even if they have dependencies. If that's
the route the library is going then I say include this patch.

There are no tests that go with this patch, but there aren't any that go
with the Kerberos auth either. I'm not sure how easy an authentication
handler like this is to test since setting up a simple test server for NTLM
auth is probably more complicated than it is worth.

—
Reply to this email directly or view it on
GitHubhttps://github.com/kennethreitz/requests/pull/934#issuecomment-10378250.


The lack of tests (both here and on Kerberos) makes me nervous about having them in the mainline build (because they'd have to be supported), but they're absolutely things Requests should be able to do. The problem with leaving them outside the mainline is that their discoverability becomes crappy, and so we'll get lots of people asking here and on SO how to do NTLM auth.

I wonder if we can find some way to have some kind of 'official' set of Requests plugins for the broader range of authentication methods. This would leave these authentication methods under the control of the people who know something about them (i.e. not me =D ), but still make it easy for people to find and use them with Requests. I'm thinking a drop-in plugin, e.g.

```
pip install requests
pip install requests-ntlm
```

And then:

``` Python
import requests
from requests_ntlm import NTLMAuth

auth = NTLMAuth('lukasa', 'notmypassword')
r = requests.get('http://httpbin.org/get', auth=auth)
```

and so on.

Eh, I dunno. Thoughts?


@Lukasa I'd feel much more comfortable with that myself :)


Cool. I'll have a think this evening about how best to handle this. Maybe something in the docs.

In the meantime, @mastahyeti, how do you feel about acting as maintainer of a Requests NTLM authentication package?


Why not start a requests organization? Maintainers of add Jonsson get their own team. That team alone has push privileges to that package /repo. We could even mirror requests there.


Sounds like a good idea, @sigmavirus24. I won't look into it until I finish work, but that combined with some documentation might be a good way to keep everything together.


Documentation makes everything better. Let's just wait on @kennethreitz to make the org if he agrees. 


Interesting. I wouldn't want requests there myself, but everything around it could exist there. 


@kennethreitz Yeah, that occurred to me too. I wouldn't have proposed moving it: it's yours, and besides, we'd break ALL THE LINKS. I then thought about mirroring requests, but that's also a bad idea: there should only be one place on Github where you can go for requests itself.

Otherwise, that might be a decent idea. What auth stuff would we move? (This, obviously, but what else would you like to pull out?)


GitHub should have org repo aliasing :)


This for now. OAuth, potentially, but the name is already taken. 


This will align with the current refactor of requests that is underway. I'll create the org.

We can also move the documentation forks (fr/jp) there.

We need a logo too :)


_/me casually deletes out-of-date post._

Awesome, sounds good to me. @mastahyeti, you cool with maintaining a repo there instead of this pull request?


Created! https://github.com/requests/requests-ntlm


I'm actually not a fan of the duplicated namespace, but it may be the best option.


@mastahyeti, you should have push access to the repo now :)


Yeah, the duplicated namespace is weird. Probably better for `pip` though.

I quite want to pull Kerberos out of `auth.py` too, but I don't want to do it until we can find a maintainer. Might see if I can get myself up to speed on Kerberos, actually.