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)
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)
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
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)
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