inventree / InvenTree

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

openid_connect Redirect URL #6280

Closed K-J-VV closed 9 months ago

K-J-VV commented 9 months ago

Please verify that this bug has NOT been raised before.

Describe the bug*

I have followed the SSO guide and have everything setup correctly, but the problem appears to be what URL inventree is redirecting to

Specifically, it is redirecting to the HTTP address rather than the HTTPS address

http://inventree.example.com/accounts/providerid/login/callback/

I see in the guide it states "If your InvenTree server is running behind a proxy, you will need to ensure that the "public facing" host address matches the internal host address of the server, and that this host address also matches the configured callback URL"

I may be missing something, but I can't seem to update the internal Inventree address to HTTPS. I'm able to setup the NGINX container to use HTTPS rather than HTTP, but the redirect still defaults to Inventree's HTTP

Steps to Reproduce

n/a

Expected behaviour

n/a

Deployment Method

Version Information

latest

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

Relevant log output

No response

matmair commented 9 months ago

Please fill out the full template (especially steps to reproduce, deployment method and version information), the provided information is not enough to reproduce anything

K-J-VV commented 9 months ago

Please fill out the full template (especially steps to reproduce, deployment method and version information), the provided information is not enough to reproduce anything

Sorry, to clarify:

Issue: When attempting to login via SSO, InvenTree is sending the SSO provider to the following address:

I believe the problem I am encountering is regarding "Proxy Support"

The InvenTree SSO guide mentions "Proxy Support: If your InvenTree server is running behind a proxy, you will need to ensure that the "public facing" host address matches the internal host address of the server, and that this host address also matches the configured callback URL"

I believe the InvenTree-server container has an internal host address of: HTTP://exampleip:8000 and I need to figure out how to tell InvenTree-server that it's internal host address is HTTPS://exampleip:8000

matmair commented 9 months ago

Please check your Base URL - https://docs.inventree.org/en/stable/settings/global/?h=settings#server-settings

K-J-VV commented 9 months ago

Please check your Base URL - https://docs.inventree.org/en/stable/settings/global/?h=settings#server-settings

I do have the following environment variable set up: INVENTREE_BASE_URL=https://inventree.example.com

And it still believes the host URL is http://inventree.example.com

I have repeated the setup with a fresh container/install and still have the same outcome

SchrodingersGat commented 9 months ago

What provider are you using? Are you sure that you have correctly set the callback URL there?

Also, can you confirm if your proxy setup is correctly redirecting any http requests to https?

K-J-VV commented 9 months ago

What provider are you using? Are you sure that you have correctly set the callback URL there?

Also, can you confirm if your proxy setup is correctly redirecting any http requests to https?

I have two setups: Authentik & Zitadel; the issue is occurring with both

My reverse proxy (NPM) is directing requests to https://inventree.example.com --> http://InternalnventreeNginxIP:80 (with NPM enforcing SSL)

The callback URL I have set is: https://inventree.example.com/accounts/providerid/login/callback/

Interestingly, if I change the callback URL to: http://inventree.example.com/accounts/providerid/login/callback/ then the redirect DOES work BUT the login fails (i.e., when I click the SSO button I'm redirected to auth provider login page)

But after successful login with auth provider, I am directed to: https://inventree.example.com/accounts/providerid/login/callback/?code=RandomString The page I see is 'Internal Server Error' from Inventree.

The error log in Inventree shows:

Type = MultipleObjectsReturned

Path = http://inventree.example.com/accounts/providerid/login/callback/?code=RandomString

data = Traceback (most recent call last):

File "/root/.local/lib/python3.10/site-packages/django/core/handlers/base.py", line 181, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/root/.local/lib/python3.10/site-packages/allauth/socialaccount/providers/openid_connect/views.py", line 74, in callback return view(request)

File "/root/.local/lib/python3.10/site-packages/allauth/socialaccount/providers/oauth2/views.py", line 84, in view return self.dispatch(request, *args, **kwargs)

File "/root/.local/lib/python3.10/site-packages/allauth/socialaccount/providers/oauth2/views.py", line 162, in dispatch return complete_social_login(request, login)

File "/root/.local/lib/python3.10/site-packages/allauth/socialaccount/helpers.py", line 208, in complete_social_login sociallogin.lookup()

File "/root/.local/lib/python3.10/site-packages/allauth/socialaccount/models.py", line 282, in lookup provider_id = self.account.get_provider().id

