8000 OIDC with Azure | akhq doesn't map roles coming from azure ad to groups | no debug logs · Issue #2137 · tchiotludo/akhq · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

OIDC with Azure | akhq doesn't map roles coming from azure ad to groups | no debug logs #2137

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

Open
youcefguichi opened this issue Mar 27, 2025 · 4 comments
Labels
wait for reply Need more information from reporter

Comments

@youcefguichi
Copy link
youcefguichi commented Mar 27, 2025

We are a bit on pressure to deliver this and i would really appreciate some help.

When mapping individual users all is good. However when using the groups as in the commented sections the mapping doesn't really work and i kept being redirected to the login page. What makes it harder to debug is that there is no logging i tried to set the level to debug but it still only showing warn and info, so i'm not sure which part is causing the problem and how to debug it.

      oidc:
        enabled: true
        providers:
          azure:
            label: "Click here to Login with Azure"
            username-field: email
            groups-field: roles
            users:
            - username: test@test.so
              groups:
                - admin
            # default-group: topic-admin
            # groups:
            #   - name: reader
            #     groups:
            #       - admin
@github-project-automation github-project-automation bot moved this to Backlog in Backlog Mar 27, 2025
@youcefguichi youcefguichi changed the title OIDC with Azure | akhq doesn't map roles coming from azure ad to groups | no logging OIDC with Azure | akhq doesn't map roles coming from azure ad to groups | no debug logs Mar 27, 2025
@youcefguichi youcefguichi marked this as a duplicate of #2128 Mar 27, 2025
@AlexisSouquiere
Copy link
Collaborator

Do you have a sample of the claim provided by Azure ?
The only reason that it works for user mapping and not for group mapping should be the groups-fields that is not referencing the right field from the claim

@AlexisSouquiere AlexisSouquiere added the wait for reply Need more information from reporter label Mar 27, 2025
@youcefguichi
Copy link
Author
youcefguichi commented Mar 27, 2025

hey @AlexisSouquiere , Thanks a bunch for getting back to me, i try to give a detailed explanation. Long story short: based on my mimictions it looks like the first senario doesn't include any roles/groups in the claim, but the second scenario does include roles/claims

Senario 1 (akhq undestand this flow, but no roles/groups included in the claim)

When i mimic the config below, which leads to construct the following url, the grenerated jwt token doesn't include roles or groups, it only include email with other info, i attached the genrated jwt sample below.

Example auth url

https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize?client_id=<client_id>&response_type=code&redirect_uri=http://localhost:9091/oauth/callback/azure&scope=openid profile email

example config

oauth2:
    enabled: true
    debug: true
    clients:
        azure:
        client-id: "<client-id>"
        client-secret: "<client_secret>"
        scopes:
            - openid
            - email
            - profile
        openid:
            issuer: "https://login.microsoftonline.com/<tenant-id>/v2.0"

generated jwt structure from the config

{
    "typ": "JWT",
    "nonce": "<nonce>",
    "alg": "RS256",
    "x5t": "<x5t>",
    "kid": "<kid>"
}.{
    "aud": "<audience>",
    "iss": "https://sts.windows.net/<tenant-id>/",
    "iat": <issued-at>,
    "nbf": <not-before>,
    "exp": <expiration>,
    "acct": <account>,
    "acr": "<acr>",
    "acrs": [
        "<acr-values>"
    ],
    "aio": "<aio>",
    "altsecid": "<altsecid>",
    "amr": [
        "<authentication-methods>"
    ],
    "app_displayname": "<app-display-name>",
    "appid": "<app-id>",
    "appidacr": "<app-id-acr>",
    "email": "<email>",
    "idp": "https://sts.windows.net/<idp-tenant-id>/",
    "idtyp": "<id-type>",
    "ipaddr": "<ip-address>",
    "name": "<name>",
    "oid": "<object-id>",
    "platf": "<platform>",
    "puid": "<puid>",
    "rh": "<rh>",
    "scp": "<scopes>",
    "sid": "<session-id>",
    "sub": "<subject>",
    "tenant_region_scope": "<tenant-region-scope>",
    "tid": "<tenant-id>",
    "unique_name": "<unique-name>",
    "uti": "<uti>",
    "ver": "<version>",
    "wids": [
        "<wids>"
    ],
    "xms_ftd": "<xms-ftd>",
    "xms_idrel": "<xms-idrel>",
    "xms_st": {
        "sub": "<xms-st-sub>"
    },
    "xms_tcdt": <xms-tcdt>,
    "xms_tdbr": "<xms-tdbr>"
}.[Signature]

