inventree / InvenTree

Open Source Inventory Management System
https://docs.inventree.org
MIT License
4.35k stars 790 forks source link

PUI login issue with OpenIDConnect #7972

Open GoryMoon opened 3 months ago

GoryMoon commented 3 months ago

Please verify that this bug has NOT been raised before.

Describe the bug*

When using the PUI login form and logging in with a OpenIDConnect provider it gives an error. Using the regular login works.

OpenIDConnectAdapter.__init__() missing 1 required positional argument: 'provider_id'

Steps to Reproduce

You need to add an OpenIDConnect provider and try to login in with it on the PUI login page.

Expected behaviour

To get logged in without an error.

Deployment Method

Version Information

Version Information:

InvenTree-Version: 0.15.8 Django Version: 4.2.14 Commit Hash: aed43b0 Commit Date: 2024-08-08

Database: postgresql Debug-Mode: False Deployed using Docker: True Platform: Linux-6.1.21-v8+-aarch64-with Installer: DOC

Active plugins: [{'name': 'InvenTreeBarcode', 'slug': 'inventreebarcode', 'version': '2.0.0'}, {'name': 'InvenTreeCoreNotificationsPlugin', 'slug': 'inventreecorenotificationsplugin', 'version': '1.0.0'}, {'name': 'InvenTreeCurrencyExchange', 'slug': 'inventreecurrencyexchange', 'version': '1.0.0'}, {'name': 'InvenTreeLabel', 'slug': 'inventreelabel', 'version': '1.0.0'}, {'name': 'InvenTreeLabelMachine', 'slug': 'inventreelabelmachine', 'version': '1.0.0'}, {'name': 'InvenTreeLabelSheet', 'slug': 'inventreelabelsheet', 'version': '1.0.0'}, {'name': 'DigiKeyPlugin', 'slug': 'digikeyplugin', 'version': '1.0.0'}, {'name': 'LCSCPlugin', 'slug': 'lcscplugin', 'version': '1.0.0'}, {'name': 'MouserPlugin', 'slug': 'mouserplugin', 'version': '1.0.0'}, {'name': 'TMEPlugin', 'slug': 'tmeplugin', 'version': '1.0.0'}]

Please verify if you can reproduce this bug on the demo site.

Relevant log output

Environment:

Request Method: GET
Request URL: http://.../api/auth/social/openid_connect/login/

Django Version: 4.2.14
Python Version: 3.11.9
Installed Applications:
['django.contrib.admin',
 'build.apps.BuildConfig',
 'common.apps.CommonConfig',
 'company.apps.CompanyConfig',
 'plugin.apps.PluginAppConfig',
 'label.apps.LabelConfig',
 'order.apps.OrderConfig',
 'part.apps.PartConfig',
 'report.apps.ReportConfig',
 'stock.apps.StockConfig',
 'users.apps.UsersConfig',
 'machine.apps.MachineConfig',
 'web',
 'generic',
 'InvenTree.apps.InvenTreeConfig',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'user_sessions',
 'whitenoise.runserver_nostatic',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'maintenance_mode',
 'django_filters',
 'rest_framework',
 'corsheaders',
 'crispy_forms',
 'import_export',
 'django_cleanup.apps.CleanupConfig',
 'mptt',
 'markdownify',
 'djmoney',
 'djmoney.contrib.exchange',
 'error_report',
 'django_q',
 'formtools',
 'dbbackup',
 'taggit',
 'flags',
 'allauth',
 'allauth.account',
 'allauth.socialaccount',
 'django_otp',
 'django_otp.plugins.otp_totp',
 'django_otp.plugins.otp_static',
 'allauth_2fa',
 'dj_rest_auth',
 'dj_rest_auth.registration',
 'drf_spectacular',
 'django_ical',
 'allauth.socialaccount.providers.openid_connect']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'x_forwarded_for.middleware.XForwardedForMiddleware',
 'user_sessions.middleware.SessionMiddleware',
 'django.middleware.locale.LocaleMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'corsheaders.middleware.CorsMiddleware',
 'whitenoise.middleware.WhiteNoiseMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'InvenTree.middleware.InvenTreeRemoteUserMiddleware',
 'django_otp.middleware.OTPMiddleware',
 'InvenTree.middleware.CustomAllauthTwoFactorMiddleware',
 'allauth.account.middleware.AccountMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'InvenTree.middleware.AuthRequiredMiddleware',
 'InvenTree.middleware.Check2FAMiddleware',
 'maintenance_mode.middleware.MaintenanceModeMiddleware',
 'InvenTree.middleware.InvenTreeExceptionProcessor']

