Django to do its own NTLM Authentication (HTTP Headers & all) - python

I'm considering moving from Apache to Lighttpd for an internal web application, written with python. The problem is that I'm relying on libapache2-mod-auth-ntlm-winbind ... which doesn't actually seem to be a well support & updated package (though that could be because it really does work well).
I'm looking for suggestions and hints about what it would take to use django itself to handle the HTTP authentication. This would allow me to be web-server-agnostic, and could potentially be a grand learning experience.
Some topical concerns:
Is it reasonable to have the custom application perform true HTTP authentication?
How involved is getting my python code connected to windows domain controller to this kind of authentication without prompting the user for a password?
Does NTLM provide any access to user details & group memberships so that I can stop searching through yet another connection to the windows domain controller via LDAP?
I would love to be able to write a module to simplify this technique which could be shared with the community.

Partial answer:
You can (and should) pass the NTLM auth off to an external helper. Basically, install Samba on the machine, configure it, join the domain, enable winbind, then use the "ntlm_auth" helper binary, probably in "pipe" mode.
Authenticating an NTLM session requires a secure pipe to the domain controller, which needs credentials (e.g. a Samba/domain-member machine account). This is the quickest route to get there.
Squid (the webcache) has code for doing NTLM auth using the external helper; FreeRadius does something similar.
The NTLM auth itself does not provide any group info; if you're running winbind you could of course use calls to "wbinfo" to get user groups.

Related

How to pass HTTP/HTTPS proxy credentials to boto3?

How can a proxy username & password be passed to boto3 without using environment variables?
There is a similar stack question, however the question & answer focus on the url/port specification. I am sitting behind a corporate proxy and need to also specify user credentials; but I am not allowed to put my login credentials in an environment variable.
I will have to read the username/password into memory, but once I have them where in boto3 do they get inputed?
Thank you in advance for your consideration and response.
Proxy configuration for boto3 is described here.
Passing username and password is not documented, however if you look at the underlying code (httpsession.py), it will extract username and password from a URL like https://username:password#example.com:443, and insert a Proxy-Authorization header using basic auth.
If that works with your company, you should be OK. However, some proxies require a different authorization method, and this will fail.
In that case will need to discuss your company's exact proxy mechanism with your IT group. They may suggest work-arounds, such as running your own proxy to handle authentication. Or they may permit you to use a cloud development tool that avoids the use of proxies.
I mention this because your deployment environment -- whether cloud or a local data center -- probably doesn't use an authenticating proxy. Which means that code written with the expectation of such a proxy won't work in a production deployment.

How to secure my Azure WebApp with the built-in authentication mechanism

I created a Flask-Webservice with Python that runs independently inside a docker container. I then uploaded the docker image to an Azure Container Registry. From there I can create a WebService (for Containers) with some few clicks in the Azure Portal, that runs this container. So far so good. It behaves just as I want it to.
But of course I don't want anyone to access the service. So I need some kind if authentication. Luckily (or so I thought) there is a built-in authentication-mechanism (I think it is based on OAuth ... I am not that well versed in security issues). Its documentation is a bit sparse on what actually happens and also concentrates on solutions in C#.
I first created a project with Google as described here and then configured the WebApp-Authentication with the Client-Id and Secret. I of course gave Google a java script source and callback-url, too.
When I now log off my Google account and try a GET-Request to my Webservice in the Browser (the GET should just return a "hello world"-String), I am greeted with a Login Screen ... just as I expected.
When I now login to Google again, I am redirected to the callback-url in the browser with some kind of information in the parameters.
a token perhaps? It looks something like this:
https://myapp.azurewebsites.net/.auth/login/google/callback?state=redirxxx&code=xxx&authuser=xxx&session_state=xxx&prompt=xxx).
Here something goes wrong, because an error appears.
An error occurred.
Sorry, the page you are looking for is currently unavailable.
Please try again later.
If you are the system administrator of this resource then you should check the error log for details.
Faithfully yours, nginx.
As far as I now, nginx is a server software that hosts my code. I can imagine that it also should handle the authentication process. It obviously lets all requests through to my code when authentication is turned off, but blocks un-authenticated accesses otherwise and redirects to the google login. Google then checks if your account is authorized for the application and redirects you to the callback with the access token along with it. This then returns a cookie which should grant my browser access to the app. (I am just reproducing the documentation here).
So my question is: What goes wrong. Does my Browser not accept the cookie. Did I something wrong when configuring Google+ or the Authentication in the WebApp. Do I have to use a certain development stack to use the authentication. Is it not supported for any of the technologies I use (Python, Flask...).
EDIT
#miknik:
In Microsofts documentation of the authentication/authorization it says
The authentication and authorization module runs in the same sandbox
as your application code. When it's enabled, every incoming HTTP
request passes through it before being handled by your application
code.
...
The module runs separately from your application code and is
configured using app settings. No SDKs, specific languages, or changes
to your application code are required.
So while you are probably right that the information in the callback-redirect is the authorization grant/code and that after that this code should now be used to get an access token from Google, I don't quite understand how this would work in my situation.
As far as I can see it Microsofts WebApp for Container-Resource on Azure should take care of getting the token automatically and return it as part of the response to the callback-request. The documentation states 4 steps:
Sign user in: Redirects client to /.auth/login/.
Post-authentication: Provider redirects client to /.auth/login//callback.
Establish authenticated session: App Service adds authenticated cookie to response.
Serve authenticated content: Client includes authentication cookie in subsequent requests (automatically handled by browser).
It seems to me that step 2 fails and that that would be exactly what you wrote: that the authorization grant is to be used by the server to get the access token but isn't.
But I also don't have any control over that. Perhaps someone could clear things up by correcting me on some other things:
First I can't quite figure out which parts of my problem represent which role in the OAuth-scheme.
I think I am the Owner, and by adding users to the list in the Google+-Project I authorize them to use my service.
Google is obviously the authorization server
my WebService (or better yet my WebApp for Containers) is the resource server
and finally an application or postman that does the requests is the Client
In the descriptions of OAuth I read the problematic step boils down to: the resource server gets the access token from the authorization server and passes it along to the client. And Azures WebApps Resource is prompted (and enabled) to do so by being called with the callback-url. Am I right somewhere in this?
Alas, I agree that I don't quite understand the whole protocol. But I find most descriptions on the net less than helpful because they are not specific to Azure. If anyone knows a good explanation, general or Azure-specific, please make a comment.
I found a way to make it work and I try to explain what went wrong as good as I can. Please correct me if I go wrong or use the wrong words.
As I suspected the problem wasn't so much that I didn't understand OAuth (or at least how Azure manages it) but the inner workings of the Azure WebApp Service (plus some bad programming on my part). Azure runs an own Server and is not using the built-in server of flask. The actual problem was that my flask-program didn't implement a WSGI-Interface. As I could gather this is another standard for python scripts to interact with any server. So while rudimentary calls from the server (I think Azure uses nginx) were possible, more elaborate calls, like the redirect to the callback url went to dev/null.
I build a new app following this tutorial and then secured it by following the authentication/authorization-tutorial and everything worked fine. The code in the tutorial implements WSGI and is probably more conform to what Azure expects. My docker solution was too simple.
My conclusion: read up on this WSGI-standard that flask always warned me about and I didn't listen and implement it in any code that goes beyond fiddeling around in development.

How to register an oauth2 client?

I'm writing an oauth2 provider and am not sure how to implement client registration. The oauth2 specification doesn't cover this aspect:
The means through which the client registers with the authorization server are beyond the scope of this specification but typically involve end-user interaction with an HTML registration form.
Moreover, the oauthlib documentation has the following to say about the Client data model:
It is common practice to link each client with one of your existing users. Whether you do associate clients and users or not, ensure you are able to protect yourself against malicious clients.
Now I sure would love to protect myself against malicious clients, but how can I link a client to a user if registering a user requires a registered client?
The oauth2 spec again has something to say about this, but it's very cryptic:
Client registration does not require a direct interaction between the client and the authorization server. When supported by the authorization server, registration can rely on other means for establishing trust and obtaining the required client properties (e.g., redirection URI, client type). For example, registration can be accomplished using a self-issued or third-party-issued assertion, or by the authorization server performing client discovery using a trusted channel.
Questions
How should a client be registered if linking to a user is required, given that registering a user requires a registered client?
How should a client be registered if linking to a user is not required? What is meant by 'redirection URI, client type, and third-party-issued assertion?
When answering this question, I am going to assume there is already an access control framework that this provider will be attached to, and the application that will use this provider will have HTTP access and has capabilities to handle HTML forms, as no details on this whatsoever were provided by the question (i.e. what framework is this provider going to sit on, or is it something completely naked and standalone on some homebrewed framework).
I'm writing an oauth2 provider and am not sure how to implement client registration. The oauth2 specification doesn't cover this aspect:
The means through which the client registers with the authorization server are beyond the scope of this specification but typically involve end-user interaction with an HTML registration form.
While it doesn't spell it out explicitly, it did suggest that typical registration of a client involves end-user interaction with a form. If you see how others have done it (such as through imgur's API, OAuth 2 user documentation) you will find that it provides a Registration link and hey that's how clients are registered. No OAuth 2 is required as you are already authenticated via the browser.
Now I sure would love to protect myself against malicious clients, but how can I link a client to a user
By linking your server applications's representation of the client details to the user (tracked by some system) that created those client details? It's not like user specific data suddenly becomes more mystical just because it is used for authenticating an OAuth2 client. If you find abuse related to access using those client details (from your logs) you could just revoke those credentials related to that client, and punish the user that own that client. (Unless it's their clients... erm, your other users using that client is doing the abuse but you should be able to see that, right?)
if registering a user requires a registered client?
If you really want to have people register their clients using their client before they register their client, that's pretty much madness (i.e. a chicken and egg problem that shouldn't need to exist). Nowhere in the specification this was ever suggested that they are mutually inclusive problems. Here, to simplify this:
You can use a registered client to register a user
You can register a client to a registered user
Those two things are completely separate from each other. You have to have one before the other (actually, you can create a user registration form that also generates a client credentials at the same time, but I digress), but really, a registered client is essentially reducible to some credentials that are shared between that client and the provider it is registered against.
You can make your own registered clients, too, since you have full control of the provider, you can inject any credentials that will be used by that registered client of yours to do whatever you need, including registering new users, but...
How should a client be registered if linking to a user is required, given that registering a user requires a registered client?
You know you can just register a user using a standard HTML registration form? Just use the user registration form that the framework provided, or write one* if that framework doesn't already provide one.
How should a client be registered if linking to a user is not required?
When I implemented an OAuth1 provider for Plone, client registration can only be done by administrators/managers of the site, so not something user can do, thus someone has to contact the owners of the site to find out how to do it. This generally removes the security problems associated with not linking clients to users (since clients are now linked to actual people coding those clients up who are not necessarily users of the site through external means).
I realized I did not really answer this question, but this is really up to your implementation and what needs/restrictions you decide to limit/provide. I mean you can have a totally anonymous form on your site and let it rip, but I don't think you want that as that weakens security of your application dramatically.
What is meant by 'redirection URI, client type, and third-party-issued assertion?
If you go to the sections as specified in the RFC, you will find answers there:
Redirection URI
There is actually quite a lot of ways to subvert the security of your users' (resource owner's) data if this is not carefully understood, but is used by the authorization server to "redirects the resource owner's user-agent back to the client", as the authorization is done on the authorization server which is part of the provider's infrastructure. So in general, the client has to let the authorization server know where/how it gets back to itself after the resource owner authorizes the client's access through this redirection URI. However, if the redirection URI specified is not verified, security issues can and will happen.
For instance, native applications (a client profile of the client type public) will (used to, I am coming from an OAuth1 background) have the complete client credentials embedded inside the application, which will be extracted by hostile attackers in a bid to masquerade as a legitimate web application (another client profile, but can be considered as a confidential client type) that makes use of your application's services. Once the hostile attackers are up and running they will entice your users (resource owners) to use their masqueraded site, and grant the masqueraded site their access tokens through your authorization server and if redirection URIs are not validated, it will redirect your users (resource owners) to the attacker with the authorization code (as outlined in section 1.3), giving the attacker access to your resource owner's data.
That was the easy common case - another problem case is that your other web application client might have a credential leak without them knowing, resulting in this exact scenario.
Hence this is why they suggest that you should only "redirect the user-agent to the client's redirection endpoint previously established with the authorization server during the client registration process... after completing its interaction with the resource owner", which can mean that only the domain name registered to that client will be legitimate redirection targets, otherwise something went wrong and your authorization server aborts and does not provide the authorization grant.
Client Types
Again, just read/scrutinize all that carefully.
Third-party-issued assertion
As opposed to self-issued client registration done kind of like a client registration form, your application might delegate the client authentication to a third party which will do the verification for you. If you have to worry about this and don't know where to start I suggest you ignore this and just only do self-issued client.
* Are you really sure you want to write an OAuth2 provider without any underlying user/ACL framework for you to hook this to? I mean you can write one but you should really build that part first before you worry about OAuth2 (again, I am not making any assertion, since the question provided no information on this).
Now, if you are not doing this as part of some existing framework but just something standalone that you want to toy/try out as learning, I strongly suggest you to pick something else because this is probably beyond what you can do in a correct manner. Especially if you don't already fully understand the implication of this with regards to the underlying ACL and security of the resource owner's data, and other related stuff.
No offense, but these things are very very difficult to do correctly. Even the bigger companies have had security issues with their OAuth2 solutions.
Finally, speaking from experience, I spent about four (4) weeks (!) staring at the OAuth1 specification years ago, using a poorly written Python OAuth library (later replaced with oauthlib, which is much better) in an attempt to build an OAuth1 provider on top of Plone, before I got a single line of code directly related to the provider committed. A lot of junk/trial code written was thrown away, and this was done because understanding all of this stuff actually took time (granted, I was not exactly working full time on this, had other responsibilities too which was distracting me from this). Another part of the time was spent trying to understand how the user/security stuff is put together at the Zope/Plone layer. Granted I was still relatively new to that side of that framework, but I can guarantee you that this road is not going to be easy... however I did seem to find that OAuth 2 cleaned things up in some ways to make it easier to understand, but find that the security may have been weakened. That said, I currently have no immediate plans to port my Plone addon to support 2.0 as my sponsors does not require that, so there may be things I suggested up there that may differ slightly from 2.0. Would love to hear your comments if others have read this far. I wrote way more words than I originally intended to, oops.
Anyway, good luck on your adventures.
Additionaly for dynamic registration, please go through this spec as well
https://www.rfc-editor.org/rfc/rfc7592

One login for multiple products

There are multiple mobile apps.
I want people using one app to login with their same login credentials into all other apps.
What is the best approach to implement this?
I'm thinking to create a separate authorization server that will issue tokens/secrets on registering and logins. It will have a validation API that will be used by mobile app servers to validate requests.
There is a protocol for handling this called Central Authentication Service(http://www.jasig.org/cas), or CAS. CAS utilizes OAuth2 protocol to provide a secure way to manage a single sign on procedure -- users have a single login credential that is used via tokens and proxy tickets to authenticate the user across a variety of applications using a single CAS authentication server. This is a procedure the company I work for uses to authenticate users across multiple applications (we use Java with Spring Security and Spring CAS) however this summer we built out a proof of concept with Django and an internal company API in which we implemented CAS procedure with the Django application -- Django authenticated users via the CAS server we run and returned them as valid, authenticated Django users. To do this we used the django-cas middleware and custom backend library which can be found here: https://bitbucket.org/cpcc/django-cas/overview.
CAS is definitely the way to go if you're looking to handle user authentication with a single sign on across multiple applications -- it was the reason CAS was created in the first place. The learning curve with CAS can be a little steep but django-cas does a good enough job making it easy to get set up with CAS in the Django project.
First check if OAuth could be adapted to using this, that would save you a lot of work. Of course all the services and apps would have to talk to some backend network server to sync tokens issued to apps.
Half-secure/maybe-abusable solution: have symmetric cipher encrypted cookie that webpages (and apps?) hold and use it for authorization with different network services (which again have to verify cookie for authorization with authorization service that knows the passphrase used to encrypt the cookie)
I've used approach #2 on internal systems but I am not sure if it is advisable to use it in in the wild - this may pose some security risks.
The authentification method in every application connects to the same webservice for autentification.

Client authorization with python backend

I'm writing panel for administrating nginx (domains, rewrites, etc), svn and other services. For that, i'm writing backend that will work on root (to change nginx configs, reload them, change user passwords, etc), and client (console client, and web app).
App works on unix sockets, and i made very simple protocol for it:
\0\0\0\0user\0key\0module\0command\0data\0
Well, this is quite simple. Client sends command and data to backend, fox ex:
\0\0\0\0morsik\0\0nginx\0add_domain\0www.domain.tld something\0
Problem is, how to authenticate that user is really morsik? For web interface i don't have to - web page have it's own authorization so i can sent some key that will work for every user that nobody will know.
Problem is if somebody have access to ssh. Then he could write simple client that will spoof username and then he could change other user configuration.
So, how can i made correct authorization for users?
Don't reinvent the wheel. ;) I found this discussion enlightening:
http://cyberelk.net/tim/2007/03/08/cups-unix-domain-sockets-authentication/ Explains the concept of socket auth.
http://pythonic.pocoo.org/2007/7/7/unix-socket-credentials-with-python Helpful details.
http://atlee.ca/software/pam/ This might work also, though less convenient.
Create a group for app admins only, etc.

Categories

Resources