AngellusMortis / django_microsoft_auth

Simple app to enable Microsoft Account, Office 365 and Xbox Live authentcation as a Django authentcation backend.
MIT License
137 stars 84 forks source link

Matching the redirect uri to the site name #270

Open oi-eddyoj opened 5 years ago

oi-eddyoj commented 5 years ago

Hi,

My django app works perfectly when I'm running this in localhost within a Docker container. However, I have pushed this same app to Azure and have matched the redirect uri in the app registration portal in the form:

https://my-app.azurewebsites.net/microsoft/auth-callback/

with the site domain name in Django Admin as:

azurewebsites.net

I get a redirect uri error when logging in. The rest of the app works fine, its just the login part.

Have you any troublshooting guidelines for this? The app is running in a Linux Docker container, so is probably behind a reverse proxy. This is a very typical setup so I'm not sure if this is the issue or not.

Have you deployed to Azure before with this functionality?

I am aware of Microsofts Authentication wrapper in Azure but its not as desirable as using your package.

barun511 commented 5 years ago

Have you tried using the site domain name as my-app.azurewebsite.net/ ?

oi-eddyoj commented 5 years ago

I did. I tried all sorts of variants. Not sure I put the '/' at the end though. I suspect it was my error somewhere along the way but also felt it could have been a function of my app running within a Docker container i.e. potentially running as localhost within it and then having its requests passed through Azure. Can this effect the callback uri?

I ended up using Microsofts own Authentication service within Azure, which handles authentication elegantly and simply passes the user name in the request header to the Django app. each consecutive request is then passed through Microsoft which is handy from a security perspective. However, it reduces the flexibility in cloud service provider so I will probably try this package out again later at some point.

barun511 commented 5 years ago

I'm not 100% sure - but ideally this should not. I'm also not fully certain about what the issue might be.

Glad to hear you got it resolved though!

jgoodleaf commented 4 years ago

I'm having a similar problem. In my case, however, I'm running the application as a docker-compose stack. So I have in the container stack:

The stack is, itself, proxied by Nginx on the docker host. So I think what's happening for me is that the redirect URI in Azure is, of course, HTTPS, but the redirect that django-microsoft-auth generates is HTTP.

e.g. https://login.microsoftonline.com/<string>/oauth2/v2.0/authorize?response_type=code&client_id=<client id>&redirect_uri=http%3A%2F%2F<fully-qualified domain name>%2Fmicrosoft%2Fauth-callback%2F&scope=openid+email+profile&state=<some number>&response_mode=form_post

So the internal nginx is not getting the protocol scheme from the host's nginx. (I think.)

Is there a way to ensure that this app always produces a HTTPS redirect? (Or is my problem elsewhere?)

pd242 commented 4 years ago

@jgoodleaf I am having the same exact issue. I am working on it and will update if i find a fix.

jgoodleaf commented 4 years ago

@pd242 is your DEBUG set to True? I had mine on because I am, in a sense, developing (i.e. trying to make this auth system work; it's new to me). But it looks like the code defaults to https unless DEBUG is enabled.

I flipped off DEBUG and it still doesn't work, but the error is different! (I'm trying to run down that problem now.)

jgoodleaf commented 4 years ago

I'm hitting an internal server error now, which appears to be related to Scope change warnings. But since I'm using v2.3.1 of this app, I'd thought not to see this.

ERROR:django.request:Internal Server Error: /microsoft/auth-callback/ Traceback (most recent call last): File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner response = get_response(request) File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 115, in _get_response response = self.process_exception_by_middleware(e, request) File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 113, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/usr/local/lib/python3.7/site-packages/django/views/generic/base.py", line 71, in view return self.dispatch(request, *args, **kwargs) File "/usr/local/lib/python3.7/site-packages/django/utils/decorators.py", line 45, in _wrapper return bound_method(*args, **kwargs) File "/usr/local/lib/python3.7/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view return view_func(*args, **kwargs) File "/usr/local/lib/python3.7/site-packages/microsoft_auth/views.py", line 47, in dispatch return super().dispatch(request, *args, **kwargs) File "/usr/local/lib/python3.7/site-packages/django/views/generic/base.py", line 97, in dispatch return handler(request, *args, **kwargs) File "/usr/local/lib/python3.7/site-packages/microsoft_auth/views.py", line 145, in post context = self.get_context_data(**request.POST.dict()) File "/usr/local/lib/python3.7/site-packages/microsoft_auth/views.py", line 68, in get_context_data self._authenticate(kwargs.get("code")) File "/usr/local/lib/python3.7/site-packages/microsoft_auth/views.py", line 129, in _authenticate user = authenticate(self.request, code=code) File "/usr/local/lib/python3.7/site-packages/django/contrib/auth/__init__.py", line 73, in authenticate user = backend.authenticate(request, **credentials) File "/usr/local/lib/python3.7/site-packages/microsoft_auth/backends.py", line 43, in authenticate token = self.microsoft.fetch_token(code=code) File "/usr/local/lib/python3.7/site-packages/microsoft_auth/client.py", line 172, in fetch_token **kwargs File "/usr/local/lib/python3.7/site-packages/requests_oauthlib/oauth2_session.py", line 360, in fetch_token self._client.parse_request_body_response(r.text, scope=self.scope) File "/usr/local/lib/python3.7/site-packages/oauthlib/oauth2/rfc6749/clients/base.py", line 421, in parse_request_body_response self.token = parse_token_response(body, scope=scope) File "/usr/local/lib/python3.7/site-packages/oauthlib/oauth2/rfc6749/parameters.py", line 431, in parse_token_response validate_token_parameters(params) File "/usr/local/lib/python3.7/site-packages/oauthlib/oauth2/rfc6749/parameters.py", line 461, in validate_token_parameters raise w Warning: Scope has changed from "openid email profile" to "profile openid email User.Read".

pd242 commented 4 years ago

That was it! Just rebuilt on my test server with debug off and it worked.

As for your second issue - from the docs

Sliencing Scope has changed warnings If you stay on 1.3.x for a bit and you start getting Scope has changed from “User.Read” to “User.Read email profile openid”., you can slience this warning by setting an env variable for OAUTHLIB_RELAX_TOKEN_SCOPE before starting Django.

Bash

bash $ export OAUTHLIB_RELAX_TOKEN_SCOPE=true $ python manage.py runserver

PowerShell

powershell > $env:OAUTHLIB_RELAX_TOKEN_SCOPE=$TRUE > python manage.py runserver

You should however upgrade to 2.0 once you can.

Not sure why you're getting that error on 2.3.1 though...

jgoodleaf commented 4 years ago

Yeah, I found that in the docs and to be clear, it DOES work. I added that to the variables passed in through docker-compose and it's all working smoothly now.

I'm not certain why the error appeared as it does seem to be documented as specific to < 2. But I also don't plan to debug this! It's working and I'm not going to look back. If I had to take a guess, I would guess that it's related to our core IT group's hybrid monstrosity of cloud + on premise AD and how accounts are set up...

Marijus commented 4 years ago

I'm getting the same Warning on 2.3.1 with Azure AD. Using env variable works but I would love a solution without adding an environment variable. Any ideas?