It seems like the security model fits very small projects, but that it is probably not feasible to write all possible registered users' hashed passwords in security.py. Do you know any examples of scaling up Pyramid's authentication, or are there any benefits to calling through Pyramid's security scheme into my own database of security information?
I dont think the size of the project is related to the security model. Either you want a simple or a complex security model. Both can be applied to projects of any size. One of Pyramid's strong points is its extensibility.
Why would you store hashed passwords in security.py? (cmiiw here, I probably misunderstood) If you read this on someone's code, that's probably just an example. In real apps, you save them in a storage/persistence system of your choice.
Again, I don't understand what you mean by "scaling up authentication". My guess is you want some working examples:
tutorial from the docs
shootout application: small and good example with forms
pyramid auth demo: complex/granular/row-level permission
pyramid apex: 3rd party auth (google, twitter, etc) with velruse, forms etc
pyramid registration: unfinished library; you can steal some ideas from it
No idea what your needs are or what you mean by "scaling up security", but pyramids authentication policy is very flexible. You need to understand though that it doesn't maintain users and passwords it merely provides a mechanism for obtaining a user identifier from the incoming request. For example, the AuthTktAuthenticationPolicy keeps track of the user id by cookie that you set using the remember method.
What meaningful information you derive from that user id is totally up to you and is application specific.
So really the question you may want to ask is can your application "scale up security".
I can't show you code because it's proprietary but I've needed to support openid, http auth and your typical db backed user store on the same application, with the extra added complication that users are stored in different database shards and the shard can't be immediately determined. It takes very little code to support this.
I ended up building something for myself that makes authentication a little easier if you happen to be using MongoDB.
https://github.com/mosesn/mongauth
It isn't built into pyramid, but hooks in easily enough. Everything is pretty transparent.
Related
I need a modern looking forum solution that is self hosted (to go with a django project)
The only reasonable thing I can see using is discourse, but that gives me a problem... How can I take care of auth between the two? It will need to be slightly deeper than just auth because I will need a few User tables in my django site as well.
I have been reading about some SSO options, but I am unclear on how to appraoch the problem down the road. here is the process that I have roughly in my head... Let me know if it sounds coherent...
Use Discourse auth (since it already has social auth and profiles and a lot of user tables.
Make some SSO hook for django so that it will accept the Discourse login
Upon account creation of the Discourse User, I will send (from the discourse instance) an API request that will create a user in my django instance with the proper user tables for my django site.
Does this sound like a good idea?
That sounds plausible. To make sure a user is logged in to both, you may put one of the auths in front of the other. For example, if discourse is in front of Django, you can use something like the builtin RemoteUserMiddleware.
In general, if they are going to be hosted on different domains, take a look at JWT. It has been gainining ground to marry different services and the only thing you need is to be able to decode the JWT token, which a lot of languages have nowadays in the form of libraries.
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 starting web project that should be very flexible and modular and definitely will grow much in the future. As we plan to provide an api to other developers I started thinking that maybe it is a good idea to implement all the methods as api and provide functionality to use them remotely and internally.
For instance, say we want to extract all registered Users. So we design method in api, like get_all_users,which maybe available via REST or internal invocation. The problem is I cannot figure out how to distinguish access from internal usage and remote usage, as I should take into consideration also speed of internal invocation,code reusage and checking of user permissions(secret keys for api access, etc). What are the best practices? How to organize such API?
So to build the API, Tastypie or Piston. These let you write 'resources' (which are basically API versions of the views) - instead of returning httpresponses you just return objects which piston/tastypie convert into json or xml or yaml or whatever your favorite data-language is.
Securing the access: Consider decorating any resources which contain confidential information with the #login_required or #staff_member_required decorator as appropriate.
You might even want to go a step further and write a decorator to check that the staff user is using https (whereas you might allow a normal user to use any connection type).
If you have not considered it yet I recommend to use Tastypie to set up an API with django.
In order to distinguish between your internal and remote usage maybe you can simply design a different URL scheme.
I'm building a webapp and needed to choose between Django and Pyramid. I decided to go with Pyramid.
I understand Pyramid comes with its own authentication/authorization framework which looks nice. But I haven't seen anywhere in Pyramid where users/groups/permissions are defined. In Django these things come for free.
I'm using SQLAlchemy and was wondering if there are similar users/groups/permissions already built that I can import. I'd rather not define these objects/mappings and hash/salting of passwords myself.
Django's definitions of these things are pretty much all I need.
Can anyone point my to something I can use? Or do I need to roll my own?
Pyramid has a much more flexible authentication system. And yes, if you want something simple like Django's user/group/permission concept, then flexible might be scary.
Pyramid does not have a "User" object, as it makes no assumptions about how you store your data or what ORM you use, therefore there isn't something for you like contrib.auth. You will need to hash/salt the passwords yourself using a library such as cryptacular or passlib, both found on PYPI.
As far as wanting user/group/permissions within Pyramid's system, this is achievable pretty simply by defining a RootFactory that has an __acl__ that maps groups to permissions. Permissions are assigned to views, thus are pretty static usually. If you'd like the groups (what Pyramid calls "principals") to be dynamic that is also achievable.
I'd suggest looking at the Pyramid wiki2 tutorial, as well as the shootout demo.
There are also a couple third-party packages for assisting with authorization within Pyramid if you plan to be using SQLAlchemy. apex is a more full stack solution, and ziggurat_foundations is a lower-level layer above SQLAlchemy to help you set up users and groups for your application.
Your question is fairly high level and authorization is a "hard problem", so I'll stop here and avoid regurgitating the tutorials and resources that already exist from the Pyramid tutorials to several third-party examples. If you have any specific questions please feel free to ask those in another question.
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.