Senario 2 (akhq doesn't understand this flow, roles/groups are included in the claim)

When i mimic the second senario and expose my entra app under this URI api://client-id/.default and then request authorization with uri scope, i do receive roles and groups in the claim

Example auth url

https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize?client_id=<client_id>&response_type=code&redirect_uri=http://localhost:9091/oauth/callback/azure&scope=client-id/.default

Example config used

    oauth2:
        enabled: true
        debug: true
        clients:
          azure:
            client-id: "<client-id>"
            client-secret: "<client-secret>"
            scopes:
              - client-id/.default
            openid:
              issuer: "https://login.microsoftonline.com/2efewfwef/v2.0"

Example Generated jwt structre, (akhq did not worked with the above config)

{
    "typ": "JWT",
    "alg": "RS256",
    "kid": "<key-id>"
}.{
    "aud": "<audience>",
    "iss": "https://login.microsoftonline.com/<tenant-id>/v2.0",
    "iat": <issued-at>,
    "nbf": <not-before>,
    "exp": <expiration>,
    "aio": "<aio>",
    "azp": "<authorized-party>",
    "azpacr": "<authorized-party-acr>",
    "groups": [
        "<group-id-1>",
        "<group-id-2>"
    ],
    "idp": "https://sts.windows.net/<idp-tenant-id>/",
    "name": "<name>",
    "oid": "<object-id>",
    "preferred_username": "<preferred-username>",
    "rh": "<rh>",
    "roles": [
        "<role-1>"
    ],
    "scp": "<scopes>",
    "sid": "<session-id>",
    "sub": "<subject>",
    "tid": "<tenant-id>",
    "uti": "<uti>",
    "ver": "<version>",
    "wids": [
        "<wids-1>",
        "<wids-2>",
        "<wids-3>"
    ]
}.[Signature]

However with this example config, akhq doesn't understand this flow and i receive the following error:

message	'Internal Server Error: Cannot invoke "String.contains(java.lang.CharSequence)" because "token" is null'
_links	
self	
href	"/oauth/callback/azure?code=gowrhgowrhgowhwvgworhgiwuhgfuwrgh379t6735yg3ty78n0%3d&session_state=c34ct34t35ty3"
templated	false
_embedded	
stacktrace	
0	
message	'java.lang.NullPointerException: Cannot invoke "String.contains(java.lang.CharSequence)" because "token" is null\n\tat io.micronaut.security.token.jwt.validator.JwtValidator.hasAtLeastTwoDots(JwtValidator.java:101)\n\tat io.micronaut.security.token.jwt.validator.JwtValidator.validate(JwtValidator.java:79)\n\tat io.micronaut.security.oauth2.endpoint.token.response.validation.DefaultOpenIdTokenResponseValidator.parseJwtWithValidSignature(DefaultOpenIdTokenResponseValidator.java:162)\n\tat io.micronaut.security.oauth2.endpoint.token.response.validation.DefaultOpenIdTokenResponseValidator.validate(DefaultOpenIdTokenResponseValidator.java:90)\n\tat io.micronaut.security.oauth2.endpoint.authorization.response.DefaultOpenIdAuthorizationResponseHandler.validateOpenIdTokenResponse(DefaultOpenIdAuthorizationResponseHandler.java:238)\n\tat io.micronaut.security.oauth2.endpoint.authorization.response.DefaultOpenIdAuthorizationResponseHandler.createAuthenticationResponse(DefaultOpenIdAuthorizationResponseHandler.java:198)\n\tat io.micronaut.security.oauth2.endpoint.authorization.response.DefaultOpenIdAuthorizationResponseHandler.lambda$handle$0(DefaultOpenIdAuthorizationResponseHandler.java:133)\n\tat reactor.core.publisher.FluxSwitchMapNoPrefetch$SwitchMapMain.subscribeInner(FluxSwitchMapNoPrefetch.java:210)\n\tat reactor.core.publisher.FluxSwitchMapNoPrefetch$SwitchMapMain.onNext(FluxSwitchMapNoPrefetch.java:164)\n\tat reactor.core.publisher.FluxPublishOn$PublishOnSubscriber.runAsync(FluxPublishOn.java:446)\n\tat reactor.core.publisher.FluxPublishOn$PublishOnSubscriber.run(FluxPublishOn.java:533)\n\tat io.micronaut.core.propagation.PropagatedContext.lambda$wrap$3(PropagatedContext.java:211)\n\tat reactor.core.scheduler.WorkerTask.call(WorkerTask.java:84)\n\tat reactor.core.scheduler.WorkerTask.call(WorkerTask.java:37)\n\tat io.micronaut.core.propagation.PropagatedContext.lambda$wrap$4(PropagatedContext.java:228)\n\tat io.micrometer.core.instrument.composite.CompositeTimer.recordCallable(CompositeTimer.java:129)\n\tat io.micrometer.core.instrument.Timer.lambda$wrap$1(Timer.java:203)\n\tat io.micronaut.core.propagation.PropagatedContext.lambda$wrap$4(PropagatedContext.java:228)\n\tat io.micrometer.core.instrument.composite.CompositeTimer.recordCallable(CompositeTimer.java:129)\n\tat io.micrometer.core.instrument.Timer.lambda$wrap$1(Timer.java:203)\n\tat java.base/java.util.concurrent.FutureTask.run(Unknown Source)\n\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)\n\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)\n\tat java.base/java.lang.Thread.run(Unknown Source)\n

@youcefguichi
Copy link
Author
youcefguichi commented Mar 31, 2025

hey @AlexisSouquiere, any update concerning this one? Thank you!

@AlexisSouquiere
Copy link
Collaborator

I just tried and I'm able to make it works on my side. Your scenario 1 looks good except that you need to add the groups claim in the tokens.

My config looks like this (the micronaut.security.oauth2.client is the same as yours):

akhq:
  security:
    oidc:
      providers:
        azure:
          label: "Login with Azure"
          username-field: preferred_username
          groups-field: groups
          groups:
            - name: <my_group_guid>
              groups:
                - admin

In Azure, I added the groups claim (doc here):
Image

When login I can see in the id_token that it contains a list of all my groups (guid in the test I did) and it maps it with the one I put in my AKHQ configuration

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wait for reply Need more information from reporter
Projects
Status: Backlog
Development

No branches or pull requests

2 participants
0