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

Azure B2C v2 authentication via generic OIDC back-end produces "KeyError 'access_token'" on application's redirect page #699

Open
svdHero opened this issue Aug 1, 2022 · 6 comments

Comments

@svdHero
Copy link

svdHero commented Aug 1, 2022

Coming from WeblateOrg/weblate#7911

Expected behaviour

After successful login and redirect to the application's specified redirect uri, I expect to be logged in without any error message.

Actual behaviour

I am using Azure B2C for Weblate authentication via OpenID Connect. I've set the environment variable WEBLATE_SOCIAL_AUTH_OIDC_OIDC_ENDPOINT to the value https://my-company-auth.b2clogin.com/my-company-auth.onmicrosoft.com/B2C_SIGNUP_SIGNIN/v2.0.

When I click on the Oidc button on the Weblate login page https://weblate.mycompany.com/accounts/login/, I am redirected to Azure B2C and I see the correct policy login page. I can also log in successfully and I am redirected to https://weblate.mycompany.com/accounts/complete/oidc/.

But then I see the following Django error message:

KeyError at /accounts/complete/oidc/
'access_token'
Request Method: GET
Request URL: https://weblate.mycompany.com/accounts/complete/oidc/?state=pOrucHH1HBEY...
Django Version: 4.0.6
Exception Type: KeyError
Exception Value:
'access_token'
Exception Location: /usr/local/lib/python3.10/site-packages/social_core/backends/open_id_connect.py, line 234, in request_access_token
Python Executable: /usr/local/bin/python
Python Version: 3.10.5
Python Path:
['/',
'/usr/local/lib/python3.10/site-packages/git/ext/gitdb',
'/',
'/usr/local/bin',
'/usr/local/lib/python310.zip',
'/usr/local/lib/python3.10',
'/usr/local/lib/python3.10/lib-dynload',
'/usr/local/lib/python3.10/site-packages',
'/app/data/python',
'/usr/local/lib/python3.10/site-packages/gitdb/ext/smmap']
Server time: Thu, 21 Jul 2022 11:42:04 +0000

What are the steps to reproduce this issue?

Input clear steps to reproduce the issue for a maintainer.

  1. Setup Azure B2C in Azure Portal.
  2. Configure Weblate authentication for OpenID Connect by setting these environment variables.
  3. Go to Weblates Login-Page https://weblate.mycompany.com/accounts/login/ and click on the button "Oidc".
  4. Log in via the Azure B2C login page.
  5. Wait until the Weblate redirect uri https://weblate.mycompany.com/accounts/complete/oidc/ is loaded.
  6. Read the Django error message.

Any logs, error output, etc?

See above

Any other comments?

According to the error message, the problem seems to be here:

response['access_token']

and the code expects to find the field access_token in the http response from the Azure B2C OIDC.

If that helps, the response from https://mycompanyauth.b2clogin.com/mycompanyauth.onmicrosoft.com/B2C_SIGNUP_SIGNIN/v2.0/.well-known/openid-configuration looks like this:

{
  "issuer": "https://mycompanyauth.b2clogin.com/32754e0f-75ef-4654-9eae-779b00b83c55/v2.0/",
  "authorization_endpoint": "https://mycompanyauth.b2clogin.com/mycompanyauth.onmicrosoft.com/b2c_signup_signin/oauth2/v2.0/authorize",
  "token_endpoint": "https://mycompanyauth.b2clogin.com/mycompanyauth.onmicrosoft.com/b2c_signup_signin/oauth2/v2.0/token",
  "end_session_endpoint": "https://mycompanyauth.b2clogin.com/mycompanyauth.onmicrosoft.com/b2c_signup_signin/oauth2/v2.0/logout",
  "jwks_uri": "https://mycompanyauth.b2clogin.com/mycompanyauth.onmicrosoft.com/b2c_signup_signin/discovery/v2.0/keys",
  "response_modes_supported": [
    "query",
    "fragment",
    "form_post"
  ],
  "response_types_supported": [
    "code",
    "code id_token",
    "code token",
    "code id_token token",
    "id_token",
    "id_token token",
    "token",
    "token id_token"
  ],
  "scopes_supported": [
    "openid"
  ],
  "subject_types_supported": [
    "pairwise"
  ],
  "id_token_signing_alg_values_supported": [
    "RS256"
  ],
  "token_endpoint_auth_methods_supported": [
    "client_secret_post",
    "client_secret_basic"
  ],
  "claims_supported": [
    "name",
    "given_name",
    "family_name",
    "email",
    "upn",
    "oid",
    "idp",
    "tid",
    "roles",
    "isForgotPassword",
    "postalCode",
    "state",
    "country",
    "iss",
    "iat",
    "exp",
    "aud",
    "acr",
    "nonce",
    "auth_time"
  ]
}

