Closed tarzzz closed 7 years ago
Big -1 on wildcard support. However, the redirect uri validation should be exposed to the library users so that it can be overridden. I don't know if that's the case yet.
the redirect uri validation should be exposed to the library users so that it can be overridden
This should also serve our purpose. Ideas on how we can implement it would be great..
@tarzzz i don't know off the top of my head. If you have a suggestion I'm willing to review it.
We have figured out a work-around for this for our application. I am going to close this issue, but can be opened if someone needs it..
Thanks @jleclanche anyways.. 😃
@tarzzz can you share the workaround, for the poor lad who's gonna end up in this issue off google a year from now? :)
@jleclanche: There wasn't a work around (pardon my language in my earlier comment). We simply decided to use another approach, which did not require wildcards/subdomains at all.
Alright, excellent. I don't think it's a particularly good idea to use wildcard redirect uris.
Actually, I've found an use-case where it might get useful. I'm trying to integrate OAuth2 based SSO login to a Plone application (don't even ask how I got into it:<).
Plone allows you to have multiple "Sites". They are located in different paths, for example:
Etc. Now for each site, I have to add another redirect URI. It would be helpful if I could just do:
http://example.com/*/acl_users/oauth2
Or even better, with some kind of a regular expression:
http://example.com/(A-Za-z0-9+)/acl_users/oauth2
I agree with @samupl and I'm also trying to do something like this.
You can subclass AbstractApplication to achieve this, e.g.:
# Standard Library
import re
from urllib.parse import parse_qsl
from urllib.parse import urlparse
# Django
from django.core.exceptions import ValidationError
# 3rd-party
from oauth2_provider.models import AbstractApplication
from oauth2_provider.settings import oauth2_settings
def validate_uris(value):
"""Ensure that `value` contains valid blank-separated URIs."""
urls = value.split()
for url in urls:
obj = urlparse(url)
if obj.fragment:
raise ValidationError('Redirect URIs must not contain fragments')
if obj.scheme.lower() not in oauth2_settings.ALLOWED_REDIRECT_URI_SCHEMES:
raise ValidationError('Redirect URI scheme is not allowed.')
if not obj.netloc:
raise ValidationError('Redirect URI must contain a domain.')
class Application(AbstractApplication):
"""Subclass of application to allow for regular expressions for the redirect uri."""
@staticmethod
def _uri_is_allowed(allowed_uri, uri):
"""Check that the URI conforms to these rules."""
schemes_match = allowed_uri.scheme == uri.scheme
netloc_matches_pattern = re.fullmatch(allowed_uri.netloc, uri.netloc)
paths_match = allowed_uri.path == uri.path
return all([schemes_match, netloc_matches_pattern, paths_match])
def __init__(self, *args, **kwargs):
"""Relax the validator to allow for uris with regular expressions."""
self._meta.get_field('redirect_uris').validators = [validate_uris, ]
super(). __init__(*args, **kwargs)
def redirect_uri_allowed(self, uri):
"""
Check if given url is one of the items in :attr:`redirect_uris` string.
A Redirect uri domain may be a regular expression e.g. `^(.*).example.com$` will
match all subdomains of example.com.
A Redirect uri may be `https://(.*).example.com/some/path/?q=x`
:param uri: Url to check
"""
for allowed_uri in self.redirect_uris.split():
parsed_allowed_uri = urlparse(allowed_uri)
parsed_uri = urlparse(uri)
if self._uri_is_allowed(parsed_allowed_uri, parsed_uri):
aqs_set = set(parse_qsl(parsed_allowed_uri.query))
uqs_set = set(parse_qsl(parsed_uri.query))
if aqs_set.issubset(uqs_set):
return True
return False
Supporting to RFC-8252 "OAuth2 for Native Apps" using PKCE would be a major upgrade to Django OAuth Toolkit. I think @whytheplatypus and @ekivemark may have also explored solutions/workarounds.
The example on https://github.com/jazzband/django-oauth-toolkit/issues/443#issuecomment-420255286 doesn't work (for domains) since validation has been moved to clean()
on https://github.com/jazzband/django-oauth-toolkit/commit/96538876d0d7ea0319ba5286f9bde842a906e1c5, and clean()
is not ideal to override as it also validates other fields
I am not sure if this is already supported (since I could not find it in docs).
Application's Redirect URIs should accept wildcard URIs (for sub-domains), and OAuth2 Validator should be able to validate the redirect_uri received in request against the redirect_uris entry in Application.
We should be able to add:
and this should be able to accept 'A.my-domain.com' in request's redirect_uri parameter.
I would be happy to make PR for this, if necessary.