Example #1
0
    def validate_userinfo_request(self, request):
        """Ensure the request is valid.

        5.3.1.  UserInfo Request
        The Client sends the UserInfo Request using either HTTP GET or HTTP
        POST. The Access Token obtained from an OpenID Connect Authentication
        Request MUST be sent as a Bearer Token, per Section 2 of OAuth 2.0
        Bearer Token Usage [RFC6750].

        It is RECOMMENDED that the request use the HTTP GET method and the
        Access Token be sent using the Authorization header field.

        The following is a non-normative example of a UserInfo Request:

        GET /userinfo HTTP/1.1
        Host: server.example.com
        Authorization: Bearer SlAV32hkKG

        5.3.3. UserInfo Error Response
        When an error condition occurs, the UserInfo Endpoint returns an Error
        Response as defined in Section 3 of OAuth 2.0 Bearer Token Usage
        [RFC6750]. (HTTP errors unrelated to RFC 6750 are returned to the User
        Agent using the appropriate HTTP status code.)

        The following is a non-normative example of a UserInfo Error Response:

        HTTP/1.1 401 Unauthorized
        WWW-Authenticate: Bearer error="invalid_token",
                error_description="The Access Token expired"
        """
        if not self.bearer.validate_request(request):
            raise errors.InvalidTokenError()
        if "openid" not in request.scopes:
            raise errors.InsufficientScopeError()
Example #2
0
    def validate_token_request(self, request):
        # This method's code is based on the parent method's code
        # We removed the original comments to replace with ours
        # explaining our modifications.

        # We need to set these at None by default otherwise
        # we are going to get some AttributeError later
        request._params.setdefault("backend", None)
        request._params.setdefault("client_secret", None)

        if request.grant_type != 'convert_token':
            raise errors.UnsupportedGrantTypeError(request=request)

        # We check that a token parameter is present.
        # It should contain the social token to be used with the backend
        if request.token is None:
            raise errors.InvalidRequestError(
                description='Missing token parameter.',
                request=request)

        # We check that a backend parameter is present.
        # It should contain the name of the social backend to be used
        if request.backend is None:
            raise errors.InvalidRequestError(
                description='Missing backend parameter.',
                request=request)

        if not request.client_id:
            raise errors.MissingClientIdError(request=request)

        if not self.request_validator.validate_client_id(request.client_id, request):
            raise errors.InvalidClientIdError(request=request)

        # Existing code to retrieve the application instance from the client id
        if self.request_validator.client_authentication_required(request):
            log.debug('Authenticating client, %r.', request)
            if not self.request_validator.authenticate_client(request):
                log.debug('Invalid client (%r), denying access.', request)
                raise errors.InvalidClientError(request=request)
        elif not self.request_validator.authenticate_client_id(request.client_id, request):
            log.debug('Client authentication failed, %r.', request)
            raise errors.InvalidClientError(request=request)

        # Ensure client is authorized use of this grant type
        # We chose refresh_token as a grant_type
        # as we don't want to modify all the codebase.
        # It is also the most permissive and logical grant for our needs.
        request.grant_type = "refresh_token"
        self.validate_grant_type(request)

        self.validate_scopes(request)

        # TODO: Find a better way to pass the django request object
        strategy = load_strategy(request=request.django_request)

        try:
            backend = load_backend(strategy, request.backend,
                                   reverse("%s:%s:complete" % (DRFSO2_URL_NAMESPACE, NAMESPACE) , args=(request.backend,)))
        except MissingBackend:
            raise errors.InvalidRequestError(
                description='Invalid backend parameter.',
                request=request)

        try:
            user = backend.do_auth(access_token=request.token)
            user_data = backend.user_data(access_token=request.token)
            exp = user_data['exp']
            if not exp and exp <= datetime.now():
               raise errors.InvalidTokenError('Token has expired', request=request)

        except requests.HTTPError as e:
            raise errors.InvalidRequestError(
                description="Backend responded with HTTP{0}: {1}.".format(e.response.status_code,
                                                                          e.response.text),
                request=request)
        except SocialAuthBaseException as e:
            raise errors.AccessDeniedError(description=str(e), request=request)

        if not user:
            raise errors.InvalidGrantError('Invalid credentials given.', request=request)

        if not user.is_active:
            raise errors.InvalidGrantError('User inactive or deleted.', request=request)
        
        request.user = user
        log.debug('Authorizing access to user %r.', request.user)