Chainlit / chainlit

Build Conversational AI in minutes ⚡️
https://docs.chainlit.io
Apache License 2.0
6.69k stars 865 forks source link

no user role with Azure AD authentication #1147

Open weipienlee opened 1 month ago

weipienlee commented 1 month ago

Although authentication works, with the below I couldn't find any info on user roles that are assigned to users in the App Registration.

def oauth_callback(provider_id: str, token: str, raw_user_data: dict, default_user: cl.User): print(f"{provider_id=}") print(f"{token=}") print(f"{raw_user_data=}") print(f"{default_user=}") return default_user

hayescode commented 1 month ago

You need azure-ad-hybrid authentication for that. It was just added a few weeks ago.

weipienlee commented 1 month ago

that's great news @hayescode, but how/where? I'm on the latest 1.1.400r1

weipienlee commented 1 month ago

ah, the env vars. Got it!

weipienlee commented 1 month ago

having troubles after replacing the OAUTH_AZURE_AD_* keys with OAUTH_AZURE_AD_HYBRID_*. Get double login buttons, one works, the other seems to have no call_back uri. But that button shouldn't be there in the first place, i guess.

image

AADSTS700016: Application with identifier 'None' was not found in the directory 'Signify'. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You may have sent your authentication request to the wrong tenant.

weipienlee commented 1 month ago

@hayescode I looked at the raw user data (provider_id='azure-ad-hybrid'), but can't find the roles. These are the keys (no nested values):

raw_user_data.keys()=dict_keys(['@odata.context', 'businessPhones', 'displayName', 'givenName', 'jobTitle', 'mail', 'mobilePhone', 'officeLocation', 'preferredLanguage', 'surname', 'userPrincipalName', 'id', 'image'])

hayescode commented 1 month ago

Add id_token to your params in the decorated login params, then decode it using jwt. ChatGPT will show you how to decode/extract the app role.

weipienlee commented 1 month ago

Not very familiar with this. When not using msal, it gets tricky very quickly. This what I used:

@cl.oauth_callback
def oauth_callback(provider_id: str, token: str, raw_user_data: dict, default_user: cl.User):
    from msal.oauth2cli.oidc import decode_id_token 
    a = decode_id_token(id_token=token, client_id=os.environ['OAUTH_AZURE_AD_HYBRID_CLIENT_ID'])
    print(a)

this is what it returns:

msal.oauth2cli.oidc.IdTokenAudienceError: 3. The aud (audience) claim must contain this client's client_id "---GUID---", case-sensitively. Was your client_id in wrong casing? Current epoch = 2024-07-19 18:51:19. The id_token was approximately: { "aud": "https://graph.microsoft.com", ...

it's https://graph.microsoft.com instead. I can fill that in and it will not complain, but that doesn't make any sense. Furthermore, no roles.

hayescode commented 1 month ago

Add id_token params at the end.

@cl.oauth_callback
def oauth_callback(provider_id: str, token: str, raw_user_data: dict, default_user: cl.User, id_token: str):

Then decode the id_token. You don't need any other API calls you already have the token with app roles here.

weipienlee commented 1 month ago

Yes, that does it @hayescode! Last issue, do you know why there are 2 auth "flows"/buttons presented? The one not working calls a microsoft authorize with:

It seems it is the "azure-ad" flow, for which I didn't provide the env vars of course. I guess I need a way to disable it somehow?

image

weipienlee commented 1 month ago

For those with the same problem, I have a temporary work around. Add this to stylesheet.css:

/* Temporary patch for "duplicated" continue with Microsoft */
.MuiStack-root .MuiButtonBase-root:first-of-type:has(span > svg[data-testid="MicrosoftIcon"]) {
    display: none;
}