Search code examples
djangosecurityoauth-2.0django-rest-frameworkdjango-oauth

Django-OAuth-ToolKit : Generating access token's for multiple resources/services using client credentials grant type of OAuth2.0


I have a couple of backend API's which are Django projects. They have a UI ( single page app) to it and a user name password based login.

My clients are usually developers and they don't want the UI , all they want is the access to the backend API's and they can build their own dashboards etc. They would want to integrate the API's with their backend system's.

Questions

question 1. I am planning to use django-oauth-tool kit , it seems to me that the client credentials grant type would be suitable for this use case . Am I right ?

To experiment , I started a seperate oauth server locally running on port 8000, I started the resource server ( r1 ) on 8001 and resource server ( r2 ) on 8002.

step1 :

I went to the admin panel of oauth server created a user u1 for resource r1 and user u2 for resource r2. I went to the applications module in admin panel registered r1 and r2 in the applications with grant type resource owner password . To generate the access token I called the token end point

POST -d "grant_type=password&username=u1&password=u1password" -u "clientid of R1:clientsecre of fR1" http://localhost:8000/o/token/

I got the access token

{
   "access_token":"KdAOMZBiMomVxpvjAWErwVGog6NRRH",
   "expires_in":86400,
   "token_type":"Bearer",
   "scope":"read write introspection",
   "refresh_token":"ffgkZZ5NtVFh4REs0TbFAALNkJqXVQ"
}

step 2:

Say the above access token I generated for Resource server R1 so I went to the settings file of R1 and added this token for introspection

OAUTH2_PROVIDER = {
    'RESOURCE_SERVER_INTROSPECTION_URL': 'http://localhost:8000/o/introspect/',
    'RESOURCE_SERVER_AUTH_TOKEN': '9b2uVud7WXHEdyolznvvkM3KwWfkVe',  # OR this but not both:
    #'RESOURCE_SERVER_INTROSPECTION_CREDENTIALS': ('5sRVXLoTQj9vlkLWaziIMZrgra1keupWIQ2On2hX','5jwMxls1JiAiQiNVnRTtbjmzgRO20FEHD0BBdiSAwvSL1XswZKqglDRke2L8Ig77ol7OE3ZdsA9SE7sry0u3BXwd1OvfFfhDVJFSLWlPG6g1vB3w4ZFc1g8ZwgzXJooc'),
}

step 3: I did the same process for the resource server R2 as well.

Question 2 : Is this process of registering multiple resource server's correct ? Have I set up the introspection correctly ?

Question 3 : How would I register different micro services running on the same resource server ?

step 4: Assuming that now I have a auth server ready to generate token for both r1 and r2 resources.

Now to simulate a scenario where a developer who wants to integrate my API with his app wants to generate a access token would have to first register his app with the auth server , I registered an App ( developer's app) on auth server with Grant type client credentials.

This how my admin panel looks now with R1 with user U1 and R2 with U2 registered as resource server's and developer app not associated with any user being the client who wants to access any of these resources.

enter image description here

step 5 : Simulating how a developer would have generated the access token , I generated the access token like this enter image description here

Note : I used the client Id and client secret of Resource R1 and generated the access token , but I am able to successfully use the same access token even for Resource R2 and its working.

Question 3 : Why is the access token I generated using R1's client id and client secret working even for R2. Am I doing something wrong here ? Basically , I want to be able to produce access tokens for developer's specifically for a resource. I know there are scope and permissions but can I generate access token for a specific resource only ? what do I need to do to achieve this , do I need extend or add some logic ?

Question 4 : Is my thought on using client credentials grant type correct and are the steps that I have done to register resources server's and the client app's which are going to use resource server's correct ?

Thanks for any help


Solution

  • question 1. I am planning to use django-oauth-tool kit , it seems to me that the client credentials grant type would be suitable for this use case . Am I right ?

    Yes, You're right.

    Question 2 : Is this process of registering multiple resource server's correct ? Have I set up the introspection correctly ?

    Yes, you're doing it the right way.

    Question 3 : How would I register different micro services running on the same resource server ?

    Do you mean running different micro-services ON DIFFERENT PORTS on the same resource server? If yes, then you have to configure your resource server in the same way as you did for your R1 and R2.

    Question 3 : Why is the access token I generated using R1's client id and client secret working even for R2. Am I doing something wrong here ? Basically , I want to be able to produce access tokens for developer's specifically for a resource. I know there are scope and permissions but can I generate access token for a specific resource only ? what do I need to do to achieve this , do I need extend or add some logic ?

    Access tokens are confidential. If shared with anyone, either of resources will be able to access it. For eg:- If I've your FB auth token, you and I can do the same thing with it, irrespective to whom does this token belong.

    Question 4 : Is my thought on using client credentials grant type correct and are the steps that I have done to register resources server's and the client app's which are going to use resource server's correct ?

    1. Yes, using client_credentials is the right way to approach your problem statement.
    2. Yes, you're setting it up the right way. However, do look into JWT for an alternative and advanced approach. Using JWT avoids the introspection call made to OAuth Server, thereby saving a network call.