def _get_token_info(self, token):
        start_time = time.time()
        # We hard code to use client_secret_post, because that's what the Google
        # oauth2client library defaults to
        request = {'token': token}
        headers = {'Content-type': 'application/x-www-form-urlencoded'}

        hint = current_app.config['OIDC_TOKEN_TYPE_HINT']
        if hint != 'none':
            request['token_type_hint'] = hint

        auth_method = current_app.config['OIDC_INTROSPECTION_AUTH_METHOD']
        if auth_method == 'client_secret_basic':
            basic_auth_string = '%s:%s' % (
                self.client_secrets['client_id'],
                self.client_secrets['client_secret'])
            basic_auth_bytes = bytearray(basic_auth_string, 'utf-8')
            headers['Authorization'] = 'Basic %s' % b64encode(basic_auth_bytes)
        elif auth_method == 'bearer':
            headers['Authorization'] = 'Bearer %s' % token
        elif auth_method == 'client_secret_post':
            request['client_id'] = self.client_secrets['client_id']
            request['client_secret'] = self.client_secrets['client_secret']

        # Use separate certs to get around python 3.4 cert issues
        resp, content = httplib2.Http(ca_certs=certifi.where()) \
            .request(self.client_secrets['token_introspection_uri'], 'POST', urlencode(request), headers=headers)

        total_time = time.time() - start_time

        if total_time > 1:
            print("Sending request to OIDC server in %.3fs" % total_time)

        return _json_loads(content)
Пример #2
0
    def _get_token_info(self, token):
        # We hardcode to use client_secret_post, because that's what the Google
        # oauth2client library defaults to
        request = {'token': token}
        headers = {'Content-type': 'application/x-www-form-urlencoded'}

        hint = current_app.config['OIDC_TOKEN_TYPE_HINT']
        if hint != 'none':
            request['token_type_hint'] = hint

        auth_method = current_app.config['OIDC_INTROSPECTION_AUTH_METHOD']
        if (auth_method == 'client_secret_basic'):
            basic_auth_string = '%s:%s' % (
                self.client_secrets['client_id'],
                self.client_secrets['client_secret'])
            basic_auth_bytes = bytearray(basic_auth_string, 'utf-8')
            headers['Authorization'] = 'Basic %s' % b64encode(basic_auth_bytes)
        elif (auth_method == 'bearer'):
            headers['Authorization'] = 'Bearer %s' % token
        elif (auth_method == 'client_secret_post'):
            request['client_id'] = self.client_secrets['client_id']
            request['client_secret'] = self.client_secrets['client_secret']

        # as of Python 3.4 disable_ssl_certificate_validation defaults to False,
        # this causes wildcard certs to throw errors,
        # and we use wildcards on our KeyCloak server, which throws errors for token verification calls
        # TODO: (Remove this whole patch) - This line of code is a temporary workaround for wildcard cert errors
        resp, content = httplib2.Http(
            disable_ssl_certificate_validation=True).request(
                self.client_secrets['token_introspection_uri'],
                'POST',
                urlencode(request),
                headers=headers)
        # TODO: Cache this reply
        return _json_loads(content)
Пример #3
0
def register_client(provider_info, redirect_uris):
    """
    This function registers a new client with the specified OpenID Provider,
    and then returns the regitered client ID and other information.

    :param provider_info: The contents of the discovery endpoint as
        specified by the OpenID Connect Discovery 1.0 specifications.
    :type provider_info: dict
    :param redirect_uris: The redirect URIs the application wants to
        register.
    :type redirect_uris: list
    :returns: An object containing the information needed to configure the
        actual client code to communicate with the OpenID Provider.
    :rtype: dict
    :raises ValueError: The same error as used by check_redirect_uris.
    :raises RegistrationError: Indicates an error was returned by the OpenID
        Provider during registration.

    .. versionadded:: 1.0
    """
    client_type = check_redirect_uris(redirect_uris)

    submit_info = {
        'redirect_uris': redirect_uris,
        'application_type': client_type,
        'token_endpoint_auth_method': 'client_secret_post'
    }

    headers = {'Content-type': 'application/json'}

    resp, content = httplib2.Http().request(
        provider_info['registration_endpoint'],
        'POST',
        json.dumps(submit_info),
        headers=headers)

    if int(resp['status']) >= 400:
        raise Exception('Error: the server returned HTTP ' + resp['status'])

    client_info = _json_loads(content)

    if 'error' in client_info:
        raise Exception(
            'Error occured during registration: %s (%s)' %
            (client_info['error'], client_info.get('error_description')))

    json_file = {
        'web': {
            'client_id': client_info['client_id'],
            'client_secret': client_info['client_secret'],
            'auth_uri': provider_info['authorization_endpoint'],
            'token_uri': provider_info['token_endpoint'],
            'userinfo_uri': provider_info['userinfo_endpoint'],
            'redirect_uris': redirect_uris,
            'issuer': provider_info['issuer'],
        }
    }

    return json_file
Пример #4
0
def discover_OP_information(OP_uri):
    """
    Discovers information about the provided OpenID Provider.

    :param OP_uri: The base URI of the Provider information is requested for.
    :type OP_uri: str
    :returns: The contents of the Provider metadata document.
    :rtype: dict

    .. versionadded:: 1.0
    """
    _, content = httplib2.Http().request(
        '%s/.well-known/openid-configuration' % OP_uri)
    return _json_loads(content)
Пример #5
0
    def _get_token_info(self, token):
        # TODO: This should be fixed in the main flask-oidc repo instead.
        # TODO: But since it is not being maintained anymore, we did it here.
        # We hardcode to use client_secret_post, because that's what the Google
        # oauth2client library defaults to
        request = {'token': token}
        headers = {'Content-type': 'application/x-www-form-urlencoded'}

        hint = current_app.config['OIDC_TOKEN_TYPE_HINT']
        if hint != 'none':
            request['token_type_hint'] = hint
            request[hint] = token

        auth_method = current_app.config['OIDC_INTROSPECTION_AUTH_METHOD']
        if auth_method == 'client_secret_basic':
            basic_auth_string = '%s:%s' % (
                self.client_secrets['client_id'],
                self.client_secrets['client_secret'])
            basic_auth_bytes = bytearray(basic_auth_string, 'utf-8')
            headers['Authorization'] = 'Basic %s' % b64encode(basic_auth_bytes)
        elif auth_method == 'bearer':
            headers['Authorization'] = 'Bearer %s' % token
        elif auth_method == 'client_secret_post':
            request['client_id'] = self.client_secrets['client_id']
            request['client_secret'] = self.client_secrets['client_secret']

        resp, content = httplib2.Http().request(
            self.client_secrets['token_introspection_uri'],
            'POST',
            urlencode(request),
            headers=headers)
        # TODO: Cache this reply
        token_info = _json_loads(content)
        if not token_info.get("active"):
            if token_info.get("expires_in") and int(
                    token_info.get("expires_in")) > 1:
                token_info["active"] = True

        return token_info