Closed singhharpreet658 closed 3 years ago
+1 It would be useful to know how to associate client credentials grants with a User especially for DRF. I assumed that setting the user on the Application instance would associate tokens generated for that application with its user. However the tokens do not seem to have a user. Django 1.10.6 and python 3.6
other oauth2 implementations seem to do the same https://github.com/laravel/passport/issues/143
Is there any workaround on this issue, I've been facing the same in Django 2
Check oauth2 specifications, the current implementation is what is expected.
Multiple issues are in the OP's initial question: 1) client_type: public + grant: client_credentials is a non-sense and must not be allowed. Bug in the DOT code ? 2) most of the time, the client_credentials generates tokens associated to a "client" (i.e. application) and not an user. However, ideally, binding a client to an user should be possible but might be a separated feature for DOT. 3) access token does not seems to allow accessing the resource, but it is not related to anything of the above ? also, the title of the issue "client_creds not working" seems to broad and does not reflect its content.
Thoughts?
Multiple issues are in the OP's initial question:
- client_type: public + grant: client_credentials is a non-sense and must not be allowed. Bug in the DOT code ?
- most of the time, the client_credentials generates tokens associated to a "client" (i.e. application) and not an user. However, ideally, binding a client to an user should be possible but might be a separated feature for DOT.
- access token does not seems to allow accessing the resource, but it is not related to anything of the above ? also, the title of the issue "client_creds not working" seems to broad and does not reflect its content.
Thoughts?
I have the same problem, but mine has some differences. I'm using django 2 and the "client type" of the application I set up is "Confidential". But still the same problem! I don't know if it's my settings or it's a bug or anything else! So for more information, I have these in the settings:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
}
OAUTH2_PROVIDER = {
'SCOPES': {'read': 'Read scope', 'write': 'Write scope',
'groups': 'Access to your groups'}
}
Please help.
@hrahmadi71, sorry but I still don't understand what is the "same problem". Do you have at least an error, stack trace, or anything which could help to understand the issue ?
@JonathanHuot , by the same problem I mean when I try to use a token generated by client_id and client_secret of an application with "client credential grant", I get the 403 error with this payload:
{
"detail": "You do not have permission to perform this action."
}
for example I have this view:
class LanguageDetect(generics.CreateAPIView):
permission_classes = [permissions.IsAuthenticated]
...
and when I try to call this API by:
curl -X POST "http://127.0.0.1:8000/api/v1/language_detect/" -H "accept: application/json" -H "authorization: Bearer [access_token]" -H "Content-Type: application/json" -d "{ \"input_text\": \"string\"}"
Depend on grant type of the application I get [access_token] from, it defers! When the [access_token] I'm using, belongs to an application with 'password' grant, it works fine. But when it belongs to an application with 'client credentials' grant, I get the error just showed. Thank you in advance, and sorry if I can't explain my problem clearly.
Thanks @hrahmadi71, that's much clearer !
I think the permissions.IsAuthenticated
require for an user to be logged-in and not an application (client).
However, I am not familiar enough with the Django framework to help.
@JonathanHuot Thank you for your help. As you mentioned the problem was the permission I've been using, so I solved it by implementing a custom permission for client credential
grant as I explained here.
And here's the DRF guide to implement a custom permission which I've used.
I hope it would be helpful.
I think it might be better to override the OAuth2Authentication class and pull out the application user instead of setting request.user
in has_permission
. Something more like...
from oauth2_provider.contrib.rest_framework import OAuth2Authentication
from oauth2_provider.models import Application
from oauth2_provider.oauth2_backends import get_oauthlib_core
class OAuth2ClientCredentialAuthentication(OAuth2Authentication):
def authenticate(self, request):
authentication = super().authenticate(request)
if authentication is not None and not self.is_client_credential_request(authentication):
return authentication
if self.is_client_credential_request(authentication):
access_token = authentication[1]
user = access_token.application.user
return user, access_token
return None
def is_client_credential_request(self, authentication):
access_token = authentication[1]
return access_token.application.authorization_grant_type == Application.GRANT_CLIENT_CREDENTIALS
I faced with the same problem (getting HTTP 403 Forbidden
response when using a client_credential granted access_token to call my APIs). So I used an authenticator like what suggested by @kdazzle. I think it would be a good feature to be added to the repository. especially for those who want to authenticate a server-to-server request. @jonatascastro12, do you agree? are you currently working on this?
Hey @mahyard! You probably wanted to mention another "Jonatas". 😉
my bad... excuse me @jonatascastro12 @JonathanHuot could you check my comment above, please?
@kdazzle This solution works for me, thanks!
Is the user for the application for a Client Credential type, just the user who is logged in when the application (client) is created?
with some modification @kdazzle 's answer worked perfectly.
Hi Team,
I've installed Django 1.11 and django-oauth-toolkit 0.12 with python 3.5 We've setup one Application with "client type: public" and "grant type: client_credentials".
We have generated a token with o/token, grant type client_credentials but the generated token is not associated with any user.
When we use this token for further API requests then it returns the error "You do not have permission to perform this action." although the scope of token is "Read Write".
Please suggest.
Thanks Harpreet