def test_token_endpoint_unauth(self): authreq = AuthorizationRequest(state="state", redirect_uri="http://example.com/authz", client_id="client1") _sdb = self.provider.sdb sid = _sdb.access_token.key(user="******", areq=authreq) access_grant = _sdb.access_token(sid=sid) _sdb[sid] = { "oauth_state": "authz", "sub": "sub", "authzreq": "", "client_id": "client1", "code": access_grant, "code_used": False, "redirect_uri": "http://example.com/authz" } # Construct Access token request areq = AccessTokenRequest(code=access_grant, redirect_uri="http://example.com/authz", client_id="client2", client_secret="hemlighet", grant_type='authorization_code') resp = self.provider.token_endpoint(request=areq.to_urlencoded()) atr = TokenErrorResponse().deserialize(resp.message, "json") assert _eq(atr.keys(), ['error_description', 'error'])
def test_token_endpoint_unauth(self): authreq = AuthorizationRequest(state="state", redirect_uri="http://example.com/authz", client_id="client1") _sdb = self.provider.sdb sid = _sdb.access_token.key(user="******", areq=authreq) access_grant = _sdb.access_token(sid=sid) _sdb[sid] = { "oauth_state": "authz", "sub": "sub", "authzreq": "", "client_id": "client1", "code": access_grant, "code_used": False, "redirect_uri": "http://example.com/authz" } # Construct Access token request areq = AccessTokenRequest(code=access_grant, redirect_uri="http://example.com/authz", client_id='<REDACTED>', client_secret="hemlighet", grant_type='authorization_code') resp = self.provider.token_endpoint(request=areq.to_urlencoded()) atr = TokenErrorResponse().deserialize(resp.message, "json") assert _eq(atr.keys(), ['error_description', 'error'])
def test_token_endpoint_unauth(): provider = Provider("pyoicserv", sdb.SessionDB(), CDB, AUTHN_BROKER, AUTHZ, verify_client, symkey=rndstr(16)) authreq = AuthorizationRequest(state="state", redirect_uri="http://example.com/authz", client_id="client1") _sdb = provider.sdb sid = _sdb.token.key(user="******", areq=authreq) access_grant = _sdb.token(sid=sid) _sdb[sid] = { "oauth_state": "authz", "user_id": "user_id", "authzreq": "", "client_id": "client1", "code": access_grant, "code_used": False, "redirect_uri": "http://example.com/authz" } # Construct Access token request areq = AccessTokenRequest(code=access_grant, redirect_uri="http://example.com/authz", client_id="client2", client_secret="hemlighet",) print areq.to_dict() resp = provider.token_endpoint(request=areq.to_urlencoded()) print resp.message atr = TokenErrorResponse().deserialize(resp.message, "json") print atr.keys() assert _eq(atr.keys(), ['error_description', 'error'])
def test_parse_authz_invalid_client(self): self.consumer.begin("http://localhost:8087", "http://localhost:8088/authorization") atr = TokenErrorResponse(error="invalid_client") with pytest.raises(AuthzError): self.consumer.handle_authorization_response( query=atr.to_urlencoded())
def token_endpoint(self, authn="", **kwargs): """ This is where clients come to get their access tokens """ _sdb = self.sdb logger.debug("- token -") body = kwargs["request"] logger.debug("body: %s" % sanitize(body)) areq = AccessTokenRequest().deserialize(body, "urlencoded") try: self.client_authn(self, areq, authn) except FailedAuthentication as err: logger.error(err) err = TokenErrorResponse(error="unauthorized_client", error_description="%s" % err) return Response(err.to_json(), content="application/json", status="401 Unauthorized") logger.debug("AccessTokenRequest: %s" % sanitize(areq)) try: assert areq["grant_type"] == "authorization_code" except AssertionError: err = TokenErrorResponse(error="invalid_request", error_description="Wrong grant type") return Response(err.to_json(), content="application/json", status="401 Unauthorized") # assert that the code is valid _info = _sdb[areq["code"]] resp = self.token_scope_check(areq, _info) if resp: return resp # If redirect_uri was in the initial authorization request # verify that the one given here is the correct one. if "redirect_uri" in _info: assert areq["redirect_uri"] == _info["redirect_uri"] try: _tinfo = _sdb.upgrade_to_token(areq["code"], issue_refresh=True) except AccessCodeUsed: err = TokenErrorResponse(error="invalid_grant", error_description="Access grant used") return Response(err.to_json(), content="application/json", status="401 Unauthorized") logger.debug("_tinfo: %s" % sanitize(_tinfo)) atr = AccessTokenResponse(**by_schema(AccessTokenResponse, **_tinfo)) logger.debug("AccessTokenResponse: %s" % sanitize(atr)) return Response(atr.to_json(), content="application/json")
def test_consumer_parse_authz_error_2(): _session_db = {} cons = Consumer(_session_db, client_config=CLIENT_CONFIG, server_info=SERVER_INFO, **CONSUMER_CONFIG) cons.debug = True _ = cons.begin("http://localhost:8087", "http://localhost:8088/authorization") atr = TokenErrorResponse(error="invalid_client") QUERY_STRING = atr.to_urlencoded() raises(AuthzError, "cons.handle_authorization_response(query=QUERY_STRING)")
def test_consumer_parse_authz_error_2(): _session_db = {} cons = Consumer(_session_db, client_config = CLIENT_CONFIG, server_info=SERVER_INFO, **CONSUMER_CONFIG) cons.debug = True environ = BASE_ENVIRON _ = cons.begin(environ, start_response) atr = TokenErrorResponse(error="invalid_client") environ = BASE_ENVIRON.copy() environ["QUERY_STRING"] = atr.to_urlencoded() raises(AuthzError, "cons.handle_authorization_response(environ, start_response)")
def test_code_grant_type_used(self): authreq = AuthorizationRequest(state="state", redirect_uri="http://example.com/authz", client_id='client1', response_type="code", scope=["openid"]) _sdb = self.provider.sdb sid = _sdb.access_token.key(user="******", areq=authreq) access_grant = _sdb.access_token(sid=sid) _sdb[sid] = { "oauth_state": "authz", "authn_event": '', "authzreq": '', "client_id": 'client1', "code": access_grant, "code_used": True, "scope": ["openid"], "redirect_uri": "http://example.com/authz", } # Construct Access token request areq = AccessTokenRequest(code=access_grant, client_id='client1', redirect_uri="http://example.com/authz", client_secret='hemlighet', grant_type='authorization_code') txt = areq.to_urlencoded() resp = self.provider.token_endpoint(request=txt) atr = TokenErrorResponse().deserialize(resp.message, "json") assert atr['error'] == "invalid_grant"
def test_token_endpoint_password(self): authreq = AuthorizationRequest(state="state", redirect_uri="http://example.com/authz", client_id="client1") _sdb = self.provider.sdb sid = _sdb.access_token.key(user="******", areq=authreq) access_grant = _sdb.access_token(sid=sid) _sdb[sid] = { "oauth_state": "authz", "sub": "sub", "authzreq": "", "client_id": "client1", "code": access_grant, "code_used": False, "redirect_uri": "http://example.com/authz", "token_endpoint_auth_method": "client_secret_basic", } areq = ROPCAccessTokenRequest(grant_type="password", username="******", password="******") authn = "Basic Y2xpZW50Mjp2ZXJ5c2VjcmV0=" resp = self.provider.token_endpoint(request=areq.to_urlencoded(), authn=authn) parsed = TokenErrorResponse().from_json(resp.message) assert parsed["error"] == "unsupported_grant_type"
def token_endpoint(self, authn="", **kwargs): """ This is where clients come to get their access tokens """ _sdb = self.sdb logger.debug("- token -") body = kwargs["request"] logger.debug("body: %s" % sanitize(body)) areq = AccessTokenRequest().deserialize(body, "urlencoded") try: self.client_authn(self, areq, authn) except FailedAuthentication as err: logger.error(err) err = TokenErrorResponse(error="unauthorized_client", error_description="%s" % err) return Response(err.to_json(), content="application/json", status_code=401) logger.debug("AccessTokenRequest: %s" % sanitize(areq)) if areq["grant_type"] != "authorization_code": err = TokenErrorResponse(error="invalid_request", error_description="Wrong grant type") return Response(err.to_json(), content="application/json", status="401 Unauthorized") # assert that the code is valid _info = _sdb[areq["code"]] resp = self.token_scope_check(areq, _info) if resp: return resp # If redirect_uri was in the initial authorization request # verify that the one given here is the correct one. if "redirect_uri" in _info and areq["redirect_uri"] != _info["redirect_uri"]: logger.error('Redirect_uri mismatch') err = TokenErrorResponse(error="unauthorized_client") return Unauthorized(err.to_json(), content="application/json") try: _tinfo = _sdb.upgrade_to_token(areq["code"], issue_refresh=True) except AccessCodeUsed: err = TokenErrorResponse(error="invalid_grant", error_description="Access grant used") return Response(err.to_json(), content="application/json", status="401 Unauthorized") logger.debug("_tinfo: %s" % sanitize(_tinfo)) atr = AccessTokenResponse(**by_schema(AccessTokenResponse, **_tinfo)) logger.debug("AccessTokenResponse: %s" % sanitize(atr)) return Response(atr.to_json(), content="application/json", headers=OAUTH2_NOCACHE_HEADERS)
def test_extra_params(self): ter = TokenErrorResponse(error="access_denied", error_description="brewers has a four game series", foo="bar") assert ter["error"] == "access_denied" assert ter["error_description"] == "brewers has a four game series" assert ter["foo"] == "bar"
def token_endpoint(self, environ, start_response): """ This is where clients come to get their access tokens """ _sdb = self.sdb LOG_DEBUG("- token -") body = get_post(environ) LOG_DEBUG("body: %s" % body) areq = AccessTokenRequest().deserialize(body, "urlencoded") # Client is from basic auth or ... client = None try: client = self.function["verify_client"](environ, client, self.cdb) except (KeyError, AttributeError): err = TokenErrorResponse(error="unathorized_client", error_description="client_id:%s" % client) resp = Response(err.to_json(), content="application/json", status="401 Unauthorized") return resp(environ, start_response) LOG_DEBUG("AccessTokenRequest: %s" % areq) assert areq["grant_type"] == "authorization_code" # assert that the code is valid _info = _sdb[areq["code"]] # If redirect_uri was in the initial authorization request # verify that the one given here is the correct one. if "redirect_uri" in _info: assert areq["redirect_uri"] == _info["redirect_uri"] _tinfo = _sdb.update_to_token(areq["code"]) LOG_DEBUG("_tinfo: %s" % _tinfo) atr = AccessTokenResponse(**by_schema(AccessTokenResponse, **_tinfo)) LOG_DEBUG("AccessTokenResponse: %s" % atr) resp = Response(atr.to_json(), content="application/json") return resp(environ, start_response)
def test_password_grant_type_bad(self): # Set a not so dummy Authn method and token policy self.provider.authn_broker = AUTHN_BROKER2 self.provider.set_token_policy('client1', {'grant_type': ['password']}) areq = ROPCAccessTokenRequest(grant_type='password', username='******', password='******') areq['client_id'] = 'client1' # Token endpoint would fill that in based on client_authn resp = self.provider.password_grant_type(areq) atr = TokenErrorResponse().deserialize(resp.message, "json") assert atr['error'] == 'invalid_grant'
def test_password_grant_type_no_authn(self): # Set a blank AuthnBroker self.provider.authn_broker = AuthnBroker() self.provider.set_token_policy('client1', {'grant_type': ['password']}) areq = ROPCAccessTokenRequest(grant_type='password', username='******', password='******') areq['client_id'] = 'client1' # Token endpoint would fill that in based on client_authn resp = self.provider.password_grant_type(areq) atr = TokenErrorResponse().deserialize(resp.message, "json") assert atr['error'] == 'invalid_grant'
def token_endpoint(self, auth_header="", **kwargs): """ This is where clients come to get their access tokens """ _sdb = self.sdb LOG_DEBUG("- token -") body = kwargs["request"] LOG_DEBUG("body: %s" % body) areq = AccessTokenRequest().deserialize(body, "urlencoded") try: client = self.client_authn(self, areq, auth_header) except FailedAuthentication, err: err = TokenErrorResponse(error="unathorized_client", error_description="%s" % err) return Response(err.to_json(), content="application/json", status="401 Unauthorized")
def token_endpoint(self, authn="", **kwargs): """ This is where clients come to get their access tokens """ _sdb = self.sdb LOG_DEBUG("- token -") body = kwargs["request"] LOG_DEBUG("body: %s" % body) areq = AccessTokenRequest().deserialize(body, "urlencoded") try: client = self.client_authn(self, areq, authn) except FailedAuthentication, err: err = TokenErrorResponse(error="unathorized_client", error_description="%s" % err) return Response(err.to_json(), content="application/json", status="401 Unauthorized")
def test_token_endpoint_unauth(): provider = Provider("pyoicserv", sdb.SessionDB(), CDB, AUTHN_BROKER, AUTHZ, verify_client, symkey=rndstr(16)) authreq = AuthorizationRequest(state="state", redirect_uri="http://example.com/authz", client_id="client1") _sdb = provider.sdb sid = _sdb.token.key(user="******", areq=authreq) access_grant = _sdb.token(sid=sid) _sdb[sid] = { "oauth_state": "authz", "sub": "sub", "authzreq": "", "client_id": "client1", "code": access_grant, "code_used": False, "redirect_uri": "http://example.com/authz" } # Construct Access token request areq = AccessTokenRequest( code=access_grant, redirect_uri="http://example.com/authz", client_id="client2", client_secret="hemlighet", ) print areq.to_dict() resp = provider.token_endpoint(request=areq.to_urlencoded()) print resp.message atr = TokenErrorResponse().deserialize(resp.message, "json") print atr.keys() assert _eq(atr.keys(), ['error_description', 'error'])
def test_password_grant_type_no_authn(self): # Set a blank AuthnBroker self.provider.authn_broker = AuthnBroker() self.provider.set_token_policy("client1", {"grant_type": ["password"]}) areq = ROPCAccessTokenRequest(grant_type="password", username="******", password="******") areq[ "client_id"] = "client1" # Token endpoint would fill that in based on client_authn resp = self.provider.password_grant_type(areq) atr = TokenErrorResponse().deserialize(resp.message, "json") assert atr["error"] == "invalid_grant"
def test_password_grant_type_bad(self): # Set a not so dummy Authn method and token policy self.provider.authn_broker = AUTHN_BROKER2 self.provider.set_token_policy("client1", {"grant_type": ["password"]}) areq = ROPCAccessTokenRequest(grant_type="password", username="******", password="******") areq[ "client_id"] = "client1" # Token endpoint would fill that in based on client_authn resp = self.provider.password_grant_type(areq) atr = TokenErrorResponse().deserialize(resp.message, "json") assert atr["error"] == "invalid_grant"
def token_endpoint(self, authn="", **kwargs): """ This is where clients come to get their access tokens """ _sdb = self.sdb LOG_DEBUG("- token -") body = kwargs["request"] LOG_DEBUG("body: %s" % body) areq = AccessTokenRequest().deserialize(body, "urlencoded") try: client = self.client_authn(self, areq, authn) except FailedAuthentication as err: err = TokenErrorResponse(error="unauthorized_client", error_description="%s" % err) return Response(err.to_json(), content="application/json", status="401 Unauthorized") LOG_DEBUG("AccessTokenRequest: %s" % areq) try: assert areq["grant_type"] == "authorization_code" except AssertionError: err = TokenErrorResponse(error="invalid_request", error_description="Wrong grant type") return Response(err.to_json(), content="application/json", status="401 Unauthorized") # assert that the code is valid _info = _sdb[areq["code"]] resp = self.token_scope_check(areq, _info) if resp: return resp # If redirect_uri was in the initial authorization request # verify that the one given here is the correct one. if "redirect_uri" in _info: assert areq["redirect_uri"] == _info["redirect_uri"] try: _tinfo = _sdb.upgrade_to_token(areq["code"], issue_refresh=True) except AccessCodeUsed: err = TokenErrorResponse(error="invalid_grant", error_description="Access grant used") return Response(err.to_json(), content="application/json", status="401 Unauthorized") LOG_DEBUG("_tinfo: %s" % _tinfo) atr = AccessTokenResponse(**by_schema(AccessTokenResponse, **_tinfo)) LOG_DEBUG("AccessTokenResponse: %s" % atr) return Response(atr.to_json(), content="application/json")
def test_token_endpoint_unauth(): provider = Provider("pyoicserv", sdb.SessionDB(), CDB, FUNCTIONS) authreq = AuthorizationRequest(state="state", redirect_uri="http://example.com/authz", client_id="client1") _sdb = provider.sdb sid = _sdb.token.key(user="******", areq=authreq) access_grant = _sdb.token(sid=sid) _sdb[sid] = { "oauth_state": "authz", "user_id": "user_id", "authzreq": "", "client_id": "client1", "code": access_grant, "code_used": False, "redirect_uri":"http://example.com/authz" } # Construct Access token request areq = AccessTokenRequest(code=access_grant, redirect_uri="http://example.com/authz", client_id="client1", client_secret="hemlighet",) str = areq.to_urlencoded() fil = StringIO.StringIO(buf=str) environ = BASE_ENVIRON.copy() environ["CONTENT_LENGTH"] = len(str) environ["wsgi.input"] = fil environ["REMOTE_USER"] = "******" resp = provider.token_endpoint(environ, start_response) print resp atr = TokenErrorResponse().deserialize(resp[0], "json") print atr.keys() assert _eq(atr.keys(), ['error_description', 'error'])
def code_grant_type(self, areq): """ Token authorization using Code Grant. RFC6749 section 4.1 """ try: _tinfo = self.sdb.upgrade_to_token(areq["code"], issue_refresh=True) except AccessCodeUsed: error = TokenErrorResponse(error="invalid_grant", error_description="Access grant used") return Unauthorized(error.to_json(), content="application/json") logger.debug("_tinfo: %s" % sanitize(_tinfo)) atr = AccessTokenResponse(**by_schema(AccessTokenResponse, **_tinfo)) logger.debug("AccessTokenResponse: %s" % sanitize(atr)) return Response(atr.to_json(), content="application/json", headers=OAUTH2_NOCACHE_HEADERS)
def test_token_endpoint_bad_state(self): authreq = AuthorizationRequest( state="state", redirect_uri="http://example.com/authz", client_id="client1", response_type="code", scope=["openid"], ) _sdb = self.provider.sdb sid = _sdb.access_token.key(user="******", areq=authreq) access_grant = _sdb.access_token(sid=sid) _sdb[sid] = { "oauth_state": "authz", "authzreq": "", "client_id": "client1", "code": access_grant, "state": "state", "code_used": False, "scope": ["openid"], "redirect_uri": "http://example.com/authz", } # Construct Access token request areq = AccessTokenRequest( code=access_grant, client_id="client1", redirect_uri="http://example.com/authz", client_secret="hemlighet", grant_type="authorization_code", state="other_state", ) txt = areq.to_urlencoded() resp = self.provider.token_endpoint(request=txt) atr = TokenErrorResponse().deserialize(resp.message, "json") assert atr["error"] == "unauthorized_client"
try: client = self.client_authn(self, areq, authn) except FailedAuthentication, err: err = TokenErrorResponse(error="unauthorized_client", error_description="%s" % err) return Response(err.to_json(), content="application/json", status="401 Unauthorized") LOG_DEBUG("AccessTokenRequest: %s" % areq) try: assert areq["grant_type"] == "authorization_code" except AssertionError: err = TokenErrorResponse(error="invalid_request", error_description="Wrong grant type") return Response(err.to_json(), content="application/json", status="401 Unauthorized") # assert that the code is valid _info = _sdb[areq["code"]] resp = self.token_scope_check(areq, _info) if resp: return resp # If redirect_uri was in the initial authorization request # verify that the one given here is the correct one. if "redirect_uri" in _info: assert areq["redirect_uri"] == _info["redirect_uri"]
def test_init(self): ter = TokenErrorResponse(error="access_denied", state="xyz") assert ter["error"] == "access_denied" assert ter["state"] == "xyz"
areq = AccessTokenRequest().deserialize(body, "urlencoded") try: client = self.client_authn(self, areq, authn) except FailedAuthentication, err: err = TokenErrorResponse(error="unauthorized_client", error_description="%s" % err) return Response(err.to_json(), content="application/json", status="401 Unauthorized") LOG_DEBUG("AccessTokenRequest: %s" % areq) try: assert areq["grant_type"] == "authorization_code" except AssertionError: err = TokenErrorResponse(error="invalid_request", error_description="Wrong grant type") return Response(err.to_json(), content="application/json", status="401 Unauthorized") # assert that the code is valid _info = _sdb[areq["code"]] resp = self.token_scope_check(areq, _info) if resp: return resp # If redirect_uri was in the initial authorization request # verify that the one given here is the correct one. if "redirect_uri" in _info: assert areq["redirect_uri"] == _info["redirect_uri"]
def token_endpoint(self, request="", authn="", dtype="urlencoded", **kwargs): """ Provide clients with access tokens. :param authn: Auhentication info, comes from HTTP header. :param request: The request. :param dtype: deserialization method for the request. """ logger.debug("- token -") logger.debug("token_request: %s" % sanitize(request)) areq = self.server.message_factory.get_request_type( "token_endpoint")().deserialize(request, dtype) # Verify client authentication try: client_id = self.client_authn(self, areq, authn) except (FailedAuthentication, AuthnFailure) as err: logger.error(err) error = TokenErrorResponse(error="unauthorized_client", error_description="%s" % err) return Unauthorized(error.to_json(), content="application/json") logger.debug("AccessTokenRequest: %s" % sanitize(areq)) # `code` is not mandatory for all requests if "code" in areq: try: _info = self.sdb[areq["code"]] except KeyError: logger.error("Code not present in SessionDB") error = TokenErrorResponse(error="unauthorized_client", error_description="Invalid code.") return Unauthorized(error.to_json(), content="application/json") resp = self.token_scope_check(areq, _info) if resp: return resp # If redirect_uri was in the initial authorization request verify that they match if ("redirect_uri" in _info and areq["redirect_uri"] != _info["redirect_uri"]): logger.error("Redirect_uri mismatch") error = TokenErrorResponse( error="unauthorized_client", error_description="Redirect_uris do not match.", ) return Unauthorized(error.to_json(), content="application/json") if "state" in areq: if _info["state"] != areq["state"]: logger.error("State value mismatch") error = TokenErrorResponse( error="unauthorized_client", error_description="State values do not match.", ) return Unauthorized(error.to_json(), content="application/json") # Propagate the client_id further areq.setdefault("client_id", client_id) grant_type = areq["grant_type"] if grant_type == "authorization_code": return self.code_grant_type(areq) elif grant_type == "refresh_token": return self.refresh_token_grant_type(areq) elif grant_type == "client_credentials": return self.client_credentials_grant_type(areq) elif grant_type == "password": return self.password_grant_type(areq) else: raise UnSupported("grant_type: {}".format(grant_type))