I am trying to implement a way for users to stay logged in my website using the JWT DRF implementation.
From the documentation it's suggested that as soon as a token is expired there is no way to refresh them.
Given that a user might close their browser, my only two options are either having long-lived tokens or storing the username/password in localStorage, and both options seem insecure.
Is there a different way to achieve this? Alternatively is there a way to only have long-lived tokens depending on what a user wants (i.e chooses the remember me option)
Yup, JWTs are intended to authenticate sessions short-term only, even with refresh. If you're designing for the browser, I suggest you use regular old SessionAuthentication to keep users logged in longer-term (e.g. 30 days).
If you want to avoid cookies, you can use a combination of a short-lived and long-lived tokens using, for example, OAuth2 -- check out Django OAuth Toolkit which integrates with DRF. The short-lived token authenticates the session just like a JWT, while the long-lived token (30-60 day lifetime) is used to get a short-lived token from your API and can be stored in localStorage.
I have a python application that needs to give users a JSON web token for authentication. The token is built using the PyJWT library (import jwt).
From what I have been reading it seems like an acceptable practice to give the token to a client after they have provided some credentials, such as logging in.
The client then uses that token in the HTTP request header in the Authorization Bearer field which must happen over TLS to ensure the token is not exposed.
The part I do not understand is what if the client exposes that token accidentally? Won't that enable anybody with that token to impersonate them?
What is the most secure way to hand off the token to a client?
You could encrypt the token before handing it off to the client, either using their own public key, or delivering them the key out of band. That secures the delivery, but still does not cover everything.
In short, there's no easy solution. You can perform due diligence and require use of security features, but once the client has decrypted the token, there is still no way to ensure they won't accidentally or otherwise expose it anyway. Good security requires both participants practice good habits.
The nice thing about tokens is you can just give them a preset lifespan, or easily revoke them and generate new ones if you suspect they have been compromised.
Token will be build based on user provided information and what you back-end decided to be part of the token. For higher security you can just widen your token information to some specific data of the user like current ip address or device mac address, this will give you a more secure way of authentication but will restrict user to every time use the same device, as a matter you can send a confirmation email when a new login happens.
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
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.
I am attempting to utilize Google App Engine as an Authentication Server for a mobile application that runs on android natively. User names and passwords will be stored in GAE and my goal is to be able to both store and verify credentials from the mobile application using GAE. Is this possible? I've looked into OAuth and JSON, but I don't think I have the proper setup for that.
Also, if I'm going about this the wrong way, please point me to the proper path.
If you are interested in having a more API-like implementation in your GAE instance, I would definitely look more into OAuth. But if you are only interested in validating credentials for this one mobile application then you need not go that far.
Fortunately you can call your GAE instance over SSL, that means that you can offload all the business of handshaking and encryption. Then I would simply use either http-basic authentication, or simply send user-id and encrypted password as parameters in the request.
On the iPhone there is a KeyChain for password storing, maybe there is an Android counterpart? Anyway, make sure to store passwords encrypted on the device and in the GAE-datastore. Send the encrypted password when validating credentials. You should never know your user's clear text passwords. That would provide a level of obscurity which I think is enough (definitely so when sent over SSL).
Then you can simply return whether the account credentials are verified or not.
If by "storign credentials" you mean storing username and password, then I imagine you are going about this the wrong way. Whether you are talking about OAuth or OpenID, the idea is that you never see or have access to the password (and perhaps not username either) of the delegated authentication mechanism. Instead you receive an authentication or authorization token to do your work (and in the case of OpeniD, some meta information about the person like first / last name and e-mail address).
By the way, have you considered a 3rd party, such as Janrain?