-
Notifications
You must be signed in to change notification settings - Fork 207
Description
Describe the bug
Django project with custom auth backend. On login page load, a 'Login with Microsoft' url is generated with the 'construct_msal_login_url()' function, and displayed on the page with a templatetag, this function performs the 'initiate_auth_code_flow' step and stores the resulting auth_flow in session for use on callback.
User clicks Login with Microsoft, SSO is enabled in environment, returns to callback, on inspecting the same auth_flow var (stored in session) the 'state' key has been completely changed to a super long value that almost looks like a token.
To Reproduce
Client app is
client_app = msal.ConfidentialClientApplication(
client_id=settings.MSAL_AUTH["client_id"],
client_credential=settings.MSAL_AUTH["client_secret"],
authority=f"https://login.microsoftonline.com/{settings.MSAL_AUTH['tenant_id'] or 'common'}",
)
Steps to reproduce the behavior:
def construct_msal_login_url(request: HttpRequest):
"""
Construct the redirect URL for MSAL authentication.
Args:
request: Current HTTP request object.
Returns:
Auth Flow
"""
# Get the next url from query string if present
next_url = request.GET.get("next", "/")
# Build our callback (redirect) URL that will be used once authenticated
redirect_url = (
f"{settings.MSAL_AUTH['scheme']}://{settings.MSAL_AUTH['site_domain']}{reverse('msal_auth:callback')}"
)
# Create the full Auth url for Microsoft Authentication
auth_flow = client_app.initiate_auth_code_flow(scopes=settings.MSAL_AUTH["scopes"], redirect_uri=redirect_url)
# Save to Session for use with callback getting Access Token
request.session["auth_flow"] = auth_flow
request.session["next"] = next_url
test = request.session["auth_flow"] # <---------------- STATE LOOKS LIKE: 'HrDRgbTYBLjZfKCq'
return auth_flow
Template Tag
@register.simple_tag(takes_context=True)
def msal_auth_url(context):
"""
Returns the MSAL authentication URL for the current request context.
Args:
context: The template context containing the request.
Returns:
str: The MSAL authentication URL.
"""
request = context["request"]
auth_flow = auth.construct_msal_login_url(request)
return auth_flow["auth_uri"]
Link on login page
<a href="{% msal_auth_url %}"><svg ...../></a>
Callback /microsoft/callback
def from_auth_redirect(request: HttpRequest):
"""
View that handles the redirect from Microsoft after authentication.
Args:
request: Current HTTP request object.
Returns:
Redirect to the next URL or login page if authentication fails.
"""
test = request.session["auth_flow"] # <--------------------- STATE LOOKS LIKE: 'eyJ0b2tlbiI6IkNBNjZHa21ZNld4MkViQkxVN3pkTDFkSWVCNzBDTHJTYkxRbTFQV0J3akg3QjNZSmtPVmt4U3d4ZXR6cnpYQkoiLCJuZXh0IjoiLyJ9:1ubGgs:kEhcT04HwPHH2v1Kk6-HfpeF_xdqS1I1yYDC4vxlOLg'
.....
So then there is a state mismatch error, I can't find any code changing the state, that is the entire code flow that I have written, URL is generated, Auth initiated, user clicks, callback shows invalid state in the stored auth_flow, BUT the state on the return params is correct....something is changing the stored state.
Expected behavior
Stored state doesn't change
What you see instead
Stored state changes from
'HrDRgbTYBLjZfKCq'
to
'eyJ0b2tlbiI6IkNBNjZHa21ZNld4MkViQkxVN3pkTDFkSWVCNzBDTHJTYkxRbTFQV0J3akg3QjNZSmtPVmt4U3d4ZXR6cnpYQkoiLCJuZXh0IjoiLyJ9:1ubGgs:kEhcT04HwPHH2v1Kk6-HfpeF_xdqS1I1yYDC4vxlOLg'
The MSAL Python version you are using
Paste the output of this
1.32.3
Additional context