Skip to content

[Question] How to get path parameter during authorization? JWT audience claim in path for multi-tenant app #2923

Open

Description

@robertdodd

In a multi-tenant application, I need the tenant_id from the path to verify the JWT's audience claim. What would the best approach to do this be?

Here's what I do now:

  • Path example: /tenants/{tenant_id}/users
  • api.OauthSecurityAuth decodes the token without verifying the audience claim.
  • In each handler, verify the audience claim

What would the best approach be to apply that at a higher level to all routes?

Activity

  1. robertdodd commented on Apr 10, 2023

    @robertdodd
    Author

    I think I figured it out, using a custom Authorizer. You still need to disable the audience claim check when decoding the JWT, but then the Authorizer will check the principal's tenant ID based on the path. Let me know if anyone has any feedback.

    type TenantAuthorizer struct {
    }
    
    func NewTenantAuthorizer() *TenantAuthorizer {
        return &TenantAuthorizer{}
    }
    
    func (a TenantAuthorizer) Authorize(req *http.Request, p interface{}) error {
        // cast principal to correct type
        var principal *models.Principal
        var ok bool
        if principal, ok = p.(*models.Principal); !ok {
            return errors.New("invalid principal, expected model.Principal type")
        }
    
        // TODO: if principal has SYSTEM/SERVICE scopes then return nil
    
        // use regex to get tenantID from `req.URL.Path`
        // NOTE: all paths must follow the same convention e.g. /tenants/:tenantID
        tenantID := getTenantIDFromRequest(req)
        if principal.TenantID != tenantID {
            return errors.New("not authenticated")
        }
    
        return nil
    }

    And in configuration file:

    api.APIAuthorizer = auth.NewTenantAuthorizer()
    
    api.OauthSecurityAuth = func(token string, scopes []string) (*models.Principal, error) {
        // decode JWT, disable audience claim verification, and return principal
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions