Skip to content
This repository was archived by the owner on Sep 14, 2022. It is now read-only.
This repository was archived by the owner on Sep 14, 2022. It is now read-only.

JWT security and scopes - my working solution #481

Open
@ric79

Description

@ric79

Hello,
here there is my solution, hope I can help other developers!

Token

Lets us imagine that the APP will receive in the header a JWT token (TOKENVALUE). The token has been sign with a private key. Payload can be for example:

{ user:
   { system_name: 'SVJWTDEV',
     user_uid: 'root',
     name: 'Supervisor',
     surname: 'Supervisor',
     email: '[email protected]' },
  scopes: [ 'admin' ],
  custom: {},
  exp: 1489696621,
  iat: 1489675021 }

In my case, the scope is just an array of roles

Swagger.yaml

...
securityDefinitions:
  APIKey:
    description: "Accesso tramite JWT"
    type: "apiKey"
    name: "Authorization"
    in: "header"
...
paths:
  /protected_calls:
    get:
      security:
        - APIKey: []
      x-security-scopes: 
      - admin           

I have extended swagger adding x-security-scopes. This is the key point of the solution.

Client authorization

Every calls to server should contains

Authorization: Bearer TOKENVALUE

Middleware

In the swaggerSecurity function it is now easy to verify the token using the public key and check if there is an intersection between scopes from token and x-security-scopes
I'm a newbie to nodejs so just get the idea and not the specific implementation

  app.use(middleware.swaggerSecurity({
    APIKey: function(req, def, JWTAuth, callback) {
      var current_req_scopes = req.swagger.operation["x-security-scopes"]
      if (!!JWTAuth && JWTAuth.indexOf("Bearer ") == 0) {
          var JWTToken = JWTAuth.split("Bearer ")[1]
          jwt.verify(JWTToken, appl_config.jwt.pubKey, function(err, payload) {
               if (err) {
                 var err = new Error('Invalid token');
                 err['statusCode'] = 400;
                 callback(err);  
                 return
               }
               if (_.intersection(payload.scopes, current_req_scopes).length == 0) {
                 console.log("Not Authorized!")
                 var err = new Error('Not Authorized');
                 err['statusCode'] = 401;
                 callback(err);  
                 return
               }
               else {
                   console.log("Authorized!")
                   req.swagger.params.auth_payload = payload;    //example
                   callback()
               }
          });   
      } else {
         var err = new Error('Failed to authenticate using bearer token');
         err['statusCode'] = 403; // custom error code
         callback(err);
      }
    },
  }));

Riccardo

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions