Closed DerekCL closed 3 months ago
Thanks for bringing this to our attention. A few things here.
Yes, the issue can be reproduced by simply running this one-liner in command line:
python -c "from msal import PublicClientApplication as PCA; PCA('client_id').get_authorization_request_url(['openid', 'offline_access'])"
and it can be reproduced in all different MSAL Python APIs and versions, because it is an intentional behavior.
We could, and will, update our current confusing error message from
ValueError: API does not accept frozenset({'offline_access', 'openid', 'profile'}) value as user-provided scopes
to
ValueError: You cannot use any scope value that is reserved. Your input: ['openid', 'offline_access'] The reserved list: ['openid', 'offline_access', 'profile']
so, that is the root cause that you will need to adjust from your side.
Besides, the function that you called, get_authorization_request_url()
, has long be deprecated. There is a deprecation warning, guess you did not notice it, possibly because your app did not show warnings by default.
Since you are using Flask, there is even a better recommendation for you. Try our Flask web app sample which was built upon (much) higher level API, and then you won't even run into the "what MSAL API to use", "what scope to use for merely sign-in" issue in the first place.
Describe the bug When using msal version 1.28.1 for azure b2c, passing a frozenset object as the scopes parameter to get_authorization_request_url results in a ValueError: API does not accept frozenset({'openid', 'offline_access', 'profile'}) value as user-provided scopes.
Specifically this error occurs because in
def get_authorization_request_url( self, scopes, # type: list[str] login_hint=None, # type: Optional[str] state=None, # Recommended by OAuth2 for CSRF protection redirect_uri=None, response_type="code", # Could be "token" if you use Implicit Grant prompt=None, nonce=None, domain_hint=None, # type: Optional[str] claims_challenge=None, **kwargs): """Constructs a URL for you to start a Authorization Code Grant.
the _decorate_scope is changing the type to a frozen set
To Reproduce Steps to reproduce the behavior:
{ "authority": "https://login.microsoftonline.com/",
"client_id": "",
"client_secret": "",
"scope": ["openid", "offline_access"]
}
Run the sample: python sample.py config.json
Observe the ValueError being raised.
Expected behavior The sample should successfully acquire an authorization code and proceed with the authentication flow.
What you see instead 127.0.0.1 - - [14/Jun/2024 06:24:24] "GET /login HTTP/1.1" 500 - Traceback (most recent call last): File "/home/gitderekt/.cache/pypoetry/virtualenvs/woodstock-pfnYhH4M-py3.12/lib/python3.12/site-packages/flask/app.py", line 1488, in call return self.wsgi_app(environ, start_response) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/gitderekt/.cache/pypoetry/virtualenvs/woodstock-pfnYhH4M-py3.12/lib/python3.12/site-packages/opentelemetry/instrumentation/flask/init.py", line 359, in _wrapped_app result = wsgi_app(wrapped_app_environ, _start_response) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/gitderekt/.cache/pypoetry/virtualenvs/woodstock-pfnYhH4M-py3.12/lib/python3.12/site-packages/flask/app.py", line 1466, in wsgi_app response = self.handle_exception(e) ^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/gitderekt/.cache/pypoetry/virtualenvs/woodstock-pfnYhH4M-py3.12/lib/python3.12/site-packages/flask/app.py", line 1463, in wsgi_app response = self.full_dispatch_request() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/gitderekt/.cache/pypoetry/virtualenvs/woodstock-pfnYhH4M-py3.12/lib/python3.12/site-packages/flask/app.py", line 872, in full_dispatch_request rv = self.handle_user_exception(e) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/gitderekt/.cache/pypoetry/virtualenvs/woodstock-pfnYhH4M-py3.12/lib/python3.12/site-packages/flask/app.py", line 870, in full_dispatch_request rv = self.dispatch_request() ^^^^^^^^^^^^^^^^^^^^^^^ File "/home/gitderekt/.cache/pypoetry/virtualenvs/woodstock-pfnYhH4M-py3.12/lib/python3.12/site-packages/flask/app.py", line 855, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/gitderekt/sss/Oma/app/routes/auth/auth.py", line 95, in login auth_url = get_auth_url(client, url_for("auth.auth_callback", _external=True)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/gitderekt/sss/Oma/app/routes/auth/auth.py", line 45, in get_auth_url return client.get_authorization_request_url(scopes, redirect_uri=redirect_uri) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/gitderekt/.cache/pypoetry/virtualenvs/woodstock-pfnYhH4M-py3.12/lib/python3.12/site-packages/msal/application.py", line 946, in get_authorization_request_url scope=self._decorate_scope(scopes), ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/gitderekt/.cache/pypoetry/virtualenvs/woodstock-pfnYhH4M-py3.12/lib/python3.12/site-packages/msal/application.py", line 626, in _decorate_scope raise ValueError( ValueError: API does not accept frozenset({'offline_access', 'openid', 'profile'}) value as user-provided scopes
The MSAL Python version you are using 1.28.1
Additional context Add any other context about the problem here.