File "/root/.local/lib/python3.10/site-packages/allauth/socialaccount/models.py", line 141, in get_provider provider = self._provider = adapter.get_provider(

File "/root/.local/lib/python3.10/site-packages/allauth/socialaccount/adapter.py", line 205, in get_provider app = self.get_app(request, provider=provider)

File "/root/.local/lib/python3.10/site-packages/allauth/socialaccount/adapter.py", line 290, in get_app raise MultipleObjectsReturned

django.core.exceptions.MultipleObjectsReturned

SchrodingersGat commented 9 months ago

Do you have multiple SSO apps called "provider"?

K-J-VV commented 9 months ago

Do you have multiple SSO apps called "provider"?

not a single one, all SSO apps are uniquely named (e.g., Inventree, Memos, Notes, etc.)

K-J-VV commented 9 months ago

I'm most confused why the redirect URL is only working when switched to HTTP rather than HTTPS

If the way to access Inventree and Base URL are both at https://inventree.example.com then I'd think that should be the correct redirect for a successful login? But for some reason it seems Inventree continues to think it's Base URL is the http address instead

which maybe is why login fails? since the error log shows the login path as http://Inventree.example.com but there is technically no address identified by that (Inventree server only has 2x known addresses, it's internal IP @ 192.x.x.x and external @ https that is proxied past NGINX)

SchrodingersGat commented 9 months ago

Try setting this value to https

https://github.com/inventree/InvenTree/blob/4f8dddc5976a5b11fbfb89c7e41ac5ceddf156cf/InvenTree/InvenTree/settings.py#L1006

Possible that this is an upstream bug:

https://github.com/pennersr/django-allauth/issues/579

K-J-VV commented 9 months ago

ACCOUNT_DEFAULT_HTTP_PROTOCOL =

Do you mean as an .env variable for the docker container, like the base url? as in:

INVENTREE_BASE_URL=https://inventree.example.com ACCOUNT_DEFAULT_HTTP_PROTOCOL=https

SchrodingersGat commented 9 months ago

You'll have to set the env var

INVENTREE_LOGIN_DEFAULT_HTTP_PROTOCOL=https

K-J-VV commented 9 months ago

Thank you, seems like progress! But still results in login error for me :/

With that environment variable set the HTTPS callback url does now work. (i.e., now the only callback URL I have set is: https://inventree.example.com/accounts/providerid/login/callback/ )

However, after successful login with the auth provider it results with the same Inventree internal server error as before. The following is error log within Inventree. One thing to note about the error log, it still states the path as HTTP and not HTTPS (i'm not sure if that's part of issue, but noticed it and I would assume it to be HTTPS now that the redirect URL is sending to HTTPS address?)

Type: MultipleObjectsReturned

Path: http://inventree.example.com/accounts/providerid/login/callback/?code=RandomString

Data: Traceback (most recent call last):

File "/root/.local/lib/python3.10/site-packages/django/core/handlers/base.py", line 181, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/root/.local/lib/python3.10/site-packages/allauth/socialaccount/providers/openid_connect/views.py", line 74, in callback return view(request)

File "/root/.local/lib/python3.10/site-packages/allauth/socialaccount/providers/oauth2/views.py", line 84, in view return self.dispatch(request, *args, **kwargs)

File "/root/.local/lib/python3.10/site-packages/allauth/socialaccount/providers/oauth2/views.py", line 162, in dispatch return complete_social_login(request, login)

File "/root/.local/lib/python3.10/site-packages/allauth/socialaccount/helpers.py", line 208, in complete_social_login sociallogin.lookup()

File "/root/.local/lib/python3.10/site-packages/allauth/socialaccount/models.py", line 282, in lookup provider_id = self.account.get_provider().id

File "/root/.local/lib/python3.10/site-packages/allauth/socialaccount/models.py", line 141, in get_provider provider = self._provider = adapter.get_provider(

File "/root/.local/lib/python3.10/site-packages/allauth/socialaccount/adapter.py", line 205, in get_provider app = self.get_app(request, provider=provider)

File "/root/.local/lib/python3.10/site-packages/allauth/socialaccount/adapter.py", line 290, in get_app raise MultipleObjectsReturned

django.core.exceptions.MultipleObjectsReturned

SchrodingersGat commented 9 months ago

Ok, this looks like a known bug the the current version of allauth we use:

https://github.com/pennersr/django-allauth/issues/3564

Is there anything in the linked issue which you can use to test on your end?

K-J-VV commented 9 months ago

@SchrodingersGat this comment looks like its worth a try https://github.com/pennersr/django-allauth/issues/3564#issuecomment-1854742630

My understanding is he's recommending editing: 'provider_id = self.account.get_provider().id'

to: 'provider_id = self.account.get_provider(request).id'

But I'm not entirely sure where to find that line of code within the inventree docker instance

K-J-VV commented 9 months ago

Actually, it looks like they were able to fix the exact problem I'm having, I'm just not sure how/what I'd need to do within the container I have running:

https://github.com/pennersr/django-allauth/commit/f356138d8903d55755a5157e2992d5b40ba93205

https://github.com/pennersr/django-allauth/issues/3564#issuecomment-1873460028

SchrodingersGat commented 9 months ago

Ok, so looks like the latest version of django-allauth has fixed this, potentially. Can you check on your end? There are two ways you can test.

As the required python libraries are installed "inside" the docker image, we need to get a little creative with testing:

Option 1

With your docker instance already running, run the following command (from outside the docker instance, but in the directory where your docker-compose file is located):

docker compose exec inventree-server pip install -U django-allauth==0.6.1

This should update the django-allauth package within the running container. Then, you can run the same procedure as before, and see if you get another failure or success.

If option 1 fails to install the right version:

Option 2

You can add the following line to your plugins.txt file (in the external volume):

django-allauth==0.6.1

This will run the pip install process when the container starts. Thus ensuring that you'll have a "fresh" version of django-allauth in any running container instance. Then, you can try again


Hopefully one of the approaches above at least lets us confirm if updating django-allauth to the latest version will address the issue for your use case.

K-J-VV commented 9 months ago

@SchrodingersGat ah-may-zing, all working!! Thank you so much for all the help!!

I used Option 2 django-allauth==0.60.1

I had to change my callback URL to: https://inventree.example.com/accounts/oidc/providerid/login/callback/

SchrodingersGat commented 9 months ago

@K-J-VV fantastic! Thanks for reporting back. I'll update the package version and push out an update.

If you are using InvenTree to support commercial operations, please consider a donation to the project so we can continue to provide quick support to issues like this!