def test_verify(self): query = ( "redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fauthz" "&response_type=code&client_id=0123456789" ) ar = AuthorizationRequest().deserialize(query, "urlencoded") assert ar.verify()
def test_access_token_srv_conf(): client_config = { 'client_id': 'client_id', 'client_secret': 'a longesh password', 'redirect_uris': ['https://example.com/cli/authz_cb'] } service_context = ServiceContext(config=client_config) db = InMemoryStateDataBase() auth_request = AuthorizationRequest( redirect_uri='https://example.com/cli/authz_cb', state='state') auth_response = AuthorizationResponse(code='access_code') _state = State(auth_request=auth_request.to_json(), auth_response=auth_response.to_json()) db.set('state', _state.to_json()) service = service_factory( 'AccessToken', ['oauth2'], state_db=db, service_context=service_context, conf={'default_authn_method': 'client_secret_post'}) req_args = { 'redirect_uri': 'https://example.com/cli/authz_cb', 'code': 'access_code' } service.endpoint = 'https://example.com/authorize' _info = service.get_request_parameters(request_args=req_args, state='state') assert _info msg = AccessTokenRequest().from_urlencoded( service.get_urlinfo(_info['body'])) assert 'client_secret' in msg
def test_deserialize_urlencoded(self): ar = AuthorizationRequest(response_type=["code"], client_id="foobar") urlencoded = ar.to_urlencoded() ar2 = AuthorizationRequest().deserialize(urlencoded, "urlencoded") assert ar == ar2
def test_json_serialize_deserialize(self): ar = AuthorizationRequest(response_type=["code"], client_id="foobar") jtxt = ar.serialize(method="json") ar2 = AuthorizationRequest().deserialize(jtxt, "json") assert ar == ar2
def test_pushed_auth_urlencoded(self): # since all endpoint used the same endpoint_context I can grab anyone _op_context = self.registration_endpoint.server_get("endpoint_context") # This is cheating. Getting the OP's provider info _fe = self.registration_service.client_get("service_context").federation_entity trust_chain = TrustChain() trust_chain.metadata = _op_context.provider_info trust_chain.anchor = "https://feide.no" trust_chain.verified_chain = [{'iss': "https://ntnu.no"}] self.discovery_service.update_service_context([trust_chain]) # and the OP's federation keys _op_context.federation_entity.context.keyjar.import_jwks( read_info(os.path.join(ROOT_DIR, 'op.ntnu.no'), 'op.ntnu.no', 'jwks'), issuer_id=_op_context.provider_info['issuer']) # Add RP's OIDC keys to the OP's keyjar. _op_context.keyjar.import_jwks( self.discovery_service.client_get("service_context").keyjar.export_jwks(issuer_id=""), RP_ENTITY_ID ) authn_request = AuthorizationRequest( response_type="code", state="af0ifjsldkj", client_id=RP_ENTITY_ID, redirect_uri="{}/callback".format(RP_ENTITY_ID), code_challenge="K2-ltc83acc4h0c9w6ESC_rEMTJ3bww-uCHaoeK1t8U", code_challenge_method="S256", scope=["ais", "openid"] ) # Create the private_key_jwt assertion _jwt = JWT(self.registration_service.client_get("service_context").keyjar, iss=RP_ENTITY_ID, sign_alg="RS256") _jwt.with_jti = True _assertion = _jwt.pack( { "aud": [_op_context.provider_info["pushed_authorization_request_endpoint"]] }) authn_request.update({"client_assertion": _assertion, "client_assertion_type": JWT_BEARER}) _req = self.pushed_authorization_endpoint.parse_request(authn_request) assert isinstance(_req, AuthorizationRequest) assert set(_req.keys()) == { "state", "redirect_uri", "response_type", "scope", "code_challenge_method", "client_id", "code_challenge", "client_assertion", "client_assertion_type", '__verified_client_assertion' } # Should have a registered client now assert set(_op_context.cdb.keys()) == {RP_ENTITY_ID}
def authorization(self, request, **kwargs): areq = AuthorizationRequest().from_urlencoded(request) if not areq.verify(): raise OidcMsgError('Verification failed') resp = HTTPResponse('OK') return resp
def test_request_init(self): req_args = {'response_type': 'code', 'state': 'state'} self.service.endpoint = 'https://example.com/authorize' _info = self.service.get_request_parameters(request_args=req_args) assert set(_info.keys()) == {'url', 'method'} msg = AuthorizationRequest().from_urlencoded( self.service.get_urlinfo(_info['url'])) assert set(msg.keys()) == {'client_id', 'scope', 'response_type', 'state', 'redirect_uri', 'nonce'}
def test_deserialize_urlencoded_multiple_params(self): ar = AuthorizationRequest(response_type=["code"], client_id="foobar", redirect_uri="http://foobar.example.com/oaclient", scope=["foo", "bar"], state="cold") urlencoded = ar.to_urlencoded() ar2 = AuthorizationRequest().deserialize(urlencoded, "urlencoded") assert ar == ar2
def test_req_json_serialize(self): ar = AuthorizationRequest(response_type=["code"], client_id="foobar") js_obj = json.loads(ar.serialize(method="json")) expected_js_obj = { "response_type": "code", "client_id": "foobar" } assert js_obj == expected_js_obj
def test_urlencoded_with_scope(self): ar = AuthorizationRequest(response_type=["code"], client_id="foobar", redirect_uri="http://foobar.example.com/oaclient", scope=["foo", "bar"], state="cold") ue = ar.to_urlencoded() assert query_string_compare(ue, "scope=foo+bar&state=cold&redirect_uri=http%3A%2F%2Ffoobar" ".example.com%2Foaclient&" "response_type=code&client_id=foobar")
def test_urlencoded_resp_type_token(self): ar = AuthorizationRequest(response_type=["token"], client_id="s6BhdRkqt3", redirect_uri="https://client.example.com/cb", state="xyz") ue = ar.to_urlencoded() assert query_string_compare(ue, "state=xyz&redirect_uri=https%3A%2F%2Fclient.example.com%2Fcb" "&response_type=token&" "client_id=s6BhdRkqt3")
def test_json_multiple_params(self): ar = AuthorizationRequest(response_type=["code"], client_id="foobar", redirect_uri="http://foobar.example.com/oaclient", state="cold") ue_obj = json.loads(ar.serialize(method="json")) expected_ue_obj = { "response_type": "code", "state": "cold", "redirect_uri": "http://foobar.example.com/oaclient", "client_id": "foobar" } assert ue_obj == expected_ue_obj
def test_get_request_parameters(self): req_args = {'response_type': 'code'} self.auth_service.endpoint = 'https://example.com/authorize' _info = self.auth_service.get_request_parameters(request_args=req_args, state='state') assert set(_info.keys()) == {'url', 'method', 'request'} msg = AuthorizationRequest().from_urlencoded( self.auth_service.get_urlinfo(_info['url'])) assert msg.to_dict() == { 'client_id': 'client_id', 'redirect_uri': 'https://example.com/cli/authz_cb', 'response_type': 'code', 'state': 'state' }
def test_json_resp_type_token(self): ar = AuthorizationRequest(response_type=["token"], client_id="s6BhdRkqt3", redirect_uri="https://client.example.com/cb", state="xyz") ue_obj = json.loads(ar.serialize(method="json")) expected_ue_obj = { "state": "xyz", "redirect_uri": "https://client.example.com/cb", "response_type": "token", "client_id": "s6BhdRkqt3" } assert ue_obj == expected_ue_obj
def test_construct_refresh_token_request(self): self.client.session_interface.create_state('issuer', 'ABCDE') auth_request = AuthorizationRequest( redirect_uri='https://example.com/cli/authz_cb', state='state') self.client.session_interface.store_item(auth_request, 'auth_request', 'ABCDE') auth_response = AuthorizationResponse(code='access_code') self.client.session_interface.store_item(auth_response, 'auth_response', 'ABCDE') token_response = AccessTokenResponse(refresh_token="refresh_with_me", access_token="access") self.client.session_interface.store_item(token_response, 'token_response', 'ABCDE') req_args = {} msg = self.client.service['refresh_token'].construct( request_args=req_args, state='ABCDE') assert isinstance(msg, RefreshAccessTokenRequest) assert msg.to_dict() == { 'client_id': 'client_1', 'client_secret': 'abcdefghijklmnop', 'grant_type': 'refresh_token', 'refresh_token': 'refresh_with_me' }
def test_construct_accesstoken_request(self): # Client 1 starts the chain of event client_1 = Client(config=CONF) _context_1 = client_1.client_get("service_context") _state = _context_1.state.create_state('issuer') auth_request = AuthorizationRequest( redirect_uri='https://example.com/cli/authz_cb', state=_state) _context_1.state.store_item(auth_request, 'auth_request', _state) # Client 2 carries on client_2 = Client(config=CONF) _state_dump = _context_1.dump() _context2 = client_2.client_get("service_context") _context2.load(_state_dump) auth_response = AuthorizationResponse(code='access_code') _context2.state.store_item(auth_response, 'auth_response', _state) msg = client_2.client_get("service", 'accesstoken').construct(request_args={}, state=_state) assert isinstance(msg, AccessTokenRequest) assert msg.to_dict() == { 'client_id': 'client_1', 'code': 'access_code', 'client_secret': 'abcdefghijklmnop', 'grant_type': 'authorization_code', 'redirect_uri': 'https://example.com/cli/authz_cb', 'state': _state }
def authn_verify(self, url_endpoint, **kwargs): """ Authentication verification :param authn_method: Which authn method that was used :param kwargs: response arguments :return: HTTP redirect """ authn_method = self.endpoint_context.endpoint_to_authn_method[ url_endpoint] username = authn_method.verify(**kwargs) if not username: cherrypy.HTTPError(403, message='Authentication failed') auth_args = authn_method.unpack_token(kwargs['token']) request = AuthorizationRequest().from_urlencoded(auth_args['query']) authn_event = AuthnEvent(uid=username, salt='salt', authn_info=auth_args['authn_class_ref'], authn_time=auth_args['iat']) endpoint = self.endpoint_context.endpoint['authorization'] args = endpoint.post_authentication(request, user=username, sid=request['state'], authn_event=authn_event) return self.do_response(endpoint, request, **args)
def authn_verify(self, url_endpoint, **kwargs): """ Authentication verification :param url_endpoint: Which endpoint to use :param kwargs: response arguments :return: HTTP redirect """ authn_method = self.endpoint_context.endpoint_to_authn_method[ url_endpoint] username = authn_method.verify(**kwargs) if not username: raise cherrypy.HTTPError(403, message='Authentication failed') auth_args = authn_method.unpack_token(kwargs['token']) request = AuthorizationRequest().from_urlencoded(auth_args['query']) authn_event = create_authn_event( uid=username, salt='salt', authn_info=auth_args['authn_class_ref'], authn_time=auth_args['iat']) endpoint = self.endpoint_context.endpoint['authorization'] args = endpoint.authz_part2(user=username, request=request, authn_event=authn_event) if isinstance(args, ResponseMessage): raise cherrypy.HTTPError(400, message=args.to_json()) return do_response(endpoint, request, **args)
def test_urlencoded_deserialize_state(self): txt = "scope=foo+bar&state=-11&redirect_uri=http%3A%2F%2Ffoobar" \ ".example.com%2Foaclient&response_type=code&" \ "client_id=foobar" ar = AuthorizationRequest().deserialize(txt, "urlencoded") assert ar["state"] == "-11"
def test_setup_auth_session_revoked(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) redirect_uri = request["redirect_uri"] cinfo = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "RS256", } _ec = self.endpoint.endpoint_context _ec.sdb["session_id"] = SessionInfo( authn_req=request, uid="diana", sub="abcdefghijkl", authn_event={ "authn_info": "loa1", "uid": "diana", "authn_time": utc_time_sans_frac(), }, revoked=True, ) item = _ec.authn_broker.db["anon"] item["method"].user = b64e( as_bytes(json.dumps({"uid": "krall", "sid": "session_id"})) ) res = self.endpoint.setup_auth(request, redirect_uri, cinfo, None) assert set(res.keys()) == {"args", "function"}
def test_setup_auth_error(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) redirect_uri = request["redirect_uri"] cinfo = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "RS256", } item = self.endpoint.endpoint_context.authn_broker.db["anon"] item["method"].fail = NoSuchAuthentication res = self.endpoint.setup_auth(request, redirect_uri, cinfo, None) assert set(res.keys()) == {"function", "args"} item["method"].fail = ToOld res = self.endpoint.setup_auth(request, redirect_uri, cinfo, None) assert set(res.keys()) == {"function", "args"} item["method"].file = ""
def test_construct_accesstoken_request(self): _context = self.client.client_get("service_context") auth_request = AuthorizationRequest( redirect_uri='https://example.com/cli/authz_cb') _state = _context.state.create_state('issuer') auth_request["state"] = _state _context.state.store_item(auth_request, 'auth_request', _state) auth_response = AuthorizationResponse(code='access_code') _context.state.store_item(auth_response, 'auth_response', _state) # Bind access code to state req_args = {} msg = self.client.client_get("service", 'accesstoken').construct( request_args=req_args, state=_state) assert isinstance(msg, AccessTokenRequest) assert msg.to_dict() == { 'client_id': 'client_1', 'client_secret': 'abcdefghijklmnop', 'grant_type': 'authorization_code', 'state': _state, 'code': 'access_code', 'redirect_uri': 'https://example.com/cli/authz_cb' }
def test_construct_accesstoken_request(self): # Client 1 starts client_1 = RP(config=CONF) _state = client_1.client_get("service_context").state.create_state( ISSUER) auth_request = AuthorizationRequest( redirect_uri='https://example.com/cli/authz_cb', state=_state) client_1.client_get("service_context").state.store_item( auth_request, 'auth_request', _state) # Client 2 carries on client_2 = RP(config=CONF) _state_dump = client_1.client_get("service_context").dump() client_2.client_get("service_context").load(_state_dump) auth_response = AuthorizationResponse(code='access_code') client_2.client_get("service_context").state.store_item( auth_response, 'auth_response', _state) # Bind access code to state req_args = {} msg = client_2.client_get("service", 'accesstoken').construct( request_args=req_args, state=_state) assert isinstance(msg, AccessTokenRequest) assert msg.to_dict() == { 'client_id': 'client_1', 'code': 'access_code', 'client_secret': 'abcdefghijklmnop', 'grant_type': 'authorization_code', 'redirect_uri': 'https://example.com/cli/authz_cb', 'state': _state }
def test_do_userinfo_request_init(self): # Client 1 starts client_1 = RP(config=CONF) _state = client_1.client_get("service_context").state.create_state( ISSUER) auth_request = AuthorizationRequest( redirect_uri='https://example.com/cli/authz_cb', state='state') # Client 2 carries on client_2 = RP(config=CONF) _state_dump = client_1.client_get("service_context").dump() client_2.client_get("service_context").load(_state_dump) auth_response = AuthorizationResponse(code='access_code') client_2.client_get("service_context").state.store_item( auth_response, 'auth_response', _state) token_response = AccessTokenResponse(refresh_token="refresh_with_me", access_token="access") client_2.client_get("service_context").state.store_item( token_response, 'token_response', _state) # Back to Client 1 _state_dump = client_2.client_get("service_context").dump() client_1.client_get("service_context").load(_state_dump) _srv = client_1.client_get("service", 'userinfo') _srv.endpoint = "https://example.com/userinfo" _info = _srv.get_request_parameters(state=_state) assert _info assert _info['headers'] == {'Authorization': 'Bearer access'} assert _info['url'] == 'https://example.com/userinfo'
def test_do_userinfo_request_init(self): self.client.session_interface.create_state('issuer', 'ABCDE') auth_request = AuthorizationRequest( redirect_uri='https://example.com/cli/authz_cb', state='state' ) self.client.session_interface.store_item(auth_request, 'auth_request', 'ABCDE') auth_response = AuthorizationResponse(code='access_code') self.client.session_interface.store_item(auth_response, 'auth_response', 'ABCDE') token_response = AccessTokenResponse(refresh_token="refresh_with_me", access_token="access") self.client.session_interface.store_item(token_response, 'token_response', 'ABCDE') _srv = self.client.service['userinfo'] _srv.endpoint = "https://example.com/userinfo" _info = _srv.get_request_parameters(state='ABCDE') assert _info assert _info['headers'] == {'Authorization': 'Bearer access'} assert _info['url'] == 'https://example.com/userinfo'
def test_access_token_srv_conf(): client_config = { 'client_id': 'client_id', 'client_secret': 'a longesh password', 'redirect_uris': ['https://example.com/cli/authz_cb'] } service_context = ServiceContext(config=client_config) service = service_factory( 'AccessToken', ['oauth2'], service_context=service_context, conf={'default_authn_method': 'client_secret_post'}) auth_request = AuthorizationRequest( redirect_uri='https://example.com/cli/authz_cb', state='state') auth_response = AuthorizationResponse(code='access_code') service.store_item(auth_request, "auth_request", 'state') service.store_item(auth_response, "auth_response", 'state') req_args = { 'redirect_uri': 'https://example.com/cli/authz_cb', 'code': 'access_code' } service.endpoint = 'https://example.com/authorize' _info = service.get_request_parameters(request_args=req_args, state='state') assert _info msg = AccessTokenRequest().from_urlencoded( service.get_urlinfo(_info['body'])) assert 'client_secret' in msg
def test_construct_accesstoken_request(self): # Bind access code to state req_args = {} self.client.session_interface.create_state('issuer', 'ABCDE') auth_request = AuthorizationRequest( redirect_uri='https://example.com/cli/authz_cb', state='ABCDE') self.client.session_interface.store_item(auth_request, 'auth_request', 'ABCDE') auth_response = AuthorizationResponse(code='access_code') self.client.session_interface.store_item(auth_response, 'auth_response', 'ABCDE') msg = self.client.service['accesstoken'].construct( request_args=req_args, state='ABCDE') assert isinstance(msg, AccessTokenRequest) assert msg.to_dict() == { 'client_id': 'client_1', 'code': 'access_code', 'client_secret': 'abcdefghijklmnop', 'grant_type': 'authorization_code', 'redirect_uri': 'https://example.com/cli/authz_cb', 'state': 'ABCDE' }
def test_create_authn_response(self): request = AuthorizationRequest( client_id="client_id", redirect_uri="https://rp.example.com/cb", response_type=["id_token"], state="state", nonce="nonce", scope="openid", ) _ec = self.endpoint.endpoint_context _ec.sdb["session_id"] = SessionInfo( authn_req=request, uid="diana", sub="abcdefghijkl", authn_event={ "authn_info": "loa1", "uid": "diana", "authn_time": utc_time_sans_frac(), }, ) _ec.cdb["client_id"] = { "client_id": "client_id", "redirect_uris": [("https://rp.example.com/cb", {})], "id_token_signed_response_alg": "ES256", } resp = create_authn_response(self.endpoint, request, "session_id") assert isinstance(resp["response_args"], AuthorizationErrorResponse)
def test_construct_with_token(self, services): authz_service = services['authorization'] _state = authz_service.create_state('Issuer') req = AuthorizationRequest(state=_state, response_type='code', redirect_uri='https://example.com', scope=['openid']) authz_service.store_item(req, 'auth_request', _state) # Add a state and bind a code to it resp1 = AuthorizationResponse(code="auth_grant", state=_state) response = services['authorization'].parse_response( resp1.to_urlencoded(), "urlencoded") services['authorization'].update_service_context(response, key=_state) # based on state find the code and then get an access token resp2 = AccessTokenResponse(access_token="token1", token_type="Bearer", expires_in=0, state=_state) response = services['accesstoken'].parse_response( resp2.to_urlencoded(), "urlencoded") services['accesstoken'].update_service_context(response, key=_state) # and finally use the access token, bound to a state, to # construct the authorization header http_args = BearerHeader().construct(ResourceRequest(), services['accesstoken'], key=_state) assert http_args == {"headers": {"Authorization": "Bearer token1"}}
def test_access_token_srv_conf(): client_config = { 'client_id': 'client_id', 'client_secret': 'a longesh password', 'redirect_uris': ['https://example.com/cli/authz_cb'] } entity = Entity(config=client_config) token_service = entity.client_get("service", 'accesstoken') _state_interface = token_service.client_get("service_context").state _state_val = _state_interface.create_state( token_service.client_get("service_context").issuer) auth_request = AuthorizationRequest( redirect_uri='https://example.com/cli/authz_cb', state=_state_val) _state_interface.store_item(auth_request, "auth_request", _state_val) auth_response = AuthorizationResponse(code='access_code') _state_interface.store_item(auth_response, "auth_response", _state_val) req_args = { 'redirect_uri': 'https://example.com/cli/authz_cb', 'code': 'access_code' } token_service.endpoint = 'https://example.com/authorize' _info = token_service.get_request_parameters(request_args=req_args, state=_state_val) assert _info msg = AccessTokenRequest().from_urlencoded(_info['body']) # client_secret_basic by default assert 'client_secret' not in msg