stormpath / stormpath-django

Django plugin for Stormpath
Apache License 2.0
38 stars 19 forks source link

Support error JWT from ID Site #65

Closed robertjd closed 8 years ago

robertjd commented 8 years ago

ID Site has been modified to return the user to the ID Site Callback with an error JWT, if an error occurs while using ID Site. For example, if the user times out on ID Site (the session expires) we return the user to the ID Site Callback with that error.

This error JWT has a different format from the normal JWT, please see "Error Token" on this page:

https://stormpath.atlassian.net/wiki/display/AM/JWT+Token

This library needs to be modified to return the error. At the moment it is throwing an exception because it is asserting certain claims:

MissingRequiredClaimError at /stormpath-id-site-callback/
Token is missing the "aud" claim
Request Method: GET
Request URL: http://127.0.0.1:8000/stormpath-id-site-callback/?jwtResponse=<the JWT>
Django Version: 1.8.4
Exception Type: MissingRequiredClaimError
Exception Value:
Token is missing the "aud" claim
Exception Location: <path to virtualenv
directory>/lib/python3.4/site-packages/jwt/api_jwt.py in _validate_aud,
line 158
Python Executable: /usr/local/bin/python3.4
Python Version: 3.4.3
Python Path:
['<path to virtualenv directory>',
 '<path to virtualenv directory>',
 '<path to virtualenv directory>/lib',
 '<path to virtualenv directory>/lib/python3.4/site-packages',
 '/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4',
 '/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/plat-darwin',
 '/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/lib-dynload',
 '/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages',
 '/Library/Frameworks/Python.framework/Versions/3.4/lib/python34.zip']
Server time: Sat, 31 Oct 2015 03:42:50 +0000
rdegges commented 8 years ago

This has been merged / released, so once you've updated the underlying stormpath sdk, it'll be good to go =)

DanielStevenLewis commented 8 years ago

Hey guys,

I updated stormpath and stormpath-django with pip3.4 in my local environment. Upon trying to login after five minutes I still get the following error. (Lines 132, 15, and 259 are highlighted).

Error at /stormpath-id-site-callback/ The session on ID Site has timed out. This can occur if the user stays on ID Site without logging in, registering, or resetting a password. Request Method: GET Request URL: http://127.0.0.1:8000/stormpath-id-site-callback/?jwtResponse= Django Version: 1.8.6 Exception Type: Error Exception Value: The session on ID Site has timed out. This can occur if the user stays on ID Site without logging in, registering, or resetting a password. Exception Location: /path/to/virtualenv/lib/python3.4/site-packages/stormpath/resources/application.py in handle_id_site_callback, line 259 Python Executable: /path/to/virtualenv/bin/python3.4 Python Version: 3.4.3 Python Path: ['/path/to/virtualenv', '/path/to/virtualenv/lib/python34.zip', '/path/to/virtualenv/lib/python3.4', '/path/to/virtualenv/lib/python3.4/plat-darwin', '/path/to/virtualenv/lib/python3.4/lib-dynload', '/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4', '/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/plat-darwin', '/path/to/virtualenv/lib/python3.4/site-packages'] Server time: Mon, 16 Nov 2015 16:56:06 +0000 Traceback Switch to copy-and-paste view /path/to/virtualenv/lib/python3.4/site-packages/django/core/handlers/base.py in get_response

  1. response = middleware_method(request, callback, callback_args, callback_kwargs)
  2. if response:
  3. break
  4. if response is None:
  5. wrapped_callback = self.make_view_atomic(callback)
  6. try:
  7. response = wrapped_callback(request, _callback_args, *_callback_kwargs) ...

  8. except Exception as e:
  9. If the view raised an exception, run it through exception

  10. middleware, and if the exception middleware returns a

  11. response, use that. Otherwise, reraise the exception.

  12. for middleware_method in self._exception_middleware:
  13. response = middleware_method(request, e) 
▶ Local vars
 /path/to/virtualenv/lib/python3.4/site-packages/django_stormpath/views.py in stormpath_id_site_callback
  14. from .models import APPLICATION
  15. from .id_site import handle_id_site_callback
  16. from .social import get_authorization_url, handle_social_callback
  17. def stormpath_id_site_callback(request):
  18. ret = APPLICATION.handle_id_site_callback(
  19. request.build_absolute_uri()) ...

  20. return handle_id_site_callback(request, ret)
  21. def stormpath_id_site_login(request):
  22. rdr = APPLICATION.build_id_site_redirect_url(
  23. callback_uri=settings.STORMPATH_ID_SITE_CALLBACK_URI, 
▶ Local vars
 /path/to/virtualenv/lib/python3.4/site-packages/stormpath/resources/application.py in handle_id_site_callback
  24. if missing_claim_error.claim != 'aud':
  25. return None
  26. decoded_data = jwt.decode(
  27. jwt_response, api_key_secret, algorithms=['HS256'])
  28. if 'err' in decoded_data:
  29. raise StormpathError(decoded_data.get('err')) ...

  30. else:
  31. raise missing_claim_error
  32. nonce = Nonce(decoded_data['irt'])
  33. check if nonce is in cache already

    
▶ Local vars


    /path/to/virtualenv

rdegges commented 8 years ago

@avojnovicDk can you take a look at this? This should be fixed now.

avojnovicDk commented 8 years ago

This works exactly as I expected - it throws stormpath.error.Error with message from the err claim in the error JWT. Should this behave differently?

rdegges commented 8 years ago

Ping @DanielStevenLewis. Looks like this is the expected functionality -- we are throwing a Stormpath Error object with the appropriate message here.

DanielStevenLewis commented 8 years ago

@rdegges @avojnovicDk

To quote Robert, "With this change, if the page has a timeout error we will send the user back to your site with the error message. Your server can then decide what to do, we assume you'll want to just redirect the user back to ID Site with a new session."

How are we supposed to redirect the user back to the ID site with a new session? The error seems to only be bubbling up to the stormpath app and django-stormpath app (not to my company's app) so I don't even know where to start implementing that behaviour.

Thanks

avojnovicDk commented 8 years ago

@DanielStevenLewis, you're right - it is not clear where to start with handling error JWT. I've made a simple example in django sample app: https://github.com/stormpath/stormpath-django-sample/commit/a0bdc66e194e9f2ac6eef03c44dc95e9991435f9 , so you can take a look.

DanielStevenLewis commented 8 years ago

Thanks @avojnovicDk , we got this working locally. I also figured out how to do it by writing middleware before you responded but this is definitely a cleaner solution.

Cheers