Traceback (most recent call last):
  File "/root/.local/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/.local/lib/python3.11/site-packages/allauth/socialaccount/providers/oauth2/views.py", line 83, in view
    self.adapter = adapter(request)
                   ^^^^^^^^^^^^^^^^

Exception Type: TypeError at /api/auth/social/openid_connect/login/
Exception Value: OpenIDConnectAdapter.__init__() missing 1 required positional argument: 'provider_id'
matmair commented 3 months ago

Thank you for the report. What OIDC provider are you using?

matmair commented 3 months ago

Note: This seems to apply to all methods that use the API to do a SSO login call with a OIDC provider. There seems to be no coverage on API logins. Would probably be fixed by https://github.com/inventree/InvenTree/pull/6293

GoryMoon commented 3 months ago

I'm using authentik, this is the specific provider within authentik I'm using https://docs.goauthentik.io/docs/providers/oauth2/

matmair commented 1 week ago

@GoryMoon is this still the case with the current 0.16.x release series?

GoryMoon commented 1 week ago

When I click the SSO login button it redirects me to https://.../platform/null with a 404 page. I haven't changed anything regarding the SSO login.


When clearing the session the following is returned by https://.../api/auth/providers/

{"sso_enabled":true,"sso_registration":true,"mfa_required":false,"mfa_enabled":true,"providers":[{"id":"openid_connect","name":"OpenID Connect","configured":true,"login":null,"connect":null,"display_name":"Internal"}],"registration_enabled":false,"password_forgotten_enabled":true}

Version Information:

InvenTree-Version: 0.16.8 Django Version: 4.2.15 Commit Hash: f23d405 Commit Date: 2024-11-07

Database: postgresql Debug-Mode: False Deployed using Docker: True Platform: Linux-6.1.21-v8+-aarch64-with Installer: DOC

Active plugins: [{'name': 'InvenTreeBarcode', 'slug': 'inventreebarcode', 'version': '2.1.0'}, {'name': 'InvenTreeCoreNotificationsPlugin', 'slug': 'inventreecorenotificationsplugin', 'version': '1.0.0'}, {'name': 'InvenTreeCurrencyExchange', 'slug': 'inventreecurrencyexchange', 'version': '1.0.0'}, {'name': 'InvenTreeLabel', 'slug': 'inventreelabel', 'version': '1.1.0'}, {'name': 'InvenTreeLabelMachine', 'slug': 'inventreelabelmachine', 'version': '1.0.0'}, {'name': 'InvenTreeLabelSheet', 'slug': 'inventreelabelsheet', 'version': '1.0.0'}, {'name': 'DigiKeyPlugin', 'slug': 'digikeyplugin', 'version': '1.0.0'}, {'name': 'LCSCPlugin', 'slug': 'lcscplugin', 'version': '1.0.0'}, {'name': 'MouserPlugin', 'slug': 'mouserplugin', 'version': '1.0.0'}, {'name': 'TMEPlugin', 'slug': 'tmeplugin', 'version': '1.0.0'}]

matmair commented 1 week ago

@GoryMoon can you provide how you configure it? Please make sure to not include full tokens but the settings you used

matmair commented 1 week ago

It would also be interesting if you are using the opened or openid_connect provider

GoryMoon commented 1 week ago

To note, my current config works in the old UI but not in PUI.

In the config file I have this:

social_backends:
  - 'allauth.socialaccount.providers.openid_connect'

