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

Support for Microsof multi-tenant #295

Closed
mkrle opened this issue Nov 17, 2020 · 4 comments
Closed

Support for Microsof multi-tenant #295

mkrle opened this issue Nov 17, 2020 · 4 comments

Comments

@mkrle
Copy link

mkrle commented Nov 17, 2020

Is your feature request related to a problem? Please describe.

Due to MS multi-tenant OIDC implementation violating RFC, it's not possible to authenticate against Azure from multiple tenants in a simple fashion. The error I get is:

authlib.jose.errors.InvalidClaimError: invalid_claim: Invalid claim "iss"

I feel this is an issue on MS side which is why I am reporting a feature request and not a bug. Still, considering that it's MS, it would be worthwhile to accommodate their quirks.

References:
authlib/loginpass#65
https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-convert-app-to-be-multi-tenant

Describe the solution you'd like

Ability to at least disable issuer validation. More elaborate tenant verification would be nice in the future.

Describe alternatives you've considered

The only alternative I see right now is using MSAL which I would like to avoid.

@lepture
Copy link
Owner

lepture commented Nov 20, 2020

This could never be a feature in Authlib itself. You may need to submit it in loginpass. And it is already fixed in loginpass master code (not released yet).

@lepture lepture closed this as completed Nov 20, 2020
@vjsingh
Copy link

vjsingh commented Dec 14, 2020

@lepture - Thanks for fixing this! Oh Microsoft...

When is the next version of loginpass with the fix going to be released?

EDIT: Also, what is the recommended fix in the meantime?

@dwt
Copy link

dwt commented Oct 7, 2021

@lepture could you perhaps add a pointer to what part of the loginpass source works around this issue? I have to support it too (just with authlib) and would like to understand how you worked around that.

This file seems like the obvious place, but I don't understand what you did there.

@nimasmi
Copy link

nimasmi commented Aug 29, 2023

For the record, I implemented something similar to Loginpass's solution above, but for a Django app that uses Authlib directiy, without Loginpass.

from authlib.integrations.django_client import DjangoOAuth2App
from django.conf import settings


class CustomDjangoOAuth2App(DjangoOAuth2App):
    """Custom DjangoOAuth2App to fix inconsistencies in Microsoft's OpenID Connect implementation.

    - See Authlib "wontfix" issue https://github.com/lepture/authlib/issues/295
    - This is a known Microsoft bug https://github.com/MicrosoftDocs/azure-docs/issues/38427
    - This fix is modelled on one in the Authlib-based Loginpass library: https://github.com/authlib/loginpass/issues/65

    In short Microsoft returns metadata reporting the issuer as
    'https://login.microsoftonline.com/{tenantid}/v2.0', with the `{tenantid}`
    placeholder not replaced. Authlib tries to validate the issuer, expecting
    the tenantid to be formatted. We must make that substitution in order for
    the comparison to pass.
    """

    def load_server_metadata(self):
        """Return metadata, but replace {tenantid} with the configured tenant ID."""
        metadata = super().load_server_metadata()
        issuer = metadata["issuer"]
        issuer = issuer.replace("{tenantid}", settings.AZUREAD_TENANT_ID)
        metadata["issuer"] = issuer
        return metadata

I imported that into my SSO views module, and created the Oauth client thus:

oauth.register(
    ...
    client_cls=CustomDjangoOAuth2App,
    ...
    server_metadata_url="https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration",
    authorize_url=f"https://login.microsoftonline.com/{settings.AZUREAD_TENANT_ID}/oauth2/v2.0/authorize",
)

I hope this helps as drop-in replacement code, outside of the context of LoginPass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants