def __init__(self, client_id=None, ca_certs=None, client_prefs=None, client_authn_methods=None, keyjar=None, verify_ssl=True, behaviour=None): umaClient.__init__(self, client_id, ca_certs, client_prefs, client_authn_methods, keyjar, verify_ssl=verify_ssl) if behaviour: self.behaviour = behaviour self.access_token_response = {}
def __init__( self, name, sdb, cdb, authn_broker, authz, client_authn, symkey, urlmap=None, as_keyjar=None, as_configuration=None, base_url="", client_authn_methods=None, authn_at_registration="", client_info_url="", secret_lifetime=86400, # client conf below client_id=None, ca_certs=None, client_authn_method=None, c_keyjar=None, server_info=None, authz_page="", flow_type="", password=None, registration_info=None, response_type="", scope="", acr="", resource_srv=""): self.authzsrv = OAuth2UmaAS( name, sdb, cdb, authn_broker, authz, client_authn, symkey, urlmap, as_keyjar, configuration=as_configuration, base_url=base_url, client_authn_methods=client_authn_methods, authn_at_registration=authn_at_registration, client_info_url=client_info_url, secret_lifetime=secret_lifetime) self.client = Client(client_id, ca_certs, client_authn_method, c_keyjar, server_info, authz_page, flow_type, password, registration_info, response_type, scope) self.client.redirect_uris = self.client.registration_info[ "redirect_uris"] self.baseurl = self.authzsrv.baseurl self.resource_srv = resource_srv self.acr = acr self.trace = []
def __init__(self, dataset, symkey="", client_id=None, ca_certs=None, client_authn_method=None, keyjar=None, server_info=None, authz_page="", flow_type="", password=None, registration_info=None, response_type="", scope="", **kwargs): ResourceServerBase.__init__(self, dataset, symkey) Client.__init__(self, client_id, ca_certs, client_authn_method, keyjar, server_info, authz_page, flow_type, password, registration_info, response_type, scope) self.kwargs = kwargs self.srv_discovery_url = "" self.cookie_handler = http_util.CookieDealer(self) self.cookie_name = "resourceserver1c"
def __init__( self, dataset, symkey="", rs_keyjar=None, baseurl="", # client conf below client_id=None, ca_certs=None, client_authn_method=None, c_keyjar=None, server_info=None, authz_page="", flow_type="", password=None, registration_info=None, response_type="", scope="", ca_bundle=None): self.ressrv = ResourceServer1C.__init__(dataset, symkey, client_id, ca_certs, client_authn_method, rs_keyjar, server_info, authz_page, flow_type, password, registration_info, response_type, scope, baseurl) self.client = Client(client_id, ca_certs, client_authn_method, c_keyjar, server_info, authz_page, flow_type, password, registration_info, response_type, scope) self.ca_bundle = ca_bundle
def __init__(self, client_name, redirect_uris, resource_srv, acr, verify_ssl=True): UserInfo.__init__(self) # The UMA Client reginfo = { "client_name": client_name, "application_type": "native", "redirect_uris": redirect_uris } self.client = Client( {}, client_authn_methods=CLIENT_AUTHN_METHOD, registration_info=reginfo, verify_ssl=verify_ssl) self.client.redirect_uris = redirect_uris self.resource_srv = resource_srv self.acr = acr
def create_client(self): dataset = DictDBWrap(USERDB) client = Client({}, client_authn_methods=CLIENT_AUTHN_METHOD) self.rsh = ResourceSetHandler(dataset, client, "hans") self.rsh.dataset.scopes2op[ 'https://dirg.org.umu.se/uma/read'] = self.rsh.dataset.get self.rsh.client.provider_info = { "resource_set_registration_endpoint": 'https://as.example.com/rsr' } self.rsh.token["PAT"] = 'pat'
def __init__(self, client_name, redirect_uris, resource_srv, acr, verify_ssl=True): UserInfo.__init__(self) # The UMA Client reginfo = {"client_name": client_name, "application_type": "native", "redirect_uris": redirect_uris} self.client = Client( {}, client_authn_methods=CLIENT_AUTHN_METHOD, registration_info=reginfo, verify_ssl=verify_ssl ) self.client.redirect_uris = redirect_uris self.resource_srv = resource_srv self.acr = acr
def __init__(self, dataset, resource_owner, info_store, symkey="", client_id=None, ca_certs=None, client_authn_methods=None, keyjar=None, server_info=None, authz_page="", flow_type="", password=None, registration_info=None, response_type="", scope="", **kwargs): self.client = Client(client_id=client_id, ca_certs=ca_certs, client_authn_methods=client_authn_methods, keyjar=keyjar, server_info=server_info, authz_page=authz_page, flow_type=flow_type, password=password, registration_info=registration_info, response_type=response_type, scope=scope) self.rs_handler = ResourceSetHandler(dataset, self.client, resource_owner) self.info_store = info_store self.symkey = symkey self.kwargs = kwargs self.srv_discovery_url = "" self.cookie_handler = http_util.CookieDealer(self) self.cookie_name = "resourceserver" self.rsd_map = {} self.pat = None
def create_client(self): dataset = DictDBWrap(USERDB) # The scope to dataset operation map dataset.register_scope('https://dirg.org.umu.se/uma/read', 'get') client = Client({}, client_authn_methods=CLIENT_AUTHN_METHOD) resource_owner = 'hans' self.rsh = ResourceSetHandler(dataset, client, resource_owner) self.rsh.client.provider_info = { "resource_set_registration_endpoint": 'https://as.example.com/rsr' } # No the real PAT obviously self.rsh.token["PAT"] = 'pat' # map client API operation (HTTP GET) to scope self.rsh.op2scope = {'GET': 'https://dirg.org.umu.se/uma/read'}
class UmaCAS(object): def __init__( self, name, sdb, cdb, authn_broker, authz, client_authn, symkey, urlmap=None, as_keyjar=None, as_configuration=None, base_url="", client_authn_methods=None, authn_at_registration="", client_info_url="", secret_lifetime=86400, # client conf below client_id=None, ca_certs=None, client_authn_method=None, c_keyjar=None, server_info=None, authz_page="", flow_type="", password=None, registration_info=None, response_type="", scope="", acr="", resource_srv=""): self.authzsrv = OAuth2UmaAS( name, sdb, cdb, authn_broker, authz, client_authn, symkey, urlmap, as_keyjar, configuration=as_configuration, base_url=base_url, client_authn_methods=client_authn_methods, authn_at_registration=authn_at_registration, client_info_url=client_info_url, secret_lifetime=secret_lifetime) self.client = Client(client_id, ca_certs, client_authn_method, c_keyjar, server_info, authz_page, flow_type, password, registration_info, response_type, scope) self.client.redirect_uris = self.client.registration_info[ "redirect_uris"] self.baseurl = self.authzsrv.baseurl self.resource_srv = resource_srv self.acr = acr self.trace = [] def get_aat(self, user): request_args = { "response_type": "code", "client_id": "internal", "redirect_uri": self.client.redirect_uris[0], "scope": [self.client.get_uma_scope("AAT")], "state": "_state" } areq = AuthorizationRequest(**request_args) self.trace.append( trace("get_aat", "C-->AS", query=areq.to_dict(), user=user)) sid = self.authzsrv.sdb.create_authz_session(user, areq) grant = self.authzsrv.sdb[sid]["code"] self.client.token[user] = { "AAT": self.authzsrv.sdb.upgrade_to_token(grant) } self.trace.append( trace("get_aat", "C<--AS", data={"AAT": self.client.token[user]["AAT"]["access_token"]})) # C <-> AS internal communication def rpt_endpoint(self, authn, **kwargs): return self.authzsrv.rpt_endpoint(authn) def get_rpt(self, user): authn = "Bearer %s" % self.client.token[user]["AAT"]["access_token"] self.trace.append(trace("*get_rpt", "C-->AS", authn_info=authn)) resp = self.rpt_endpoint(authn) rtr = RPTResponse().from_json(resp.message) self.client.token[user]["RPT"] = rtr["rpt"] self.trace.append( trace("*get_rpt", "C<--AS", data={"RPT": self.client.token[user]["RPT"]})) def authorization_request_endpoint(self, data, authn): self.trace.append( trace("*authorization_request", "C-->AS", authn_info=authn, query=data)) return self.authzsrv.authorization_request_endpoint(data, authn) def resource_sets_by_user(self, uid): return self.authzsrv.resource_sets_by_user(uid) def store_permission(self, user, requestor, resource_id, scopes): return self.authzsrv.store_permission(user, requestor, resource_id, scopes) # client stuff def rs_query(self, requestor, path): try: rpt = self.client.token[requestor]["RPT"] except KeyError: rpt = None url = "%s/%s" % (self.resource_srv, path) if rpt: kwargs = {"headers": [("Authorization", "Bearer %s" % rpt)]} self.trace.append( trace("rs_query", "C-->RS", authn_info="Bearer %s" % rpt, url=url)) else: kwargs = {} self.trace.append(trace("rs_query", "C-->RS", url=url)) return self.client.send(url, "GET", **kwargs) def get_info(self, requester, path, state=""): """ :param requester: requester """ resp = self.rs_query(requester, path) self.trace.append(trace("rs_query", "C<--RS", response=resp)) if resp.status_code == 200: return Response(resp.text) if resp.status_code == 401: # No RPT as_uri = resp.headers["as_uri"] if as_uri == self.baseurl: # It's me as it should be, means get a RPT from myself self.get_aat(requester) self.get_rpt(requester) return self.get_info(requester, path, state) else: return R2C[500]("Wrong AS") if resp.status_code == 403: # Permission registered, got ticket prr = PermissionRegistrationResponse().from_json(resp.text) kwargs = self.client.create_authorization_data_request( requester, prr["ticket"]) resp = self.authorization_request_endpoint( kwargs["data"], kwargs["headers"]["Authorization"]) self.trace.append( trace("*authorization_request", "C<--AS", response=resp)) if resp.status == "200 OK": return self.get_info(requester, path) raise UMAError() def get_tokens(self, query): aresp = AuthorizationResponse().from_urlencoded(query) uid = self.client.acquire_access_token(aresp, "AAT") self.client.get_rpt(uid) return uid
class UMAUserInfo(UserInfo): def __init__(self, client_name, redirect_uris, resource_srv, acr, verify_ssl=True): UserInfo.__init__(self) # The UMA Client reginfo = {"client_name": client_name, "application_type": "native", "redirect_uris": redirect_uris} self.client = Client( {}, client_authn_methods=CLIENT_AUTHN_METHOD, registration_info=reginfo, verify_ssl=verify_ssl ) self.client.redirect_uris = redirect_uris self.resource_srv = resource_srv self.acr = acr def __call__(self, user, requestor, attrs=None, state="", **kwargs): """ This is the main API :param user: user identifier :param requestor: The entity_id of the SP that requests the information :param attrs: which attributes to return :param state: Where in the process am I """ return self.get_info(user, requestor, attrs, state, **kwargs) def rs_query(self, sp_user, user, attr=None): """ :param sp_user: an identifier representing the tuple (user, sp) :param user: user identifier common with the backend system """ try: rpt = self.client.token[sp_user]["RPT"] except KeyError: rpt = None url = create_query(self.resource_srv, urllib.parse.quote(user), attr) if rpt: kwargs = {"headers": {"Authorization": "Bearer %s" % rpt}} else: kwargs = {} return self.client.send(url, "GET", **kwargs) def get_info(self, user, requestor, attrs=None, state="", **kwargs): """ :param user: user identifier :param requestor: The entity_id of the SP that requests the information :param attrs: which attributes to return :param state: Where in the process am I """ # The real requestor is <user>@<sp_entity_id> user_and_sp = "%s@%s" % (user, requestor) resp = self.rs_query(user_and_sp, user, attrs) args = {} for attr in ["authn_method", "password"]: try: args[attr] = kwargs[attr] except KeyError: args[attr] = "" if resp.status_code == 200: return Response(resp.text) if resp.status_code == 401: # No RPT as_uri = resp.headers["as_uri"] return self.client.acquire_grant(as_uri, "RPT", user_and_sp, state, self.acr, **args) # if isinstance(resp, Redirect): # which it should be # redirect that are part of the grant code flow # return resp # elif resp.status_code == 200: # ??? # return Response(resp.text) # else: # return R2C[resp.status_code](resp.text) if resp.status_code == 403: # Permission registered, got ticket if state == "403": # loop ? return {} prr = PermissionRegistrationResponse().from_json(resp.text) resp = self.client.authorization_data_request(user_and_sp, prr["ticket"]) if resp.status_code in (200, 201): return self.get_info(user, requestor, attrs, "403") raise UMAError() def get_tokens(self, query): aresp = AuthorizationResponse().from_urlencoded(query) uid = self.client.acquire_access_token(aresp, "AAT") self.client.get_rpt(uid) return uid
import hashlib from oic.utils.authn.client import CLIENT_AUTHN_METHOD from uma.client import Client from uma.resourcesrv import ResourceServer1C __author__ = 'rolandh' # The UMA Client reginfo = { "client_name": "https://idp.example.com", "application_type": "native", "redirect_uris": ["https://client.example.com/uma"] } CCONF = {"client_authn_method": CLIENT_AUTHN_METHOD} idp_client = Client({}, CCONF, registration_info=reginfo) # The UMA RS class DataSet(object): def __init__(self): pass def __call__(self, owner, scopes, **kwargs): return "Some result" ressrv = ResourceServer1C(DataSet(), registration_info=reginfo) EPPN = b"*****@*****.**"
def __init__( self, name, sdb, cdb, authn_broker, authz, client_authn, symkey, urlmap=None, as_keyjar=None, as_configuration=None, base_url="", client_authn_methods=None, authn_at_registration="", client_info_url="", secret_lifetime=86400, # client conf below client_id=None, ca_certs=None, client_authn_method=None, c_keyjar=None, server_info=None, authz_page="", flow_type="", password=None, registration_info=None, response_type="", scope="", acr="", resource_srv="", ): self.authzsrv = OAuth2UmaAS( name, sdb, cdb, authn_broker, authz, client_authn, symkey, urlmap, as_keyjar, configuration=as_configuration, base_url=base_url, client_authn_methods=client_authn_methods, authn_at_registration=authn_at_registration, client_info_url=client_info_url, secret_lifetime=secret_lifetime, ) self.client = Client( client_id, ca_certs, client_authn_method, c_keyjar, server_info, authz_page, flow_type, password, registration_info, response_type, scope, ) self.client.redirect_uris = self.client.registration_info["redirect_uris"] self.baseurl = self.authzsrv.baseurl self.resource_srv = resource_srv self.acr = acr self.trace = []
from oic.utils.authn.client import CLIENT_AUTHN_METHOD from uma.client import Client from uma.resourcesrv import ResourceServer1C __author__ = 'rolandh' # The UMA Client reginfo = { "client_name": "https://idp.example.com", "application_type": "native", "redirect_uris": ["https://client.example.com/uma"] } CCONF = {"client_authn_method": CLIENT_AUTHN_METHOD} idp_client = Client({}, CCONF, registration_info=reginfo) # The UMA RS class DataSet(object): def __init__(self): pass def __call__(self, owner, scopes, **kwargs): return "Some result" ressrv = ResourceServer1C(DataSet(), registration_info=reginfo) EPPN = b"*****@*****.**"
RS_PORT = 8089 RS_HOST = "https://localhost:%s" % RS_PORT RS_CookieHandler = CookieDealer(None) ressrv = uma_rs.main(RS_HOST, RS_CookieHandler) print("go!") # ============================== 1 =========================================== # teach the RS about what the AS can do and where (=endpoints) opc = OIDCProviderConfiguration() resp = authzsrv.providerinfo_endpoint() oidc_pcr = ProviderConfigurationResponse().from_json(resp.message) client = Client({}, client_config={"client_authn_method": CLIENT_AUTHN_METHOD}, registration_info=ressrv.registration_info) callback = "%s/%s" % (ressrv.baseurl, "key") client.redirect_uris = [callback] _me = ressrv.registration_info.copy() _me["redirect_uris"] = [callback] # link to the client RESSRV_CLI_KEY = "abcdefghijklmn" ressrv.oic_client[RESSRV_CLI_KEY] = client ressrv.client[BASE + "/"] = client client.handle_provider_config(oidc_pcr, authzsrv.baseurl, False, False) opc.update(oidc_pcr) resp = authzsrv.uma_providerinfo_endpoint()
class UmaCAS(object): def __init__( self, name, sdb, cdb, authn_broker, authz, client_authn, symkey, urlmap=None, as_keyjar=None, as_configuration=None, base_url="", client_authn_methods=None, authn_at_registration="", client_info_url="", secret_lifetime=86400, # client conf below client_id=None, ca_certs=None, client_authn_method=None, c_keyjar=None, server_info=None, authz_page="", flow_type="", password=None, registration_info=None, response_type="", scope="", acr="", resource_srv="", ): self.authzsrv = OAuth2UmaAS( name, sdb, cdb, authn_broker, authz, client_authn, symkey, urlmap, as_keyjar, configuration=as_configuration, base_url=base_url, client_authn_methods=client_authn_methods, authn_at_registration=authn_at_registration, client_info_url=client_info_url, secret_lifetime=secret_lifetime, ) self.client = Client( client_id, ca_certs, client_authn_method, c_keyjar, server_info, authz_page, flow_type, password, registration_info, response_type, scope, ) self.client.redirect_uris = self.client.registration_info["redirect_uris"] self.baseurl = self.authzsrv.baseurl self.resource_srv = resource_srv self.acr = acr self.trace = [] def get_aat(self, user): request_args = { "response_type": "code", "client_id": "internal", "redirect_uri": self.client.redirect_uris[0], "scope": [self.client.get_uma_scope("AAT")], "state": "_state", } areq = AuthorizationRequest(**request_args) self.trace.append(trace("get_aat", "C-->AS", query=areq.to_dict(), user=user)) sid = self.authzsrv.sdb.create_authz_session(user, areq) grant = self.authzsrv.sdb[sid]["code"] self.client.token[user] = {"AAT": self.authzsrv.sdb.upgrade_to_token(grant)} self.trace.append(trace("get_aat", "C<--AS", data={"AAT": self.client.token[user]["AAT"]["access_token"]})) # C <-> AS internal communication def rpt_endpoint(self, authn, **kwargs): return self.authzsrv.rpt_endpoint(authn) def get_rpt(self, user): authn = "Bearer %s" % self.client.token[user]["AAT"]["access_token"] self.trace.append(trace("*get_rpt", "C-->AS", authn_info=authn)) resp = self.rpt_endpoint(authn) rtr = RPTResponse().from_json(resp.message) self.client.token[user]["RPT"] = rtr["rpt"] self.trace.append(trace("*get_rpt", "C<--AS", data={"RPT": self.client.token[user]["RPT"]})) def authorization_request_endpoint(self, data, authn): self.trace.append(trace("*authorization_request", "C-->AS", authn_info=authn, query=data)) return self.authzsrv.authorization_request_endpoint(data, authn) def resource_sets_by_user(self, uid): return self.authzsrv.resource_sets_by_user(uid) def store_permission(self, user, requestor, resource_id, scopes): return self.authzsrv.store_permission(user, requestor, resource_id, scopes) # client stuff def rs_query(self, requestor, path): try: rpt = self.client.token[requestor]["RPT"] except KeyError: rpt = None url = "%s/%s" % (self.resource_srv, path) if rpt: kwargs = {"headers": [("Authorization", "Bearer %s" % rpt)]} self.trace.append(trace("rs_query", "C-->RS", authn_info="Bearer %s" % rpt, url=url)) else: kwargs = {} self.trace.append(trace("rs_query", "C-->RS", url=url)) return self.client.send(url, "GET", **kwargs) def get_info(self, requester, path, state=""): """ :param requester: requester """ resp = self.rs_query(requester, path) self.trace.append(trace("rs_query", "C<--RS", response=resp)) if resp.status_code == 200: return Response(resp.text) if resp.status_code == 401: # No RPT as_uri = resp.headers["as_uri"] if as_uri == self.baseurl: # It's me as it should be, means get a RPT from myself self.get_aat(requester) self.get_rpt(requester) return self.get_info(requester, path, state) else: return R2C[500]("Wrong AS") if resp.status_code == 403: # Permission registered, got ticket prr = PermissionRegistrationResponse().from_json(resp.text) kwargs = self.client.create_authorization_data_request(requester, prr["ticket"]) resp = self.authorization_request_endpoint(kwargs["data"], kwargs["headers"]["Authorization"]) self.trace.append(trace("*authorization_request", "C<--AS", response=resp)) if resp.status == "200 OK": return self.get_info(requester, path) raise UMAError() def get_tokens(self, query): aresp = AuthorizationResponse().from_urlencoded(query) uid = self.client.acquire_access_token(aresp, "AAT") self.client.get_rpt(uid) return uid
class UMAUserInfo(UserInfo): def __init__(self, client_name, redirect_uris, resource_srv, acr, verify_ssl=True): UserInfo.__init__(self) # The UMA Client reginfo = { "client_name": client_name, "application_type": "native", "redirect_uris": redirect_uris } self.client = Client({}, client_authn_methods=CLIENT_AUTHN_METHOD, registration_info=reginfo, verify_ssl=verify_ssl) self.client.redirect_uris = redirect_uris self.resource_srv = resource_srv self.acr = acr def __call__(self, user, requestor, attrs=None, state="", **kwargs): """ This is the main API :param user: user identifier :param requestor: The entity_id of the SP that requests the information :param attrs: which attributes to return :param state: Where in the process am I """ return self.get_info(user, requestor, attrs, state, **kwargs) def rs_query(self, sp_user, user, attr=None): """ :param sp_user: an identifier representing the tuple (user, sp) :param user: user identifier common with the backend system """ try: rpt = self.client.token[sp_user]["RPT"] except KeyError: rpt = None url = create_query(self.resource_srv, urllib.parse.quote(user), attr) if rpt: kwargs = {"headers": {"Authorization": "Bearer %s" % rpt}} else: kwargs = {} return self.client.send(url, "GET", **kwargs) def get_info(self, user, requestor, attrs=None, state="", **kwargs): """ :param user: user identifier :param requestor: The entity_id of the SP that requests the information :param attrs: which attributes to return :param state: Where in the process am I """ # The real requestor is <user>@<sp_entity_id> user_and_sp = "%s@%s" % (user, requestor) resp = self.rs_query(user_and_sp, user, attrs) args = {} for attr in ["authn_method", "password"]: try: args[attr] = kwargs[attr] except KeyError: args[attr] = "" if resp.status_code == 200: return Response(resp.text) if resp.status_code == 401: # No RPT as_uri = resp.headers["as_uri"] return self.client.acquire_grant(as_uri, "RPT", user_and_sp, state, self.acr, **args) #if isinstance(resp, Redirect): # which it should be # redirect that are part of the grant code flow # return resp # elif resp.status_code == 200: # ??? # return Response(resp.text) # else: # return R2C[resp.status_code](resp.text) if resp.status_code == 403: # Permission registered, got ticket if state == "403": # loop ? return {} prr = PermissionRegistrationResponse().from_json(resp.text) resp = self.client.authorization_data_request( user_and_sp, prr["ticket"]) if resp.status_code in (200, 201): return self.get_info(user, requestor, attrs, "403") raise UMAError() def get_tokens(self, query): aresp = AuthorizationResponse().from_urlencoded(query) uid = self.client.acquire_access_token(aresp, "AAT") self.client.get_rpt(uid) return uid
class ResourceServer(object): def __init__(self, dataset, resource_owner, info_store, symkey="", client_id=None, ca_certs=None, client_authn_methods=None, keyjar=None, server_info=None, authz_page="", flow_type="", password=None, registration_info=None, response_type="", scope="", **kwargs): self.client = Client(client_id=client_id, ca_certs=ca_certs, client_authn_methods=client_authn_methods, keyjar=keyjar, server_info=server_info, authz_page=authz_page, flow_type=flow_type, password=password, registration_info=registration_info, response_type=response_type, scope=scope) self.rs_handler = ResourceSetHandler(dataset, self.client, resource_owner) self.info_store = info_store self.symkey = symkey self.kwargs = kwargs self.srv_discovery_url = "" self.cookie_handler = http_util.CookieDealer(self) self.cookie_name = "resourceserver" self.rsd_map = {} self.pat = None # def rs_request_info(self, msgtype, method=DEFAULT_METHOD, # authn_method="bearer_header", request_args=None, # extra_args=None): # # return self.client.request_info(msgtype, method, # request_args=request_args, # extra_args=extra_args, # authn_method=authn_method, # content_type=JSON_ENCODED) @staticmethod def _get_bearer_token(authz): try: if authz.startswith("Bearer"): return authz[len("Bearer "):] else: return None except KeyError: return None def do_introspection(self, rpt, path=None): """ The resource server doing introspection on a RPT at the AuthzServer :param rpt: Resource access token :param path: path representing the resource :returns: """ pat = self.client.token ir = IntrospectionRequest(token=rpt) # if path: # fpath = self.rs_handler.dataset.resource_name(path) # ir["resource_id"] = self.rs_handler.path2rsid[fpath] request_args = {"access_token": pat} ht_args = self.client.client_authn_method["bearer_header"]( self).construct(ir, request_args=request_args) url = list( self.client.provider_info.values())[0]["introspection_endpoint"] return self.client.request_and_return(url, IntrospectionResponse, body=ir.to_json(), body_type="json", http_args=ht_args) # ======================================================================== # Below is the client API methods # ======================================================================== def result(self, environ, start_response, result): resp = Response(mako_template="opresult.mako", template_lookup=self.kwargs["template_lookup"], headers=[]) argv = {"result": result} return resp(environ, start_response, **argv) @staticmethod def filter_by_permission(intro, scope=None): """ :param intro: An IntrospectionResponse instance :param scope: The scope that access is asked for :return: list of resource_set_description ids :rtype: list """ rsids = [] now = utc_time_sans_frac() try: assert now < intro["exp"] except KeyError: pass except AssertionError: return False for perm in intro["permissions"]: try: assert now < perm["exp"] except KeyError: pass except AssertionError: continue try: assert scope in perm["scopes"] except AssertionError: pass else: rsids.append(perm["resource_set_id"]) return rsids def collect_info(self, introspection_response, scope): """ :param introspection_response: :param scope: :return: Dictionary of attributes and values :rtype: dict """ rsids = self.filter_by_permission(introspection_response, scope) # Collect information res = {} for rsid in rsids: lid = self.rs_handler.rsid2lid[rsid] part = lid.split(':') if len(part) == 2: # every value for an attribute res[part[1]] = self.rs_handler.get_info(part[0], part[1]) else: try: res[part[1]].append(part[2]) except KeyError: res[part[1]] = [part[2]] return res # ---------------------------------------------------------------------- # ---------------------------------------------------------------------- def resource_endpoint(self, operation, path, auth=None, query=None): """ This is where the client sends its requests. Assumes a HTTP interface. Three possible cases: - No RPT - A RPT that doesn't give the necessary access - A valid RPT :param auth: Authentication information, HTTP Authorization header :param operation: A HTTP operation: "GET","POST", ... :param path: The URL path :param query: A possible URL query part :return: HTTP response """ rpt = self._get_bearer_token(auth) if auth is None: # no RPT rssp = self.rs_handler.query2permission_registration_request_primer( operation, path, query) else: self.do_introspection(rpt) return Response
RS_HOST = "https://*****:*****@example.com"], "redirect_uris": [callback]} # link to the client that will talk to the AS RESSRV_CLI_KEY = "abcdefghijklmn" ressrv.oidc_client = client ressrv.client = client # load the AS provider configuration
"bearer_header"](rsrv).construct(ireq, request_args=req_args) _iresp = asrv.introspection_endpoint(ireq.to_json(), http_args["headers"]["Authorization"]) return IntrospectionResponse().from_json(_iresp.message) # ============================== 1 =========================================== # teach the RS about what the AS can do and where (=endpoints) opc = OIDCProviderConfiguration() resp = authzsrv.providerinfo_endpoint() oidc_pcr = ProviderConfigurationResponse().from_json(resp.message) client = Client( {}, client_config={"client_authn_method": CLIENT_AUTHN_METHOD}, registration_info=ressrv.registration_info) callback = "%s/%s" % (ressrv.baseurl, "key") client.redirect_uris = [callback] _me = ressrv.registration_info.copy() _me["redirect_uris"] = [callback] # link to the client RESSRV_CLI_KEY = "abcdefghijklmn" ressrv.oic_client[RESSRV_CLI_KEY] = client ressrv.client[BASE + "/"] = client client.handle_provider_config(oidc_pcr, authzsrv.baseurl, False, False) opc.update(oidc_pcr) resp = authzsrv.uma_providerinfo_endpoint()
class ResourceServer(object): def __init__(self, dataset, resource_owner, info_store, symkey="", client_id=None, ca_certs=None, client_authn_methods=None, keyjar=None, server_info=None, authz_page="", flow_type="", password=None, registration_info=None, response_type="", scope="", **kwargs): self.client = Client(client_id=client_id, ca_certs=ca_certs, client_authn_methods=client_authn_methods, keyjar=keyjar, server_info=server_info, authz_page=authz_page, flow_type=flow_type, password=password, registration_info=registration_info, response_type=response_type, scope=scope) self.rs_handler = ResourceSetHandler(dataset, self.client, resource_owner) self.info_store = info_store self.symkey = symkey self.kwargs = kwargs self.srv_discovery_url = "" self.cookie_handler = http_util.CookieDealer(self) self.cookie_name = "resourceserver" self.rsd_map = {} self.pat = None # def rs_request_info(self, msgtype, method=DEFAULT_METHOD, # authn_method="bearer_header", request_args=None, # extra_args=None): # # return self.client.request_info(msgtype, method, # request_args=request_args, # extra_args=extra_args, # authn_method=authn_method, # content_type=JSON_ENCODED) @staticmethod def _get_bearer_token(authz): try: if authz.startswith("Bearer"): return authz[len("Bearer "):] else: return None except KeyError: return None def do_introspection(self, rpt, path=None): """ The resource server doing introspection on a RPT at the AuthzServer :param rpt: Resource access token :param path: path representing the resource :returns: """ pat = self.client.token ir = IntrospectionRequest(token=rpt) # if path: # fpath = self.rs_handler.dataset.resource_name(path) # ir["resource_id"] = self.rs_handler.path2rsid[fpath] request_args = {"access_token": pat} ht_args = self.client.client_authn_method[ "bearer_header"](self).construct(ir, request_args=request_args) url = list(self.client.provider_info.values())[0][ "introspection_endpoint"] return self.client.request_and_return(url, IntrospectionResponse, body=ir.to_json(), body_type="json", http_args=ht_args) # ======================================================================== # Below is the client API methods # ======================================================================== def result(self, environ, start_response, result): resp = Response(mako_template="opresult.mako", template_lookup=self.kwargs["template_lookup"], headers=[]) argv = { "result": result } return resp(environ, start_response, **argv) @staticmethod def filter_by_permission(intro, scope=None): """ :param intro: An IntrospectionResponse instance :param scope: The scope that access is asked for :return: list of resource_set_description ids :rtype: list """ rsids = [] now = utc_time_sans_frac() try: assert now < intro["exp"] except KeyError: pass except AssertionError: return False for perm in intro["permissions"]: try: assert now < perm["exp"] except KeyError: pass except AssertionError: continue try: assert scope in perm["scopes"] except AssertionError: pass else: rsids.append(perm["resource_set_id"]) return rsids def collect_info(self, introspection_response, scope): """ :param introspection_response: :param scope: :return: Dictionary of attributes and values :rtype: dict """ rsids = self.filter_by_permission(introspection_response, scope) # Collect information res = {} for rsid in rsids: lid = self.rs_handler.rsid2lid[rsid] part = lid.split(':') if len(part) == 2: # every value for an attribute res[part[1]] = self.rs_handler.get_info(part[0], part[1]) else: try: res[part[1]].append(part[2]) except KeyError: res[part[1]] = [part[2]] return res # ---------------------------------------------------------------------- # ---------------------------------------------------------------------- def resource_endpoint(self, operation, path, auth=None, query=None): """ This is where the client sends its requests. Assumes a HTTP interface. Three possible cases: - No RPT - A RPT that doesn't give the necessary access - A valid RPT :param auth: Authentication information, HTTP Authorization header :param operation: A HTTP operation: "GET","POST", ... :param path: The URL path :param query: A possible URL query part :return: HTTP response """ rpt = self._get_bearer_token(auth) if auth is None: # no RPT rssp = self.rs_handler.query2permission_registration_request_primer( operation, path, query) else: self.do_introspection(rpt) return Response
RS_PORT = 8089 RS_HOST = "https://*****:*****@example.com"], "redirect_uris": [callback] } # link to the client that will talk to the AS RESSRV_CLI_KEY = "abcdefghijklmn" ressrv.oidc_client = client
def __call__(self, owner, scopes, **kwargs): return "Some result" reginfo = { "client_name": "Resource server A", "redirect_uris": ["https://rsa.example.com/"], "application_type": "web" } ressrv = ResourceServer(DataSet(), registration_info=reginfo) # -------------------- ResourceServer as Client --------------------- rs_client = Client({}, {"client_authn_method": CLIENT_AUTHN_METHOD}) _me = ressrv.registration_info.copy() _me["redirect_uris"] = ["https://rs.example.com/"] # init authsrv authzsrv = Provider("foo", SessionDB(), CDB, None, AUTHZ, verify_client, "1234567890", keyjar=KeyJar()) authzsrv.baseurl = "https://as.example.com/" AUTHN_BROKER = AuthnBroker() AUTHN_BROKER.add(UNSPECIFIED, DummyAuthn(None, user="******"), 0, "http://%s" % socket.gethostname()) # AUTHN_BROKER.add(PASSWORD, # UsernamePasswordMako(