10

I'm using Django Oauth Library.

I want to have different Auth and Resource Server.

On Auth Server, following is my setting.

INSTALLED_APPS = [
    ...


    'oauth2_provider',
    'rest_framework',
]


REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
}

# ############## OAUTH SETTINGS ###################

OAUTH2_PROVIDER = {
    'SCOPES': {'users': 'user details', 'read': 'Read scope', 'write': 'Write scope', 'groups': 'Access to your groups', 'introspection': 'introspection'},
    'ACCESS_TOKEN_EXPIRE_SECONDS': 86400,  # 1 Day.
}

On my Resource Server

INSTALLED_APPS = [
    ...


    'oauth2_provider',
    'rest_framework',
]


REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
}

# ############## OAUTH SETTINGS ###################

OAUTH2_PROVIDER = {
'RESOURCE_SERVER_INTROSPECTION_URL': 'http://localhost:8000/o/introspect/',
'RESOURCE_SERVER_AUTH_TOKEN': '3yUqsWtwKYKHnfivFcJu',

}

Question 1)

How do I obtain RESOURCE_SERVER_AUTH_TOKEN?

Question 2)

Upon introspecting the token, Auth Server returns 403 Forbidden Error in the console logs.

Following is the flow to obtain the access token.

I get the client_id, client_secret, grant_type and scopes from the client POST request onto the Resource Server. I call the AuthServer from the Resource Server and return the response back to the client.

What exactly am I missing over here?

Praful Bagai
  • 16,684
  • 50
  • 136
  • 267
  • Currently, I'm developing locally, ie on my machine. – Praful Bagai Dec 05 '17 at 05:39
  • What's the `RESOURCE_SERVER_AUTH_TOKEN`? – Praful Bagai Dec 05 '17 at 05:40
  • RESOURCE SERVER AUTH TOKEN is the token used by introspection endpoint to authenticate resource server. But are you getting error at introspection or at Intial client Authorization grant ?? looks like you are hitting the error at AUTH server, not at Introspection. – Saji Xavier Dec 05 '17 at 06:02
  • Well, whenever I try to authorize myself, my Resource server fires a query locally `access_token = AccessToken.objects.select_related("application", "user").get(token=token)`. Since `resource_server` does not have any tokens saved (all the tokens are saved in Auth server), it returns an error `AccessToken matching query does not exist.`. And while handling the above exception, another exception was thrown which is 403 error returned by the Auth Server. – Praful Bagai Dec 05 '17 at 06:08
  • According django-oauth-toolkit implementation, it first tries to check whether access token is present in its db, so 'AccessToken matching query does not exist' is not issue .. if access token is not present, it wll try to validate the token with introspection endpoint based on the URL & access token provided in the settings .. so the issue is at the introspection endpoint. how you create the RES SERVER AUTH TOKEN ? can you put the urlconf of AUTH SERVER – Saji Xavier Dec 05 '17 at 07:04
  • That's what I want to know. How do I create `RESOURCE_SERVER_AUTH_TOKEN` ? – Praful Bagai Dec 05 '17 at 07:07
  • urlconf of AuthServer is `url(r'^o/', include('oauth2_provider.urls', namespace='oauth2_provider')),` – Praful Bagai Dec 05 '17 at 07:11
  • you can create AUTH TOKEN using the admin login. – Saji Xavier Dec 05 '17 at 07:13
  • Should that Auth Token be associated with a particular application? Which means shall I create a new application for my resource server and then create a new auth_token associated with the newly created application? – Praful Bagai Dec 05 '17 at 07:18
  • First create a resource_server_user, then create an 'application' for that user with client_type=Application.CLIENT_CONFIDENTIAL, authorization_grant_type=Application.GRANT_AUTHORIZATION_CODE .. Then create a AUTH token for that user application with scope as scope="read write introspection" and a random token string. – Saji Xavier Dec 05 '17 at 07:26
  • @SajiXavier - It worked as expected. Finally the token can be introspect. Thanks a lot. – Praful Bagai Dec 05 '17 at 09:03
  • One quick question, how do I not create Oauth DB tables in Resource Server? Is there a `managed=False` setting in OAuth.? – Praful Bagai Dec 05 '17 at 09:05
  • You could post it as an answer, and I'll be glad to accept it. :) – Praful Bagai Dec 05 '17 at 09:21
  • Oauth DB tables should be present in your resource server, only the records are created in AUTH server .. because you have INTROSPECTION details in settings – Saji Xavier Dec 05 '17 at 09:42
  • I have updated the answer with all the details. – Saji Xavier Dec 05 '17 at 09:51
  • Could you help me with my question: https://stackoverflow.com/q/65898992/9682023 – Usoof Jan 26 '21 at 12:56

1 Answers1

12

According django-oauth-toolkit implementation, Resource server first tries to check whether access token is available in its db or not.

If access token is not present, it will check introspection URL and introspection token are available in settings. If introspection settings is available then resource server tries to validate the user token with an introspection endpoint.

So the issue seems to be that AUTH SERVER and DRF might be returing 403 Forbidden since the permission is set as IsAuthenticated. This could be either due to invalid token or invalid user.

So create a user for the resource server and then create an application for the resource server user.

creating the application,

client_type=Application.CLIENT_CONFIDENTIAL
authorization_grant_type=Application.GRANT_AUTHORIZATION_COD‌​E

And generate a token through the admin site and update the resource server INTROSPECTION setting with the newly created token. Make sure you put the appropriate scopes while creating the token.

Saji Xavier
  • 2,132
  • 16
  • 21
  • One last question (:P), how do I configure scopes without updating the AUTH_SERVER settings `OAUTH2_PROVIDER['SCOPES']`. I mean everytime I need to add a new scope to the auth_server, I need to reload the application!!! – Praful Bagai Dec 05 '17 at 10:12
  • Any thoughts on this @Saji? – Praful Bagai Dec 05 '17 at 16:52
  • can you give me a use case for the same ? the scopes defined in the setting are for a special scenario - If the client omits the scope parameter when requesting authorization, the authorization server MUST either process the request using a pre-defined default value. This is standard mandated . How frequently you change default values ? . – Saji Xavier Dec 05 '17 at 17:32
  • @PythonEnthusiast I am also doing something similar. I have an Auth server and a separate resource server. Say a client is going to access my resource server. How do I create a token for the client ? What I am doing is creating a user and application for that user at the Auth server , so I get a client id and client secret from the Auth server. Now I call the http://localhost:8001/o/token/ url of the auth server which gives me an access token. Now I give the client the access token . So how can my resource server verify that the client is having the right token ? Please help me understand this – Syed Ammar Mustafa Mar 26 '19 at 17:23
  • When you've different resource and auth server, the auth token is cached by the resource server within its DB (after first introspection). So, when a request is made to the resource server, checking the validity of auth token, it is checked by the resource server itself. – Praful Bagai Mar 29 '19 at 12:12
  • @PythonEnthusiast So here is the problem , I have multiple resource servers say r1 and r2. A single separate auth server. I registered r1 and r2 as clients in auth server using resource owner password credentials , i generated access token for r1 and r2 and added it to retrospect_auth_token for introspect. Say post man is a client who wants to access r1 . I want post man to able to generate access token for r1 without using a user name and password but just using client id and client secret? do I have register post man as a client in auth server and use that client id and client secret ? – Syed Ammar Mustafa Mar 31 '19 at 12:30
  • @PythonEnthusiast I created a new question , if you could help it would be great : https://stackoverflow.com/questions/55351275/django-oauth-toolkit-generating-access-tokens-for-multiple-resources-services – Syed Ammar Mustafa Mar 31 '19 at 18:30