Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
robertdodd opened this issue Apr 9, 2023 · 1 comment
Labels
auth API authentication question

Comments

@robertdodd
Copy link

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?

@robertdodd
Copy link
Author

robertdodd commented Apr 10, 2023

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
}

@fredbi fredbi added question auth API authentication labels Dec 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auth API authentication question
Projects
None yet
Development

No branches or pull requests

2 participants