Further browser debugging shows, that Weblate issued a request to
https://login.microsoftonline.com/0eca7f40-e581-4860-a149-172d3a66a43b/oauth2/v2.0/authorize?client_id=e60c2871-629b-4c40-8dd2-a8418ab7ce8d&redirect_uri=https://mycompanyauth.b2clogin.com/mycompanyauth.onmicrosoft.com/oauth2/authresp&response_type=code&scope=openid+profile&response_mode=form_post&nonce=g78JTkGi8YBTeaGbHjgNlg==&state=StateProperties=eyJTSUQiOiJ4LW1zLWNwaW0tcmM6NWQ5YTNkZmQtZDkwZC00MGJlLTkxYWUtYjdjZmFhMjZjYzc0IiwiVElEIjoiZGJhNTFmODAtZGM5Yi00MzVjLTg2ZTctZDQ5NTQ3MjBkNTFmIiwiVE9JRCI6IjMyNzU0ZTBmLTc1ZWYtNDY1NC05ZWFlLTc3OWIwMGI4M2M1NSJ9

Note the request query parameter response_type which is set to code. So the response probably should not not have a field access_token anyway, as far as my basic OIDC / OAuth knowledge goes.

@nijel mentioned #459, but I don't think this is related, because, as explained above, this seems to be a parsing bug on the Social-Auth-Core client side and not an endpoint error on the Microsoft server side.

@svdHero
Copy link
Author

svdHero commented Aug 25, 2022

Any comment on this?

@nijel
Copy link
Member

nijel commented Aug 26, 2022

@svdHero
Copy link
Author

svdHero commented Aug 29, 2022

@nijel as far as I understand it, this is a bug with the OIDC back-end in general, since, as described above, there seems to be something wrong with parsing the response.
So even if I did use the B2C-Tenant back-end, this bug in the OIDC back-end would still exist and hit the next person who wants to use a generic OIDC authentication. I assume that there is a general interest in generic OIDC, because you've just added support for it in a recent release, haven't you? Hence, it would be good if this feature worked with any OIDC identity provider, even with Azure B2C.

Can you reproduce the problem I've described above? Have you looked into it?

Now, in my particular use case, I chose the vanilla OIDC back-end over the B2C-Tenant back-end, because, within my cloud environment, that was just easier than fiddling with Docker compose files, volumes and Weblate's /app/data/settings-override.py (compare WeblateOrg/weblate#7885).

@nijel
Copy link
Member

nijel commented Aug 30, 2022

Sorry, I currently have no clue whether it's bug in the generic backend or something specific to Azure. Using service specific backend is always recommend when it exists

@svdHero
Copy link
Author

svdHero commented Aug 31, 2022

Okay, I will look into the Azure specific back-end again.

However, I still think something might be wrong with the Weblate response parser. After all, I would expect Microsoft to implement the OIDC standard on their identity systems correctly. Are there any plans to investigate this? Maybe @omab who created open_id_connect.py in ae03e08 or @zulrang who added the response['access_token'] in #240 could help?

Please let me know if I can provide any further information that could be useful.

@zchoate
Copy link
Contributor

zchoate commented Mar 21, 2023

I proposed PR 777 that may help in the adoption of the B2C provider since it supports the updated endpoints. You can also achieve a similar result by setting the following values:

  • SOCIAL_AUTH_AZUREAD_B2C_OAUTH2_AUTHORITY_HOST to tenant name + b2clogin.com: foobar.b2clogin.com
  • SOCIAL_AUTH_AZUREAD_B2C_OAUTH2_TENANT_ID to tenant name + onmicrosoft.com: foobar.onmicrosoft.com
  • SOCIAL_AUTH_AZUREAD_B2C_OAUTH2_POLICY to the name of the policy: b2c_1a_signin

That seemed to work in some initial testing but probably isn't the greatest solution long term.

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

No branches or pull requests

3 participants