def test_deserialize(self): msg = { "client_id": "s6BhdRkqt3", "client_secret": "ZJYCqe3GGRvdrudKyZS0XhGv_Z45DuKhCUk0gBR1vZk", "client_secret_expires_at": 1577858400, "registration_access_token": "this.is.an.access.token.value.ffx83", "registration_client_uri": "https://server.example.com/connect/register?client_id" "=s6BhdRkqt3", "token_endpoint_auth_method": "client_secret_basic", "application_type": "web", "redirect_uris": ["https://client.example.org/callback", "https://client.example.org/callback2"], "client_name": "My Example", "client_name#ja-Jpan-JP": "クライアント名", "logo_uri": "https://client.example.org/logo.png", "subject_type": "pairwise", "sector_identifier_uri": "https://other.example.net/file_of_redirect_uris.json", "jwks_uri": "https://client.example.org/my_public_keys.jwks", "userinfo_encrypted_response_alg": "RSA1_5", "userinfo_encrypted_response_enc": "A128CBC+HS256", "contacts": ["*****@*****.**", "*****@*****.**"], "request_uris": [ "https://client.example.org/rf.txt" "#qpXaRLh_n93TTR9F252ValdatUQvQiJi5BDub2BeznA"] } resp = RegistrationResponse().deserialize(json.dumps(msg), "json") assert _eq(msg.keys(), resp.keys())
def test_registration_endpoint_openid4us(self): req = RegistrationRequest( **{'token_endpoint_auth_method': u'client_secret_post', 'redirect_uris': [ u'https://connect.openid4.us:5443/phpRp/index.php/callback', u'https://connect.openid4.us:5443/phpRp/authcheck.php/authcheckcb'], 'jwks_uri': u'https://connect.openid4.us:5443/phpRp/rp/rp.jwk', 'userinfo_encrypted_response_alg': u'RSA1_5', 'contacts': [u'*****@*****.**'], 'userinfo_encrypted_response_enc': u'A128CBC-HS256', 'application_type': u'web', 'client_name': u'ABRP-17', 'grant_types': [u'authorization_code', u'implicit'], 'post_logout_redirect_uris': [ u'https://connect.openid4.us:5443/phpRp/index.php/logoutcb'], 'subject_type': u'public', 'response_types': [u'code', u'token', u'id_token', u'code token', u'code id_token', u'id_token token', u'code id_token token'], 'policy_uri': u'https://connect.openid4.us:5443/phpRp/index.php/policy', 'logo_uri': u'https://connect.openid4.us:5443/phpRp/media/logo.png'}) resp = self.provider.registration_endpoint(request=req.to_json()) regresp = RegistrationResponse().deserialize(resp.message, "json") assert _eq(regresp.keys(), list(req.keys()) + ['registration_client_uri', 'client_secret_expires_at', 'registration_access_token', 'client_id', 'client_secret', 'client_id_issued_at'])
def read_registration(self, authn, request, **kwargs): """ Read all information this server has on a client. Authorization is done by using the access token that was return as part of the client registration result. :param authn: The Authorization HTTP header :param request: The query part of the URL :param kwargs: Any other arguments :return: """ logger.debug("authn: %s, request: %s" % (authn, request)) # verify the access token, has to be key into the client information # database. assert authn.startswith("Bearer ") token = authn[len("Bearer "):] client_id = self.cdb[token] # extra check _info = urlparse.parse_qs(request) assert _info["client_id"][0] == client_id logger.debug("Client '%s' reads client info" % client_id) args = dict([(k, v) for k, v in self.cdb[client_id].items() if k in RegistrationResponse.c_param]) self.comb_redirect_uris(args) response = RegistrationResponse(**args) return Response(response.to_json(), content="application/json", headers=[("Cache-Control", "no-store")])
def test_registration_endpoint(self): req = RegistrationRequest() req["application_type"] = "web" req["client_name"] = "My super service" req["redirect_uris"] = ["http://example.com/authz"] req["contacts"] = ["*****@*****.**"] req["response_types"] = ["code"] resp = self.provider.registration_endpoint(request=req.to_json()) regresp = RegistrationResponse().deserialize(resp.message, "json") assert _eq( regresp.keys(), [ "redirect_uris", "contacts", "application_type", "client_name", "registration_client_uri", "client_secret_expires_at", "registration_access_token", "client_id", "client_secret", "client_id_issued_at", "response_types", ], )
def _fixup_registration_response(self, http_resp): # remove client_secret since no token endpoint is published response = RegistrationResponse().deserialize(http_resp.message, "json") del response["client_secret"] # specify supported id token signing alg response["id_token_signed_response_alg"] = self.sign_alg http_resp.message = response.to_json() return http_resp
def refresh_session_endpoint(self, query): self.parse_refresh_session_request(query=query) resp = RegistrationResponse(client_id="anonymous", client_secret="hemligt") response = Response() response.headers = {"content-type": "application/json"} response.text = resp.to_json() return response
def create_client_from_secrets(self, name: str, provider: config.ProviderConfig) -> None: """ Try to create an openid connect client from the secrets that are saved in the secrets file""" client_secrets = self._secrets[name] client = oic.oic.Client(client_authn_method=CLIENT_AUTHN_METHOD) client.provider_config(provider.configuration_url) client_reg = RegistrationResponse(**client_secrets) client.store_registration_info(client_reg) client.redirect_uris = client_secrets['redirect_uris'] self.__oidc_provider[name] = client self._secrets[name] = client_reg.to_dict()
def test_registration_endpoint_unicode(self): data = 'application_type=web&client_name=M%C3%A1+supe%C5%99+service&' \ 'redirect_uris=http%3A%2F%2Fexample.com%2Fauthz&response_types=code' resp = self.provider.registration_endpoint(request=data) regresp = RegistrationResponse().deserialize(resp.message, "json") assert _eq(regresp.keys(), [ 'redirect_uris', 'application_type', 'client_name', 'registration_client_uri', 'client_secret_expires_at', 'registration_access_token', 'client_id', 'client_secret', 'client_id_issued_at', 'response_types' ])
def test_read_registration(self): rr = RegistrationRequest(operation="register", redirect_uris=["http://example.org/new"], response_types=["code"]) registration_req = rr.to_json() resp = self.provider.registration_endpoint(request=registration_req) regresp = RegistrationResponse().from_json(resp.message) authn = ' '.join(['Bearer', regresp['registration_access_token']]) query = '='.join(['client_id', regresp['client_id']]) resp = self.provider.read_registration(authn, query) assert json.loads(resp.message) == regresp.to_dict()
def test_read_registration(self): rr = RegistrationRequest( operation="register", redirect_uris=["http://example.org/new"], response_types=["code"] ) registration_req = rr.to_json() resp = self.provider.registration_endpoint(request=registration_req) regresp = RegistrationResponse().from_json(resp.message) authn = " ".join(["Bearer", regresp["registration_access_token"]]) query = "=".join(["client_id", regresp["client_id"]]) resp = self.provider.read_registration(authn, query) assert json.loads(resp.message) == regresp.to_dict()
def setup_client_registration_endpoint(self): client_info = TestConfiguration.get_instance().rp_config.CLIENTS[PROVIDER]["client_info"] request = RegistrationRequest().deserialize(json.dumps(client_info), "json") _cinfo = self.provider.do_client_registration(request, CLIENT_ID) args = dict([(k, v) for k, v in _cinfo.items() if k in RegistrationResponse.c_param]) args['client_id'] = CLIENT_ID self.provider.comb_uri(args) registration_response = RegistrationResponse(**args) responses.add( responses.POST, self.op_base + "registration", body=registration_response.to_json(), status=200, content_type='application/json')
def test_registered_redirect_uri_with_query_component(self): provider2 = Provider("FOOP", {}, {}, None, None, None, None, "") rr = RegistrationRequest( operation="register", redirect_uris=["http://example.org/cb?foo=bar"], response_types=["code"]) registration_req = rr.to_json() resp = provider2.registration_endpoint(request=registration_req) regresp = RegistrationResponse().from_json(resp.message) print regresp.to_dict() faulty = [ "http://example.org/cb", "http://example.org/cb/foo", "http://example.org/cb?got=you", "http://example.org/cb?foo=you" "http://example.org/cb?foo=bar&got=you", "http://example.org/cb?foo=you&foo=bar" ] correct = [ "http://example.org/cb?foo=bar", ] cid = regresp["client_id"] for ruri in faulty: areq = AuthorizationRequest(redirect_uri=ruri, client_id=cid, scope="openid", response_type="code") print areq try: provider2._verify_redirect_uri(areq) except RedirectURIError: pass for ruri in correct: areq = AuthorizationRequest(redirect_uri=ruri, client_id=cid, scope="openid", response_type="code") resp = provider2._verify_redirect_uri(areq) print resp assert resp is None
def test_registered_redirect_uri_with_query_component(self): provider2 = Provider("FOOP", {}, {}, None, None, None, None, "") rr = RegistrationRequest(operation="register", redirect_uris=["http://example.org/cb?foo=bar"], response_types=["code"]) registration_req = rr.to_json() resp = provider2.registration_endpoint(request=registration_req) regresp = RegistrationResponse().from_json(resp.message) print regresp.to_dict() faulty = [ "http://example.org/cb", "http://example.org/cb/foo", "http://example.org/cb?got=you", "http://example.org/cb?foo=you" "http://example.org/cb?foo=bar&got=you", "http://example.org/cb?foo=you&foo=bar" ] correct = [ "http://example.org/cb?foo=bar", ] cid = regresp["client_id"] for ruri in faulty: areq = AuthorizationRequest(redirect_uri=ruri, client_id=cid, scope="openid", response_type="code") print areq try: provider2._verify_redirect_uri(areq) except RedirectURIError: pass for ruri in correct: areq = AuthorizationRequest(redirect_uri=ruri, client_id=cid, scope="openid", response_type="code") resp = provider2._verify_redirect_uri(areq) print resp assert resp is None
def oidc_login(): state = rndstr() nonce = rndstr() client = Client(client_authn_method=CLIENT_AUTHN_METHOD) client.provider_config(OIDC_INFO_URL) info = {"client_id": CLIENT_ID, "client_secret": CLIENT_SECRET} client_reg = RegistrationResponse(**info) client.store_registration_info(client_reg) args = { "client_id": client.client_id, "response_type": "code", "scope": ["openid"], "nonce": nonce, "redirect_uri": OIDC_REDIRECT_URI, "state": state } auth_req = client.construct_AuthorizationRequest(request_args=args) login_url = auth_req.request(client.authorization_endpoint) # Save in cache Key: state => Value: nonce current_app.cache.set(state, nonce) return redirect(login_url, 303)
def test_scope_who_am_i(provider): registration_params = { "application_type": "web", "response_types": ["code", "token"], "redirect_uris": "http://example.org" } reg_req = RegistrationRequest(**registration_params) resp = provider.registration_endpoint(reg_req.to_urlencoded()) reg_resp = RegistrationResponse().from_json(resp.message) auth_req = AuthorizationRequest( **{ "client_id": reg_resp["client_id"], "scope": "openid who_am_i", "response_type": "code token", "redirect_uri": "http://example.org", "state": "state0", "nonce": "nonce0" }) resp = provider.authorization_endpoint(auth_req.to_urlencoded()) auth_resp = AuthorizationResponse().from_urlencoded(resp.message) userinfo_req = UserInfoRequest( **{"access_token": auth_resp["access_token"]}) resp = provider.userinfo_endpoint(userinfo_req.to_urlencoded()) userinfo_resp = AuthorizationResponse().from_json(resp.message) assert userinfo_resp["given_name"] == "Bruce" assert userinfo_resp["family_name"] == "Lee"
def init_oic(self, provider_name): if provider_name not in PROVIDER_URL_MAP: raise ValueError('Invalid provider: %s', provider_name) provider = PROVIDER_URL_MAP[provider_name] self.scopes = ['openid', 'profile', 'email'] db = SessionStore(self.db) client = Consumer(db, consumer_config, client_config=client_config) client.allow['issuer_mismatch'] = True # Github does not support dynamically resolving OpenID configuration. if provider_name == PROVIDER_GITHUB: self.scopes = ['user:email', 'read:user'] client.provider_info = { 'authorization_endpoint': 'https://github.com/login/oauth/authorize', 'token_endpoint': 'https://github.com/login/oauth/access_token', } client.handle_provider_config(client.provider_info, 'GitHub') else: client.provider_info = client.provider_config(provider) providers = self.db.oic_registration.filter(None, {'issuer': provider}) assert len(providers) == 1 provider = self.db.oic_registration.getnode(providers[0]) client_reg = RegistrationResponse( client_id=provider['client_id'], client_secret=provider['client_secret']) client.store_registration_info(client_reg) return client
def handle_client_registration_request(self, request, http_headers=None): # type: (Optional[str], Optional[Mapping[str, str]]) -> oic.oic.message.RegistrationResponse """ Handles a client registration request. :param request: JSON request from POST body :param http_headers: http headers """ registration_req = RegistrationRequest().deserialize(request, 'json') for validator in self.registration_request_validators: validator(registration_req) logger.debug('parsed authentication_request: %s', registration_req) client_id, client_secret = self._issue_new_client() credentials = { 'client_id': client_id, 'client_id_issued_at': int(time.time()), 'client_secret': client_secret, 'client_secret_expires_at': 0 # never expires } response_params = self.match_client_preferences_with_provider_capabilities( registration_req) response_params.update(credentials) self.clients[client_id] = copy.deepcopy(response_params) registration_resp = RegistrationResponse(**response_params) logger.debug('registration_resp=%s from registration_req=%s', registration_resp, registration_req) return registration_resp
def registration_endpoint(self, request, authn=None, **kwargs): try: reg_req = RegistrationRequest().deserialize(request, "json") except ValueError: reg_req = RegistrationRequest().deserialize(request) self.events.store(EV_PROTOCOL_REQUEST, reg_req) try: response_type_cmp(kwargs['test_cnf']['response_type'], reg_req['response_types']) except KeyError: pass try: provider.Provider.verify_redirect_uris(reg_req) except InvalidRedirectURIError as err: return error(error="invalid_configuration_parameter", descr="Invalid redirect_uri: {}".format(err)) # Do initial verification that all endpoints from the client uses # https for endp in ["jwks_uri", "initiate_login_uri"]: try: uris = reg_req[endp] except KeyError: continue if not isinstance(uris, list): uris = [uris] for uri in uris: if not uri.startswith("https://"): return error( error="invalid_configuration_parameter", descr="Non-HTTPS endpoint in '{}'".format(endp)) if not "contacts" in reg_req: return error( error="invalid_configuration_parameter", descr="No \"contacts\" claim provided in registration request." ) elif not "@" in reg_req["contacts"][0]: return error( error="invalid_configuration_parameter", descr= "First address in \"contacts\" value in registration request is not a valid e-mail address." ) _response = provider.Provider.registration_endpoint( self, request, authn, **kwargs) self.events.store(EV_HTTP_RESPONSE, _response) self.init_keys = [] if "jwks_uri" in reg_req: if _response.status == "200 OK": # find the client id req_resp = RegistrationResponse().from_json(_response.message) for kb in self.keyjar[req_resp["client_id"]]: if kb.imp_jwks: self.events.store("Client JWKS", kb.imp_jwks) return _response
def setup_client_registration_endpoint(self): client_info = TestConfiguration.get_instance( ).rp_config.CLIENTS[PROVIDER]["client_info"] request = RegistrationRequest().deserialize(json.dumps(client_info), "json") _cinfo = self.provider.do_client_registration(request, CLIENT_ID) args = dict([(k, v) for k, v in _cinfo.items() if k in RegistrationResponse.c_param]) args['client_id'] = CLIENT_ID self.provider.comb_uri(args) registration_response = RegistrationResponse(**args) responses.add(responses.POST, self.op_base + "registration", body=registration_response.to_json(), status=200, content_type='application/json')
def _configure_client(self): config_file_path = JwtAuthenticationMethod.openid_client_config_path() if not os.path.exists(config_file_path): logger.info( 'OpenID Connect configuration ({}) not found, JWT' ' authentication is disabled'.format(config_file_path) ) return with open(config_file_path) as fp: config = json.loads(fp.read()) self._client = Client( client_authn_method=CLIENT_AUTHN_METHOD, verify_ssl='/etc/pki/tls/certs/ca-bundle.crt' ) self._client.provider_config(config['issuer']) client_registration = RegistrationResponse( client_id=config['client_id'], client_secret=config['client_secret'] ) self._client.store_registration_info(client_registration)
def get_client(): """Method that prepare the oidc client. This method use lru_cache in order call the OIDC provider once per thread Today we only support OIDC providers (ISSUER) that expose a /.well-known/openid-configuration route At the moment to authenticate the RP to the OIDC provider we only support through client_id/secret_ID/rp_callback attributes. You must configure OIDC in AnyBlok configuration: * **oidc-provider-issuer**: The OIDC Provider urls (ie: https://gitlab.com) * **oidc-relying-party-callback**: The Relaying Party callback, once the user is authenticate against the OIDC provider he will be redirect to that uri to the RP service (ie: http://localhost:8080/callback). In general this value is also configured in your OIDC provider to avoid redirection issues. * **oidc-relying-party-client-id**: The client id provide by your OIDC provider * **oidc-relying-party-secret-id**: The secret id provide by your OIDC provider And optionally: * **oidc-scope**: Specify what access privileges are being requested for Access Tokens. `cf Requesting claims using scope values <https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims`_. a list of claims using coma separator. (default value: `openid,email`) * **oidc-userinfo-field**: Specify which field to use from the response of the OIDC provider `userinfo endpoint <https://openid.net/specs/ openid-connect-core-1_0.html#UserInfoResponse>`_. To make sure it's a known user. (default value: `email`). """ client = Client(client_authn_method=CLIENT_AUTHN_METHOD) for config in [ "oidc_provider_issuer", "oidc_relying_party_client_id", "oidc_relying_party_secret_id", "oidc_relying_party_callback", ]: if Configuration.get(config, None) is None: raise ValueError("You must provide {} parameter".format(config)) provider_info = client.provider_config( Configuration.get("oidc_provider_issuer")) info = { "client_id": Configuration.get("oidc_relying_party_client_id"), "client_secret": Configuration.get("oidc_relying_party_secret_id"), "redirect_uris": [Configuration.get("oidc_relying_party_callback")], } info.update(provider_info._dict) client_reg = RegistrationResponse(**info) client.store_registration_info(client_reg) return client
def test_full_flow(self, context, frontend_with_extra_scopes): redirect_uri = "https://client.example.com/redirect" response_type = "code id_token token" mock_callback = Mock() frontend_with_extra_scopes.auth_req_callback_func = mock_callback # discovery http_response = frontend_with_extra_scopes.provider_config(context) provider_config = ProviderConfigurationResponse().deserialize(http_response.message, "json") # client registration registration_request = RegistrationRequest(redirect_uris=[redirect_uri], response_types=[response_type]) context.request = registration_request.to_dict() http_response = frontend_with_extra_scopes.client_registration(context) registration_response = RegistrationResponse().deserialize(http_response.message, "json") # authentication request authn_req = AuthorizationRequest( redirect_uri=redirect_uri, client_id=registration_response["client_id"], response_type=response_type, scope="openid email eduperson", state="state", nonce="nonce", ) context.request = dict(parse_qsl(authn_req.to_urlencoded())) frontend_with_extra_scopes.handle_authn_request(context) assert mock_callback.call_count == 1 # fake authentication response from backend internal_response = self.setup_for_authn_response( context, frontend_with_extra_scopes, authn_req ) http_response = frontend_with_extra_scopes.handle_authn_response( context, internal_response ) authn_resp = AuthorizationResponse().deserialize(urlparse(http_response.message).fragment, "urlencoded") assert "code" in authn_resp assert "access_token" in authn_resp assert "id_token" in authn_resp # token request context.request = AccessTokenRequest(redirect_uri=authn_req["redirect_uri"], code=authn_resp["code"]).to_dict() credentials = "{}:{}".format(registration_response["client_id"], registration_response["client_secret"]) basic_auth = urlsafe_b64encode(credentials.encode("utf-8")).decode("utf-8") context.request_authorization = "Basic {}".format(basic_auth) http_response = frontend_with_extra_scopes.token_endpoint(context) parsed = AccessTokenResponse().deserialize(http_response.message, "json") assert "access_token" in parsed assert "id_token" in parsed # userinfo request context.request = {} context.request_authorization = "Bearer {}".format(parsed["access_token"]) http_response = frontend_with_extra_scopes.userinfo_endpoint(context) parsed = OpenIDSchema().deserialize(http_response.message, "json") assert "email" in parsed assert "eduperson_principal_name" in parsed assert "eduperson_scoped_affiliation" in parsed
def oidc_client(webserver, oidc_provider, reverse): client = Client(client_authn_method=CLIENT_AUTHN_METHOD) client.provider_config(issuer=reverse("openid")) client.store_registration_info( RegistrationResponse(client_id=oidc_provider.client_id, client_secret=oidc_provider.client_secret)) return client
def registration_endpoint(self, data): try: req = self.parse_registration_request(data, "json") except ValueError: req = self.parse_registration_request(data) client_secret = rndstr() expires = utc_time_sans_frac() + self.registration_expires_in kwargs = {} if "client_id" not in req: client_id = rndstr(10) registration_access_token = rndstr(20) _client_info = req.to_dict() kwargs.update(_client_info) _client_info.update({ "client_secret": client_secret, "info": req.to_dict(), "expires": expires, "registration_access_token": registration_access_token, "registration_client_uri": "register_endpoint" }) self.client[client_id] = _client_info kwargs["registration_access_token"] = registration_access_token kwargs["registration_client_uri"] = "register_endpoint" try: del kwargs["operation"] except KeyError: pass else: client_id = req.client_id _cinfo = self.client[req.client_id] _cinfo["info"].update(req.to_dict()) _cinfo["client_secret"] = client_secret _cinfo["expires"] = expires resp = RegistrationResponse(client_id=client_id, client_secret=client_secret, client_secret_expires_at=expires, **kwargs) response = Response() response.headers = {"content-type": "application/json"} response.text = resp.to_json() return response
def test_registration_endpoint(self): req = RegistrationRequest() req["application_type"] = "web" req["client_name"] = "My super service" req["redirect_uris"] = ["http://example.com/authz"] req["contacts"] = ["*****@*****.**"] req["response_types"] = ["code"] resp = self.provider.registration_endpoint(request=req.to_json()) regresp = RegistrationResponse().deserialize(resp.message, "json") assert _eq(regresp.keys(), [ 'redirect_uris', 'contacts', 'application_type', 'client_name', 'registration_client_uri', 'client_secret_expires_at', 'registration_access_token', 'client_id', 'client_secret', 'client_id_issued_at', 'response_types' ])
def handle_registration_info(self, response): if response.status_code == 200: resp = RegistrationResponse().deserialize(response.text, "json") self.store_registration_info(resp) else: err = ErrorResponse().deserialize(response.text, "json") raise PyoidcError("Registration failed: %s" % err.get_json()) return resp
def test_complete_auth_token_idtoken(self): _state = "state0" self.consumer.consumer_config["response_type"] = ["id_token", "token"] self.consumer.registration_response = RegistrationResponse( id_token_signed_response_alg="HS256") self.consumer.authz_req = {} # Store AuthzReq with state as key args = { "client_id": self.consumer.client_id, "response_type": self.consumer.consumer_config["response_type"], "scope": ["openid"], "nonce": "nonce", } token = IdToken( iss="https://example.com", aud="client_1", sub="some_sub", exp=1565348600, iat=1565348300, nonce="nonce", ) location = ( "https://example.com/cb?state=state0&access_token=token&token_type=bearer&" "scope=openid&id_token={}".format( token.to_jwt(key=[SYMKey(key="hemlig")], algorithm="HS256"))) with responses.RequestsMock() as rsps: rsps.add( responses.GET, "https://example.com/authorization", status=302, headers={"location": location}, ) result = self.consumer.do_authorization_request(state=_state, request_args=args) query = parse_qs(urlparse(result.request.url).query) assert query["client_id"] == ["client_1"] assert query["scope"] == ["openid"] assert query["response_type"] == ["id_token token"] assert query["state"] == ["state0"] assert query["nonce"] == ["nonce"] assert query["redirect_uri"] == ["https://example.com/cb"] parsed = urlparse(result.headers["location"]) with freeze_time("2019-08-09 11:00:00"): part = self.consumer.parse_authz(query=parsed.query) assert isinstance(part, tuple) auth = part[0] atr = part[1] idt = part[2] assert auth is None assert isinstance(atr, AccessTokenResponse) assert _eq( atr.keys(), ["access_token", "id_token", "token_type", "state", "scope"]) assert isinstance(idt, IdToken)
def run(self): if self.dynamic: self.catch_exception_and_error(self.conv.entity.register, **self.req_args) else: self.conv.events.store(EV_NOOP, "Dynamic registration") self.conv.entity.store_registration_info( RegistrationResponse( **self.conv.entity_config["registration_response"]))
def _store_registration_info(self, client_metadata): registration_response = RegistrationResponse(**client_metadata) self._client.store_registration_info(registration_response) self._client_extension.store_registration_info(registration_response) # Set client_id and client_secret for _oauth2_client. This is used # by Client Credentials Flow. self._oauth2_client.client_id = registration_response['client_id'] self._oauth2_client.client_secret = registration_response[ 'client_secret']
def prepare_client(): # http://pyoidc.readthedocs.io/en/latest/examples/rp.html # Instantiate a client client = Client(client_authn_method=CLIENT_AUTHN_METHOD) # Register the OP # endpoints are now loaded from a json file rather than defined here # DEV endpoints # issuer = "https://unity.eudat-aai.fz-juelich.de:443" # authorization_endpoint = "https://unity.eudat-aai.fz-juelich.de:443/oauth2-as/oauth2-authz" # token_endpoint = "https://unity.eudat-aai.fz-juelich.de:443/oauth2/token" # userinfo_endpoint = "https://unity.eudat-aai.fz-juelich.de:443/oauth2/userinfo" # PROD endpoints # issuer = "https://b2access.eudat.eu:443" # authorization_endpoint = "https://b2access.eudat.eu:443/oauth2-as/oauth2-authz" # token_endpoint = "https://b2access.eudat.eu:443/oauth2/token" # userinfo_endpoint = "https://b2access.eudat.eu:443/oauth2/userinfo" try: dir = os.path.dirname(__file__) provider_endpoints = json.load(open(dir + '/provider_endpoints.json')) issuer = provider_endpoints['issuer'] authorization_endpoint = provider_endpoints['authorization_endpoint'] token_endpoint = provider_endpoints['token_endpoint'] userinfo_endpoint = provider_endpoints['userinfo_endpoint'] except: print "Error when reading provider_endpoints.json" stdlogger.error("Error when reading provider_endpoints.json") issuer = "error" authorization_endpoint = "error" token_endpoint = "error" userinfo_endpoint = "error" op_info = ProviderConfigurationResponse(issuer=issuer, authorization_endpoint=authorization_endpoint, token_endpoint=token_endpoint, userinfo_endpoint=userinfo_endpoint) client.provider_info = op_info # Set our credentials (that we got from manually registering to B2Access), as well as the redirect URI try: dir = os.path.dirname(__file__) client_credentials = json.load(open(dir + '/client_credentials.json')) id = client_credentials['client_id'] secret = client_credentials['client_secret'] uri = client_credentials['client_redirect_uri'] except: print "Error when reading client_credential.json" stdlogger.error("Error when reading client_credential.json") id = "error" secret = "error" uri = "error" # /!\ Added the redirect URI here, else it's not defined later (in args ={[...] client.registration_response["redirect_uris"][0]) uris = [uri] info = {"client_id": id, "client_secret": secret, "redirect_uris": uris} client_reg = RegistrationResponse(**info) client.store_registration_info(client_reg) return client
def test_registered_redirect_uri_with_query_component(): provider2 = Provider("FOOP", {}, {}, None, None) environ = {} rr = RegistrationRequest(operation="register", redirect_uris=["http://example.org/cb?foo=bar"]) registration_req = rr.to_urlencoded() resp = provider2.registration_endpoint(environ, start_response, query=registration_req) regresp = RegistrationResponse().from_json(resp[0]) print regresp.to_dict() faulty = [ "http://example.org/cb", "http://example.org/cb/foo", "http://example.org/cb?got=you", "http://example.org/cb?foo=you" ] correct = [ "http://example.org/cb?foo=bar", "http://example.org/cb?foo=bar&got=you", "http://example.org/cb?foo=bar&foo=you" ] for ruri in faulty: areq = AuthorizationRequest(redirect_uri=ruri, client_id=regresp["client_id"], scope="openid", response_type="code") print areq assert provider2._verify_redirect_uri(areq) != None for ruri in correct: areq = AuthorizationRequest(redirect_uri= ruri, client_id=regresp["client_id"]) resp = provider2._verify_redirect_uri(areq) print resp assert resp == None
def oidc_callback(): # Instantiate again the client client = Client(client_authn_method=CLIENT_AUTHN_METHOD) info = {"client_id": CLIENT_ID, "client_secret": CLIENT_SECRET} client_reg = RegistrationResponse(**info) client.store_registration_info(client_reg) args = { "client_id": client.client_id, "response_type": "code", "scope": ["openid"], "redirect_uri": OIDC_REDIRECT_URI, } auth_req = client.construct_AuthorizationRequest(request_args=args) client.provider_config(OIDC_INFO_URL) # Posted information query_string = request.url auth_response = client.parse_response(AuthorizationResponse, info=query_string, sformat="urlencoded") # We need to find a state/nonce pair that matches what we have nonce = current_app.cache.get(auth_response['state']) current_app.cache.delete(auth_response['state']) if "id_token" in auth_response and auth_response["id_token"][ "nonce"] != nonce: return make_response('', 500) # Request an access token an use it to require the user's information args = {"code": auth_response["code"]} client.do_access_token_request(state=auth_response["state"], request_args=args, authn_method="client_secret_basic") # This is the object with the user info user_info = client.do_user_info_request(state=auth_response["state"]) # Take the mail depending on the attribute they have saved it in mail = user_info[u'mail'] if not mail: mail = user_info[u'email'] # Validate that the user mail is in the DB user = User.query.filter_by(email=mail).first() if user is None: return make_response('Unauthorized user', 401) # Login the user and return login_user(user, remember=True) return redirect(url_for('welcome'))
def _build_oidc_client(self): client = Client(client_authn_method=CLIENT_AUTHN_METHOD) provider_config = ProviderConfigurationResponse( **self.settings["oidc"]["provider"]["configuration"]) client.handle_provider_config(provider_config, provider_config["issuer"]) client.store_registration_info( RegistrationResponse( **self.settings["oidc"]["provider"]["registration"])) return client
def create_oidc_client(issuer=None, registration_info=None): if "oidc" not in g: g.oidc = Client(client_authn_method=CLIENT_AUTHN_METHOD) config = get(f"{issuer}/.well-known/openid-configuration", headers={"Content-type": "application/json"}).json() provider_config = ProviderConfigurationResponse(**config) g.oidc.handle_provider_config(provider_config, issuer) g.oidc.store_registration_info( RegistrationResponse(**registration_info) ) g.oidc.redirect_uris.append(f"{g.oidc.registration_response['redirect_uris'][0]}/callback") return g.oidc
def init_client_for_shortcut(openid_client_obj): client = Client(client_authn_method=CLIENT_AUTHN_METHOD) reg_info = { 'client_id': openid_client_obj.client_id, 'client_secret': openid_client_obj.client_secret, 'redirect_uris': [settings.REDIRECT_URI], } client_reg = RegistrationResponse(**reg_info) client.store_registration_info(client_reg) client.provider_config(openid_client_obj.issuer) return client
def test_register_client(self, context, frontend): redirect_uri = "https://client.example.com" registration_request = RegistrationRequest(redirect_uris=[redirect_uri], response_types=["id_token"]) context.request = registration_request.to_dict() registration_response = frontend.client_registration(context) assert registration_response.status == "201 Created" reg_resp = RegistrationResponse().deserialize(registration_response.message, "json") assert "client_id" in reg_resp assert reg_resp["redirect_uris"] == [redirect_uri] assert reg_resp["response_types"] == ["id_token"]
def test_registration_endpoint(self): req = RegistrationRequest() req["application_type"] = "web" req["client_name"] = "My super service" req["redirect_uris"] = ["http://example.com/authz"] req["contacts"] = ["*****@*****.**"] req["response_types"] = ["code"] print req.to_dict() resp = self.server.registration_endpoint(request=req.to_json()) print resp.message regresp = RegistrationResponse().deserialize(resp.message, "json") print regresp.keys() assert _eq(regresp.keys(), ['redirect_uris', 'contacts', 'application_type', 'client_name', 'registration_client_uri', 'client_secret_expires_at', 'registration_access_token', 'client_id', 'client_secret', 'client_id_issued_at', 'response_types'])
def test_registration_endpoint(): server = provider_init req = RegistrationRequest(operation="register") req["application_type"] = "web" req["client_name"] = "My super service" req["redirect_uris"] = ["http://example.com/authz"] req["contacts"] = ["*****@*****.**"] environ = BASE_ENVIRON.copy() environ["QUERY_STRING"] = req.to_urlencoded() resp = server.registration_endpoint(environ, start_response) print resp regresp = RegistrationResponse().deserialize(resp[0], "json") print regresp.keys() assert _eq(regresp.keys(), ['redirect_uris', 'application_type', 'expires_at', 'registration_access_token', 'client_id', 'client_secret', 'client_name', "contacts"]) # --- UPDATE ---- req = RegistrationRequest(operation="client_update") req["application_type"] = "web" req["client_name"] = "My super duper service" req["redirect_uris"] = ["http://example.com/authz"] req["contacts"] = ["*****@*****.**"] environ = BASE_ENVIRON.copy() environ["QUERY_STRING"] = req.to_urlencoded() environ["HTTP_AUTHORIZATION"] = "Bearer %s" % regresp["registration_access_token"] resp = server.registration_endpoint(environ, start_response) print resp update = RegistrationResponse().deserialize(resp[0], "json") print update.keys() assert _eq(update.keys(), ['redirect_uris', 'application_type', 'expires_at', 'registration_access_token', 'client_id', 'client_secret', 'client_name', 'contacts'])
"client_id_issued_at": utc_time_sans_frac()} self.cdb[_rat] = client_id _cinfo = self.do_client_registration(request, client_id, ignore=["redirect_uris", "policy_url", "logo_url"]) if isinstance(_cinfo, Response): return _cinfo args = dict([(k, v) for k, v in _cinfo.items() if k in RegistrationResponse.c_param]) self.comb_redirect_uris(args) response = RegistrationResponse(**args) self.keyjar.load_keys(request, client_id) # Add the key to the keyjar if client_secret: _kc = KeyBundle([{"kty": "oct", "key": client_secret, "use": "ver"}, {"kty": "oct", "key": client_secret, "use": "sig"}]) try: _keyjar[client_id].append(_kc) except KeyError: _keyjar[client_id] = [_kc] self.cdb[client_id] = _cinfo