I would like to use OpenID authentication in a small Pyramid web application. Most projects I found are old and/or their status is unclear. My requirements are quite simple:
I want to protect access to some parts of the app. It's no high security stuff, but I don't want to care about user registration, password encryption, ... No fancy integration of multiple authentication sources, ...
Is there a simple, known working solution?
I used velruse in the past to have OpenID authentication on Pyramid, and it worked well.
However, if what you want is just a way to authenticate users without dealing with the boring parts, Mozilla Persona might be what you are looking for. One of the advantages over OpenID is that any email address can be used to log in; it's not limited to OpenID addresses. There an easy-to use library to use it with persona (disclaimer : I wrote it).
Related
Here is the situation:
We use Flask for a website application development.Also on the website sever, we host a RESTful service. And we use Flask-login for as the authentication tool, for BOTH the web application access and the RESTful service (access the Restful service from browsers).
Later, we find that we need to, also, access the RESTful from client calls (python), so NO session and cookies etc. This gives us a headache regarding the current authentication of the RESTful service.
On the web, there exist whole bunch of ways to secure the RESTful service from client calls. But it seems no easy way for them to live together with our current Flask-login tool, such that we do not need to change our web application a lot.
So here are the question:
Is there a easy way(framework) so the RESTful services can support multiple authentication methods(protocols) at the same time. Is this even a good practice?
Many thanks!
So, you've officially bumped into one of the most difficult questions in modern web development (in my humble opinion): web authentication.
Here's the theory behind it (I'll answer your question in a moment).
When you're building complicated apps with more than a few users, particularly if you're building apps that have both a website AND an API service, you're always going to bump into authentication issues no matter what you're doing.
The ideal way to solve these problems is to have an independent auth service on your network. Some sort of internal API that EXCLUSIVELY handles user creation, editing, and deletion. There are a number of benefits to doing this:
You have a single authentication source that all of your application components can use: your website can use it to log people in behind the scenes, your API service can use it to authenticate API requests, etc.
You have a single service which can smartly managing user caching -- it's pretty dangerous to implement user caching all over the place (which is what typically happens when you're dealing with multiple authentication methods: you might cache users for the API service, but fail to cache them with the website, stuff like this causes problems).
You have a single service which can be scaled INDEPENDENTLY of your other components. Think about it this way: what piece of application data is accessed more than any other? In most applications, it's the user data. For every request user data will be needed, and this puts a strain on your database / cache / whatever you're doing. Having a single service which manages users makes it a lot nicer for you to scale this part of the application stack easily.
Overall, authentication is really hard.
For the past two years I've been the CTO at OpenCNAM, and we had the same issue (a website and API service). For us to handle authentication properly, we ended up building an internal authentication service like described above, then using Flask-Login to handle authenticating users via the website, and a custom method to authenticate users via the API (just an HTTP call to our auth service).
This worked really well for us, and allowed us to scale from thousands of requests to billions (by isolating each component in our stack, and focusing on user auth as a separate service).
Now, I wouldn't recommend this for apps that are very simple, or apps that don't have many users, because it's more hassle than it's worth.
If you're looking for a third party solution, Stormpath looks pretty promising (just google it).
Anyhow, hope that helps! Good luck.
I'm trying to understand OAuth, and I'm having a hard time figuring this basic thing out...
I have developed a service (with Python and Flask), which supports classic authentification through a dedicated login & password combination, and an "official" client in the form of a webapp. I would like my service to support OAuth and looked into flask-oauthprovider, which seems like a perfect fit for this task, but I can't seem to understand how everything should articulate.
My questions are:
Today, all my API entry points required the user to be logged in: once my service supports OAuth, should every entry points become "oauth_required" rather than "login_required"?
What is the proper way to support my "official" webapp front-end? I'd rather not have it go through the regular OAuth flow (with the extra redirections to login on the service). Should it go through OAuth with automatically granted access tokens, or should it bypass OAuth and directly use the "resource owner" login & password?
I think one of the problems with the concept behind oauthlib is that it tries too hard to be everything and the result is a difficult-to-reason-about set of abstractions (this is very similar to the python-oauth2 approach). OAuth providers in particular are tricky because you implicitly need to persist things like tokens not to mention the assumption of some kind of pre-exisiting user management. As such a "good" or idiomatic implementation tends to be more opinionated from framework to framework. In my opinion this is part of why we don't see a single Python OAuth provider implementation as an abstraction: there just aren't great solutions, but plenty of messy ones. Looking at flask-oauthprovider and we see some direct examples of these issues. I've had similar problems with flask-login, which I maintain. At any rate, this past weekend I wrote a very rough first pass of a OAuth provider in Flask that "just works"; feel free to take a look and adapt it to your needs. It assumes some things like, like MongoDB but with minimal work I think any datastore could be used.
1) Protect whichever endpoints you want to be accessible via a third-party, e.g. your public API.
2) I would avoid automatic access tokens, that defeats the person of negotiating authorization on a per-user basis, unless of course you have a different scheme, e.g. a predefined set of clients. I believe the second option you're talking about is xauth, in which case, why not just use OAuth 2.0 and grant_type=password? Bearer tokens are similar in concept but may be a little easier to implement so long as you can provide HTTPS.
I am considering a 3rd part Authentication system for logging in (new/old) users. Much like how StackOverflow authenticates it's users. This scheme is good as it frees me from doing authentication from my side. I need this -
Login using Google, Facebook, Twitter, Yahoo, OpenID Authentication Systems.
Provide the same user logged in functionality as the default django auth system i.e. #login_required decorators should work
There seem to be some number of Django-apps out there which claim to solve this problem. Which ones are good?
Ex. Django-SocialAuth, django-openid-auth
For an all-in-one solution, I had good results with django-socialregistration. It has auth backends for Twitter, Facebook and OpenID (Google, Yahoo!, ...).
Another possibility would be JanRain Engage (formerly RPX) which provides a single point of authentication for all the major authentication providers. There's a 3rd party django app for it, but I can't say anything about its quality.
If you want something simple try this
those are actually auth backends.
In other words, you're still using django.contrib.auth - you're just loading an extension to it.
Auth backends are pretty easy to write, so I would just take a look at the docs and then see if the code looks like something you'd be comfortable working on (for each candidate for a backend).
If you're afraid to change your codebase, you're in trouble.
What are the pros and cons of using open id vs auth? Shoud I do both?
That depends whether you want to support Open ID. As to the reasons behind Open ID, in my view the most compelling one is that it avoids requiring your users to have an account just for your site, with all the hassle that involves (yet another username and password to remember).
If you decide you want to use Open ID, there's not need to choose between that and auth - use django-openid-auth, which adds Open ID support to the auth framework.
Definitely try and avoid using an Open ID implementation that doesn't plug into Django's auth framework - you'll lose a lot of the baked-in goodness of Django (model-level permissions etc).
OpenID and OAuth do different things. OpenID lets users log into your site. OAuth lets people give your site access to their data elsewhere. On the other side of the coin, OAuth gives you a secure way to let users access their data in your service from elsewhere.
If you implement OpenID, don't implement an OpenID producer. Everyone's already got an OpenID, whether they know it or not. Just consume openids from elsewhere. Migrating OpenIDs shouldn't be hard. Just make sure that a user account can connect via multiple OIDs, then they can add new ones as needed, and remove when they're done with them.
Edit: Just saw that you were talking about django auth, not oauth. Oops. The second paragraph still stands.
I need to add few more options for login and therefore need to customize create_login_url with some HTML code.
Is there a way to add on your code in default login screen of Google?
Environment: Python (Google App Engine)
I want to continue having the default Google ext class Users behavior in place.
You can't customize the login page. Allowing you to do so would introduce the possibility of XSS vulnerabilities, as well as making it harder for users to identify a legitimate login page.
If you want to provide for federated login, you may want to simply redirect users to an interstitial page that allows them to pick standard Google login, or one of a number of other services.
Nick Johnson recently released an alpha version of a WSGI middleware that you could use. The API is very similar to the standard Users API in app engine. It is a way to support auth via OpenID (something Alex Martelli suggested in his answer). Therefore you are able to support Google as Identity Provider as well as others. If you only want to support Google accounts for some reason, you could certainly only whitelist them though.
Nick's blog announcement also lists some things to consider (these might be deal-breakers for you):
Users are identified uniquely by their OpenID endpoint.
You can't construct a User object without specifying an OpenID URL.
Nicknames and email addresses are user-supplied, so they're not guaranteed unique or validated.
is_current_user_admin() is not yet implemented.
login: clauses in app.yaml are not affected by AEoid - they still authenticate using the regular Users API.
You might consider OpenID, through any of the various open-source app engine projects for the purpose, such as this one for Django.
You can't use the existing Users module with those (save perhaps with some serious hacking, but I have not attempted such feats and would not necessarily recommend them;-), but the various projects in question tend to offer usable replacements.
Making your own login pages is also not too hard with these approaches, of course, since you start with all the sources to the "OpenID consumer" you choose to use.
I don't know if all the domains you want to support are OpenID providers (though I don't see why any site supporting its own user logins wouldn't also be an OpenID provider -- it's easy and makes it more valuable for users to have logins on that site!-), but I hope this will take you some part of the way towards your goal!