I am writing a small webapp using the pyramid framework. For authentication I use a service of the cloud infrastructure that supplies me with a javascript web token, which I can use to validate the identity of the user.
I am a bit unsure on how to incorporate this with pyramid, especially since most examples I found are either username-password based authentication frameworks, or they generate JWT tokens themselves (I just consume those by the identity provider).
Anyway, in the login view, I have currently a logic like this:
.....
user = validate_jwt_token_and_return_user(id_token, ** config)
if user:
headers = remember(self.request, user.id)
raise HTTPFound(location=next_url, headers=headers)
Now it seems that by this I store the user-ID as a session cookie (?) and the user visits the next view, the user id is taken from the cookie?
Wouldn't it be better to store the jwt_token in the cookie and use this upon the next request to check whether the user's login attempt is valid?
Sure, you can store the JWT token in a cookie. You choose the authentication policy - just write one that does that instead of using one that stores it in the session.
Related
I have setup a simple REST API server (using Django REST framework) that responds to POST requests by doing some processing on an image uploaded to the server in the request. Previously I used it to power my own frontend (http://lips.kyleingraham.com) as a demonstration but I would now like to open the API to other users.
I would like for an end-user to be able to sign up and, from a dashboard, generate a token based on their credentials that could then be hard-coded into their web app. The sign-up part I believe I can handle but I am unclear on how to restrict a generated token to a user's web app domain. I know that the code for a web app is easily inspected so any API token I provide would need to be policed on my backend.
How can I restrict an authorization token to a users' web app domain so that even if the token was leaked, another user would not be able to utilize it?
If you want to hard-code url into user web app, in that way you can't guarantee that if someone get the token, he won't be able to use it.
The only idea is to set some time limit for each token
I have a website with frontend in AngularJS and backend in Python.
Currently we are presenting the user with a simple webform to fetch credentials.
The credentials from the form are sent to the Python backend(flask webservice)(this is a basic auth mechanism).
Now we would like to enable Single Sign on (SSO) on the website.Our identity provider is Pingone or Ping Federate.
I am starting from scratch here..with no prior knowledge of SAML or SSO.
I would like to know which path to take?
Which libraries to use and more importantly,how to use them?
At this point in time I am not sure how exactly SAML identifies a user and then authenticates him/her.
The basic exchange of SAML starts with a user asking for a resources (page, SPA app) on your Python server. The server determines if the user is already authenticated (has a session, JWT token, etc), and if not, creates a SAML request token to be sent via a redirect to the Identity Provider (use a library for this).
The identity provider verifies the SAML request token via digital signature. Once the token is verified, the user is asked to log in (if they are not already authenticated there). Once the user is authenticated, the identity provider creates a SAML request token which is presented back at your server via a redirect.
Upon receipt of the SAML request token, your server validates the token via digital signature, and you treat the user as logged in (again, use a library for this part). The token will minimally identify the user, but can contain authorizations and additional info. At this point your user is authenticated and you would create a session on your server or you create a JWT token to identify your user from within your angular app to the Python backend.
Creating the SAML request token and processing in the resultant SAML response token is not trivial. As suggested above, use a library, preferably one that has been through the the test of time. I'm not a Python dev, but I found this with some googling: onelogin/python-saml.
Wikipedia has a nice sequence diagram to demonstrate this and of course you can peruse the many docs on the Oasis SAML docs website.
Good luck with the implementation. I've done it a couple times in Java.
I'm designing a web application and now I'm working on the authentication function. I read that there are two approaches: cookies and tokens. I do not really understanding how these two work.
I'm planing to use django-rest-framework-jwt if I chose tokens. Here's where I am at :
Tokens
The user sends his data (login and password). The application verifies that the data are correct and calculates a token and then send it back to the user. When the user make a request he includes the token in the request. The application decodes the request and we get the information about the user.
My question :
- How do we get the token? Is it like calculating a hash code?
- How do we get the user information after we decode the token?
- How is it determined that the token is dead?
- Can a web application that uses tokens be used through a browser
Cookies
Same as tokens but cookie are sent using the HTTP header not in request body. Cookies must stored in the server side.
My question :
- In articles I read they say that tokens have the advantage that they have life time. But cookies have that too. So what's the difference between the life time of a cookie and a token?
- How we identify the user who made the request? Do we store a dictionary (cookie, user id)?
I believe "Tokens" as you call it are identical to "Sessions" as on https://docs.djangoproject.com/en/dev/topics/http/sessions/.
Similar to what you stated, Sessions calculate a hash code/id to be sent back to the user to be identified as an authenticated user etc.
To answer your questions directly:
Sessions and Cookies work together. Once Django generates a SessionId it is stored on user's computer through the use of a cookie while it is also recorded in django backend. Therefore, I am not sure if your question is valid. Try reading up at http://www.tangowithdjango.com/book/chapters/cookie.html.
The link above also answers this questions for you. To summarize, the SessionId sent back to the user includes an ID to identify that user as authenticated or any other property etc.
Basically the difference between Cookie-based authentication (by storing sessionIds in cookies on the client) and token authentication is that an authentication token is sent in the http-header 'authentication' field. This is more flexible, since there are REST clients (native clients on phones etc.) that don't support the concept of a cookie at all.
Session Authentication is built-in in Django, session authentication is provided by Django-rest-framework.
Django-rest-framework has a built-in method of passing the token to the client, but you're welcome to implement your own devices.
Tokens are valid until they are deleted from the database. Again, you can roll your own auto-invalidation solution here.
The django-rest-framework documentation is pretty detailed about the different authentication mechanisms it supports. See http://www.django-rest-framework.org/api-guide/authentication
I'm trying to implement single sign-on using only django auth.
Let's assume two django projects, on different sub-domains: site.com(auth) and app1.site.com(app1)
The auth table in site.com is master. site.com handles: login, logout, account registration, etc.
site.com sets SESSION_COOKIE_DOMAIN to .site.com to allow it to be read by subdomains
app1 will have login_url set to a view in the app1 project, which does the following:
retrieves site.com's session_id value(from cookie)
validates session_id by making a request to: site.com/validate/[session_id]/
If False, redirects to site.com/login?next=[...]
If True, request user data to: site.com/attributes/[session_id]/
site.com/attributes/ delivers a dictionary with all the User values, encrypted using a shared SSO_KEY(encryption done the same way django encodes and decodes session_id)
Now, app1 has a model SSO_User which has two fields, a foreign key to User model and an integer field. The SSO_User models links local auth User to the id of master auth table.
Using the id retrieved from site.com, we check SSO_User for existing local user, if true we simply update the values and login; if non existing, we create the user and SSO_User and login.
app1(or any other sub-domain) can keep their own profile information, without interfering with anything.
It seems simple to implement and safe, but before implementing I wanted some opinions. What do you think?
I don't profess to be a web security expert, but I've done something similar in the past. As long as you properly set the cookie domain (which you claim to be doing) I don't really see any security issues, especially since both sites are on the same domain.
If you really want to be safe I suppose you could set up your own OAuth portal or something, but quite frankly that seems to be overkill.
I'm building a site on Google App Engine, running python and Django non-rel. Everything is working great for HTML and posting/reading data. But as I'm moving forward I'd like to do many of the updates with AJAX, and eventually also over mobile devices like Android and iPhone.
My pages use django non-rel and my login/logout authentication works great for the HTML. But update information sent over JSON would have to be authenticated that the user can make the changes. I see how doing authentication for just AJAX calls wouldn't be too difficult since your still hitting the website, but what about when throwing in mobile phone authentication?
So I'm new to this, where do I start?
How can I set up services on gae so I can do authenticated CRUD operations? Ideally I'd like to use the exact same REST services for ajax, android, etc.
Python makes this pretty easy, you can just create a decorator method of checking the auth and add the decorator to any method requiring auth credentials.
def admin(handler_method):
"""
This decorator requires admin, 403 if not.
"""
def auth_required(self, *args, **kwargs):
if users.is_current_user_admin():
handler_method(self, *args, **kwargs)
else:
self.error(403)
return auth_required
...
#admin
def crudmethod_update(self, *args, **kwargs):
...
Mind you, this assumes a few things about how you are grabbing user data and such but the principal is the same with any setup. The notion you may be laboring under is that ajax calls are handled somehow differently on the server, but just like any restful method you are really getting the same headers. If you can check the authentication on the standard html request you can quite literally hijack the form submission with an ajax request and get the same result back. You may want to get JSON back instead or a smaller piece of HTML and for that you want to either:
Add something you can check in the request to know that it is an ajax request and adjust accordingly.
Implement an RPC Model for handling ajax requests specifically.
For actually handling authentication you can use the google.appengine.ext users library and ride on the google accounts auth or you can write your own. Writing your own of course means implementing a session mechanism (for retaining state across the user session) and storing the passwords in a hashed and salted state for verification.