OpenMetadata
OpenMetadata copied to clipboard
JTW Token Generation not working when using jwtPrincipalClaimsMapping for OIDC auth
Affected module OIDC Authentication Provider
Describe the bug When using OIDC Auth (Custom) and configuring a jwtPrincipalClaimsMapping like:
jwtPrincipalClaimsMapping:
- email:email
- username:unique_name
The authentication for Personal Access Tokens or Bots won't work anymore. The issue is that the JWTTokenGenerator doesn't add the JWT Claims for the jwtPrincipalClaimsMapping as configured and the Authentication Controller checks for them.
E.g. when starting an ingestion over the UI following error happens:
9809ac99-6c0b-4aa3-b38e-b5153cd4b822 Failed to deploy Ingestion Pipeline due to airflow API returned Internal Server Error and response {"error": "Internal error while deploying due to [Failed to generate workflow [9809ac99-6c0b-4aa3-b38e-b5153cd4b822] verify config is correct: Invalid JWT token, 'username' claim is not present] "}
To Reproduce
Configure a Custom OIDC authentication with a jwtPrincipalClaimsMapping with different claimts than 'sub' and 'email'. Then try to start a ingestion over UI, or user an PAT or configure an external ingestion.
Expected behavior Authentication for Ingestin Bots, or Bots in general and PAT is still working when using OIDC authentication with custom jwtPrincipalClaimsMapping configuration.
Version:
- OS: Linux / Docker Container / Kubernetes / Helm
- Python version:
- OpenMetadata version: 1.5.6
- OpenMetadata Ingestion package version:
Additional context Suggested solution:
Add to the JWTTokenGenerator at getJwtAuthMechanism()
JWT.create()
.withIssuer(issuer)
.withKeyId(kid)
.withClaim(SUBJECT_CLAIM, userName)
.withClaim(ROLES_CLAIM, roles.stream().toList())
.withClaim(EMAIL_CLAIM, email)
.withClaim(IS_BOT_CLAIM, isBot)
.withClaim(TOKEN_TYPE, tokenType.value())
.withIssuedAt(new Date(System.currentTimeMillis()))
.withExpiresAt(expires)
.sign(algorithm);
the JWT claims configured in jwtPrincipalClaimsMapping like:
JWT.create()
.withIssuer(issuer)
.withKeyId(kid)
.withClaim(SUBJECT_CLAIM, userName)
.withClaim(jwtPrincipalClaimsMapping.get(USERNAME_CLAIM_KEY), userName)
.withClaim(ROLES_CLAIM, roles.stream().toList())
.withClaim(EMAIL_CLAIM, email)
.withClaim(jwtPrincipalClaimsMapping.get(EMAIL_CLAIM_KEY), email)
.withClaim(IS_BOT_CLAIM, isBot)
.withClaim(TOKEN_TYPE, tokenType.value())
.withIssuedAt(new Date(System.currentTimeMillis()))
.withExpiresAt(expires)
.sign(algorithm);
but only add the claims if they don't exist already.