I have a problem with Okta token authentication, I know how to authenticate with drf token and jwt token auth.
In my project, I have to use okta token which is a type of jwt as well, however, this token is generated by front-end and send back to me in the request
so here you can see how I authenticate the okta token with okta_jwt package:
def post(self, request, *args, **kwargs):
access_token = request.META.get('HTTP_AUTHORIZATION')
try:
validate_token(access_token, config.issuer, config.aud, config.client_id)
except Exception as e:
return JsonResponse({"result": e.args[0]}, status=400)
..........
Basically I have to take the token out from the header and check with okta_jwt to see if it's legal
Obviously, I don't think it's a good solution and it's hard to do unit test
Can anyone provide a better solution for this?
Thanks
I found the solution:
I just created the custom authentication inherit from BaseAuthentication. In the Custom authentication, you can do whatever authenticating process you want:
class OktaAuthentication(authentication.BaseAuthentication):
def authenticate(self, request):
access_token = request.META.get('HTTP_AUTHORIZATION')
if not access_token:
return None
payload = validate_token(access_token, config.issuer, config.aud, config.client_id)
try:
user = get_user_model().objects.get(email=payload['sub'])
except User.DoesNotExist:
raise exceptions.AuthenticationFailed('No such user')
return user, None
In the setting.py, making sure you have the custom authentication added as the Default:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'core.authentication.OktaAuthentication',
)}
In the views:
authentication_classes = (OktaAuthentication,)
permission_classes = (IsAuthenticated,)
Related
I am using DRF Social OAuth2 for social authentication, it's giving me the token when I log in, but I want to return the token in response when I register a user with an email and password. How can I do that
We would need to see your endpoint in order to answer the question better. Here is a suggestion if you are using token auth.
from rest_framework.authtoken.models import Token
def get_token_response(user):
token, _ = Token.objects.get_or_create(user=user)
response = {"token": "Token " + str(token)}
return response
And then your endpoint would look something like this (if you are using a viewset):
class UserViewSet(viewsets.ModelViewSet):
def create(self, request, *args, **kwargs):
response = super().create(request, *args, **kwargs)
user = User.objects.get(id=response.data["id"])
return Response(get_token_response(user), status=201)
My point is that you need to get the token from the database and adjust your create user endpoint (aka registration) to return it.
Hope this helps.
I have implemented CRUD with Django Ninja framework, but now I want auth in my app,
I had installed and config Djoser, so now I can generate tokens, but I don't know how to verify in my CRUD's
class AuthBearer(HttpBearer):
def authenticate(self, request, token):
if token == "supersecret":
return token
#api.get("/bearer", auth=AuthBearer())
def bearer(request):
return {"token": request.auth}
I shoud able to check token inside "AuthBearer" function, but I don't know how
my repo (link)
so basically you have to extend Ninja's HttpBearer class and implement authenticate method, which will accept request and token as parameters. This method returns None if the user is not authenticated, and a string which will be populated in request.auth if the user is authenticated. Usually this string will be the username so you can use it in all your endpoints.
Something like this (I am using PyJWT for token decoding):
import jwt
from ninja.security import HttpBearer
class AuthBearer(HttpBearer):
def authenticate(self, request, token):
try:
#JWT secret key is set up in settings.py
JWT_SIGNING_KEY = getattr(settings, "JWT_SIGNING_KEY", None)
payload = jwt.decode(token, JWT_SIGNING_KEY, algorithms=["HS256"])
username: str = payload.get("sub")
if username is None:
return None
except jwt.PyJWTError as e:
return None
return username
I need to sign in a user using firebase from my django app.I have done what I think I needed to do but I seem to be missing something.I am using the pyrebase library.I have created a user on firebase and now I need to sign them in.
I am posting the email and password on Postman and I get the 'idToken' and 'refreshToken', which means the user gets authenticated on firebase.But this only works when I use the drf Token authentication(DEFAULT AUTH CLASSES) and authorization token of a user previously created on django admin. What am I missing so that I can authenticate the user without the drf token authentication?
views.py
config = {
"apiKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
"authDomain": "xxxxx.firebaseapp.com",
"databaseURL": "https://xxxxxxxxx-default-rtdb.firebaseio.com",
"storageBucket": "xxxxxxxxx.appspot.com",
}
firebase = pyrebase.initialize_app(config)
auth = firebase.auth()
class Auth(APIView):
def post(self, request, format=None):
email = "xxxx#gmail.com"
password = "xxxx"
user = auth.sign_in_with_email_and_password(email, password)
return Response(user)
Settings.py
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": (
"rest_framework.authentication.TokenAuthentication",
),
"DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",),
}
Yeah so basically, you don't need any authorization in any of the authentication views. Since you have a global default of IsAuthenticated, you need to overwrite the permission_classes in the View.
class Auth(APIView):
permission_classes = []
def post(self, request, format=None):
...
I have a very interesting issue. We have built couple of apis using django rest framework. These apis are consumed by frontend designed using React. We use SAML withe sessions to manage the authentication process.This SAML authentication is handled by a django middleware.
Now I have a requirement to make some of these apis accessible to a different domain, where their backend would call our apis programmatically. So I need to give auth details to them for them to able to access it.
Since SAML is enabled here, how do I able to set the authentication using JWT and give them the tokens?
The saml middleware code looks like this,
class SamlMiddleware(object):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
if hasattr(request, 'user') and request.user.is_anonymous and 'samlUserdata' in request.session:
data = request.session['samlUserdata']['mail'][0]
if data is not None:
try:
email=data
user = User.objects.get(email=email)
except ObjectDoesNotExist:
user = User.objects.create_user(username=data.split("#")[0],
email=data)
login(request,user)
request.session.set_expiry(settings.SESSION_EXPIRY)
elif not settings.DEBUG and 'samlUserdata' not in request.session \
and not request.get_full_path().startswith('/admin'):
if not request.path == settings.REDIRECT_LOGIN_URL and not request.path == REDIRECT_LOGOUT_URL and \
not request.path == '/saml':
return redirect(settings.REDIRECT_LOGIN_URL)
response = self.get_response(request)
request.session.set_expiry(settings.SESSION_EXPIRY)
if request.user.is_authenticated:
tokens=self.__class__.get_tokens_for_user(self,request,request.user)
request.session.set_expiry(settings.SESSION_EXPIRY)
return response
#staticmethod
def get_tokens_for_user(self,request,user):
refresh = RefreshToken.for_user(user)
return {
'refresh': str(refresh),
'access': str(refresh.access_token),
}
return response
Now for this I am trying to use djangorestframework-simplejwt. But since SAML is used here, I am not sure how do I implement JWT here. Do I have to change something in the above middleware or any other ways?
I am using django Django=2.1.7 and rest framework djangorestframework=3.9.2 This is my url for login
path('rest-auth/', include('rest_auth.urls')),
After authentication I got token but I need user id too. I tried to override the post method of rest_framework.authtoken.views.py file with the following code
def post(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data,
context={'request': request})
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
token, created = Token.objects.get_or_create(user=user)
context = {
'token': token.key,
'user': user.id
}
return Response({'context': context})
Please help me figure out how to get user id with the token. This is my college project.
Note: I find many answers on stack overflow but none is helpful.
Use this Django RestFramework token authentication in order to use authentication. Here you can see how to authenticate, however if you want to use token authentication by default for all views you should add it in settings.py file as :
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
...
'rest_framework.authentication.TokenAuthentication',
...
),
}
or you should add it manually to views which requires token authentication. And in this views you can get authenticated user as request.user or self.request.user.
from rest_framework.authentication import TokenAuthentication
class ViewSetName(ViewSet):
authentication_classes = [TokenAuthentication]