Comments (6)
I think I figured out how to do this; what works and what doesn't work.
I got api1 running using DRF-JWT. api2 now needs to verify authtokens coming from api1. I therefore use asymetric signing, install api1's public key on api2 and can now accept and verify authtokens issues by api1 - as it should be in a proper claims-based architecture. Logically, api2 only defines the decode_handler and ignores the encode_handler and payload_handlers.
What doesn't work is that Django needs a user object in it's internal user table for permissions to work (if I understood correctly). I figured that I would need to change the code so that the DRF-JWT can be run in "federated" mode. In that case, all the attributes of the user are included in the JWT, as is the group (if defined). api2 would then create the user's object on the fly, using the data from the token. If a group is given in the JWT, it must be defined.
That way, authentication and role association is done at the auth server (api1), while detailed authorization is done at each endpoint (api2 in this case) depending on the user's group.
Is this remotely sane? I am not very experienced with Django and auth frameworks, so I would appreciate a cross-check.
from django-rest-framework-jwt.
Hey @arnuschky this is great stuff. We're thinking of doing something like this, so we'll eventually have to take a look at some sane approach. The part that I think we both are a bit confused is what to do on api2 regarding users. I know that with Django you could set another whole DB that is used specifically for User objects, but that would be coupling the two systems. Another approach would be creating the user objects on the fly like you say, or having some kind of webhook system on api1 that notifies all other systems about changes to user, those systems would then create or update user objects on their side.
Let's definitely keep this thread updated with whatever progress we make. It will definitely make an interesting blog post and follow up on JWT and SSO.
from django-rest-framework-jwt.
Yes, it would obviously be preferable not to create anything in the DB, and just create user objects on the fly. Both APIs would still need to share the same model, but that shouldn't be a problem. My concern is mostly: if the user object is complex, I think it's not very sane to send all the user's data in every request. That means, going further than username, id, email and group is already a stretch IMHO. But I see no other way. (If absolutely required, api2 could do a REST GET on the user object if needed... But that seems like a nasty and would still couple the two systems)
I'll have a go at this one of these days.
from django-rest-framework-jwt.
Hi @arnuschky, is it possible to give an example of how you use asymmetric signing and install api1's public key on api2? I am stuck with this issue. API1 authentication works fine. However when accessing api2 with the same token in HTTP Authorization header, it always returns 403 Permission Denied. Don't know how to verify the auth token in api2. Could you please help? Thanks.
from django-rest-framework-jwt.
@lst7788: The example below should work. There are two APIs, api1 allows you to retrieve a JWT token that can be used to authenticate against both APIs. Note: both APIs need to share the same public key and user database.
In api1/settings.py
:
JWT_AUTH = {
'JWT_ENCODE_HANDLER': 'userdb.jwt_settings.jwt_encode_handler',
'JWT_DECODE_HANDLER': 'userdb.jwt_settings.jwt_decode_handler',
'JWT_PAYLOAD_HANDLER': 'userdb.jwt_settings.jwt_payload_handler'
}
In api1/jwt_settins.py
:
import datetime
import jwt
import Crypto.PublicKey.RSA
pubKeyFile = open('path/public_key.pem','r')
pubKey = Crypto.PublicKey.RSA.importKey(pubKeyFile.read())
privKeyFile = open('path/private_key.pem','r')
privKey = Crypto.PublicKey.RSA.importKey(privKeyFile.read())
def jwt_payload_handler(user):
return {
'user_id': user.id,
'email': user.email,
'username': user.get_username(),
# NOTE: for debugging, we made tokes valid for 1 hour
'exp': datetime.datetime.utcnow() + datetime.timedelta(seconds=3600)
}
def jwt_encode_handler(payload):
return jwt.encode(
payload,
privKey,
'RS256'
).decode('utf-8')
def jwt_decode_handler(token):
return jwt.decode(
token,
pubKey,
True,
True,
0
)
In api2/settings.py
:
JWT_AUTH = {
'JWT_DECODE_HANDLER': 'userdb.jwt_settings.jwt_decode_handler'
}
In api2/jwt_settins.py
:
import datetime
import jwt
import Crypto.PublicKey.RSA
pubKeyFile = open('path/public_key.pem','r')
pubKey = Crypto.PublicKey.RSA.importKey(pubKeyFile.read())
def jwt_decode_handler(token):
return jwt.decode(
token,
pubKey,
True,
True,
0
)
Let me know if this works. I had to scrap that project shortly after I figured out this part, so it never went into production. :|
from django-rest-framework-jwt.
@arnuschky , my issue is different and much simpler. I didn't do the Authorization right with the token retrieved. It is ok now, but thanks for your reply and your example. I believe it will help me when I come to that situation. :)
from django-rest-framework-jwt.
Related Issues (20)
- Is there a way that we can avoid multiple token generations for a single user if he/she try to login on different browsers? HOT 2
- JSONWebTokenAuthentication object has no attribute 'media_type'
- external server
- Call an endpoint without Authorization header HOT 1
- Add support for ES256 signing algorithm
- [feature] permit to use custom header instead of `Authorization`
- registration
- how to refresh existing tokens??? HOT 6
- redis cache HOT 1
- WinError 123 after tutorial HOT 1
- How to use this library by only using Http Only Cookie? HOT 1
- Curious Whether JWT Still Works Given Libraries Requirements Mismatch? HOT 3
- Status HOT 12
- Documentation not found HOT 2
- Dead Link in readme.md HOT 1
- DeprecationWarning: The following fields will be removed in the future: `email` and `user_id`. HOT 1
- Hope to support the response format of custom authentication failure HOT 1
- Unreachable code when user is_active is False in. HOT 1
- Can we use allauth only for the things, where we can get involved with email verification, and jwt for others purposes like login/get api request/ post api requests....????
- Cookie not removed in request when response is 401
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from django-rest-framework-jwt.