Admin interface config (I added the key to test but didn't change anything): Image

SchrodingersGat commented 5 days ago

@GoryMoon where are you seeing the error exactly when you try to login via PUI?

GoryMoon commented 5 days ago

The log that I attached was from the error page in the Admin interface. At the moment I can't get that error again because of the error above sending me to a 404 page.

SchrodingersGat commented 4 days ago

Does SSO work with the "classic" user interface?

GoryMoon commented 4 days ago

Yes, SSO login works with the "classic" interface.

This is the redirects that happens when I click the SSO button in the "classic" interface it it's of any interest. (I made sure to remove all sensitive parts) The auth. subdomain contains my authentik installation and inventree. is my inventree installation. Both run on the same server as docker containers. Status Code URL IP Page Type Redirect Type Redirect URL
302 https://inventree.example.com/accounts/x2/login/?process=login&next=%2F 10.0.0.2 server_redirect temporary https://auth.example.com/application/o/authorize/?client_id=dummy_client_id&redirect_uri=http%3A%2F%2Finventree.example.com%2Faccounts%2Fx2%2Flogin%2Fcallback%2F&scope=profile+email+openid&response_type=code&state=dummy_state
302 https://auth.example.com/application/o/authorize/?client_id=dummy_client_id&redirect_uri=http%3A%2F%2Finventree.example.com%2Faccounts%2Fx2%2Flogin%2Fcallback%2F&scope=profile+email+openid&response_type=code&state=dummy_state 10.0.0.2 server_redirect temporary https://auth.example.com/if/flow/default-provider-authorization-implicit-consent/?client_id=dummy_client_id&redirect_uri=http%3A%2F%2Finventree.example.com%2Faccounts%2Fx2%2Flogin%2Fcallback%2F&scope=profile+email+openid&response_type=code&state=dummy_state
200 https://auth.example.com/if/flow/default-provider-authorization-implicit-consent/?client_id=dummy_client_id&redirect_uri=http%3A%2F%2Finventree.example.com%2Faccounts%2Fx2%2Flogin%2Fcallback%2F&scope=profile+email+openid&response_type=code&state=dummy_state 10.0.0.2 normal none none
301 http://inventree.example.com/accounts/x2/login/callback/?code=dummy_code&state=dummy_state 10.0.0.2 server_redirect permanent https://inventree.example.com/accounts/x2/login/callback/?code=dummy_code&state=dummy_state
302 https://inventree.example.com/accounts/x2/login/callback/?code=dummy_code&state=dummy_state 10.0.0.2 server_redirect temporary https://inventree.example.com/
302 https://inventree.example.com/ 10.0.0.2 server_redirect temporary https://inventree.example.com/index/

In the PUI interface it sends me directly from https://inventree.example.com/platform/login to https://inventree.example.com/platform/null

SchrodingersGat commented 4 days ago

In the PUI interface it sends me directly from https://inventree.example.com/platform/login to https://inventree.example.com/platform/null

Do you mean immediately as you click the "login with SSO" button? Does it 302 you to /platform/null/? Any further log traces?

SchrodingersGat commented 4 days ago

Can you share (please redact any sensitive information) what you get at this API endpoint:

https://inventree.example.com/api/auth/providers/

In particular what is the the list of providers: []

Image

Does your provider "x2" exist here - and does it provide a "login" attribute?

SchrodingersGat commented 4 days ago

If the "login" attribute is null - that will not get caught properly by the frontend (currently). It could creep in from here:

Image

matmair commented 4 days ago

@SchrodingersGat I already have a fix locally for OIDC but it breaks Entra ID auth, I should get it working this week

SchrodingersGat commented 4 days ago

@matmair we should make sure that the frontend correctly handles the case where the "login" attribute is not provided. Will your fix include that or should I submit it separately?

GoryMoon commented 4 days ago

Can you share (please redact any sensitive information) what you get at this API endpoint:

https://inventree.example.com/api/auth/providers/

I shared that above at https://github.com/inventree/InvenTree/issues/7972#issuecomment-2470566304 but here it is again:

{

      "sso_enabled": true,
      "sso_registration": true,
      "mfa_required": false,
      "mfa_enabled": true,
      "providers": [
            {
                  "id": "openid_connect",
                  "name": "OpenID Connect",
                  "configured": true,
                  "login": null,
                  "connect": null,
                  "display_name": "X2 Internal"
            }
      ],
      "registration_enabled": false,
      "password_forgotten_enabled": true

}

Do you mean immediately as you click the "login with SSO" button? Does it 302 you to /platform/null/? Any further log traces? It's the path that I'm redirected to once I click the button.

Looking in the "Network" tab when clicking the SSO button it first does a PUT to api/web/ui_preference/ with 200.

Then it does a GET when navigating to /platform/null where it displays the 404 message. Image

In the server logs it's just the above mentioned calls before the assets are loaded.

10.0.0.10 - - [19/Nov/2024:14:11:32 +0100] "PUT /api/web/ui_preference/ HTTP/1.0" 200 54 "https://inventree.example.com/platform/login" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0"
10.0.0.10 - - [19/Nov/2024:14:11:32 +0100] "GET /platform/null HTTP/1.0" 200 639 "https://inventree.example.com/platform/login" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0"

I don't have any OpenTelemetry tracing setup at the moment.

SchrodingersGat commented 4 days ago

@GoryMoon thanks, and sorry that I missed that you had already shared that information.

@matmair if the SSO config works correctly for CUI, any idea why it is reporting a "null" value for the login and connect attributes via the API?

matmair commented 3 days ago

@GoryMoon I have a solution in https://github.com/inventree/InvenTree/pull/8527 that might be interesting; I do not recommend switching production to it as it is in the not-released 0.17.x release series