def test_make_id_token(): srv = Server() srv.keyjar = KEYJ srv.keyjar["http://oic.example/rp"] = KC_RSA session = {"sub": "user0", "client_id": "http://oic.example/rp"} issuer = "http://oic.example/idp" code = "abcdefghijklmnop" _idt = srv.make_id_token(session, loa="2", issuer=issuer, code=code, access_token="access_token") algo = "RS256" ckey = srv.keyjar.get_signing_key(alg2keytype(algo), session["client_id"]) _signed_jwt = _idt.to_jwt(key=ckey, algorithm="RS256") idt = IdToken().from_jwt(_signed_jwt, keyjar=srv.keyjar) print idt header = unpack(_signed_jwt) lha = left_hash(code, func="HS" + header[0]["alg"][-3:]) assert lha == idt["c_hash"] atr = AccessTokenResponse(id_token=_signed_jwt, access_token="access_token", token_type="Bearer") atr["code"] = code assert atr.verify(keyjar=srv.keyjar)
def test_make_id_token(): srv = Server() srv.keyjar = KEYJ srv.keyjar["http://oic.example/rp"] = KC_RSA session = {"sub": "user0", "client_id": "http://oic.example/rp"} issuer = "http://oic.example/idp" code = "abcdefghijklmnop" _idt = srv.make_id_token(session, loa="2", issuer=issuer, code=code, access_token="access_token") algo = "RS256" ckey = srv.keyjar.get_signing_key(alg2keytype(algo), session["client_id"]) _signed_jwt = _idt.to_jwt(key=ckey, algorithm="RS256") idt = IdToken().from_jwt(_signed_jwt, keyjar=srv.keyjar) print idt header = unpack(_signed_jwt) lha = left_hash(code, func="HS" + header[0]["alg"][-3:]) assert lha == idt["c_hash"] atr = AccessTokenResponse(id_token=_signed_jwt, access_token="access_token", token_type="Bearer") atr["code"] = code assert atr.verify(keyjar=srv.keyjar)
def test_make_id_token(): srv = Server(KEYS) session = {"user_id": "user0", "client_id": "http://oic.example/rp"} issuer = "http://oic.example/idp" code = "abcdefghijklmnop" idt_jwt = srv.make_id_token(session, loa="2", issuer=issuer, code=code, access_token="access_token") jwt_keys = srv.keystore.get_keys("ver", owner=None) idt = IdToken().from_jwt(idt_jwt, key=jwt_keys) print idt header = unpack(idt_jwt) lha = left_hash(code, func="HS" + header[0]["alg"][-3:]) assert lha == idt["c_hash"] atr = AccessTokenResponse(id_token=idt_jwt, access_token="access_token", token_type="Bearer") atr["code"] = code assert atr.verify(key=jwt_keys)
class TestServer(object): @pytest.fixture(autouse=True) def create_server(self): self.srv = Server() self.srv.keyjar = KEYJ def test_parse_authz_req(self): ar = AuthorizationRequest(response_type=["code"], client_id="foobar", redirect_uri="http://foobar.example.com/oaclient", state="cold", nonce="NONCE", scope=["openid"]) # query string uencq = ar.to_urlencoded() areq = self.srv.parse_authorization_request(query=uencq) assert isinstance(areq, AuthorizationRequest) assert areq["response_type"] == ["code"] assert areq["client_id"] == "foobar" assert areq["redirect_uri"] == "http://foobar.example.com/oaclient" assert areq["state"] == "cold" # urlencoded urluenc = "https://example.com/authz?{}".format(uencq) areq = self.srv.parse_authorization_request(url=urluenc) assert isinstance(areq, AuthorizationRequest) assert areq["response_type"] == ["code"] assert areq["client_id"] == "foobar" assert areq["redirect_uri"] == "http://foobar.example.com/oaclient" assert areq["state"] == "cold" def test_parse_authz_req_jwt(self): ar = AuthorizationRequest(response_type=["code"], client_id=CLIENT_ID, redirect_uri="http://foobar.example.com/oaclient", state="cold", nonce="NONCE", scope=["openid"]) _keys = self.srv.keyjar.get_verify_key(owner=CLIENT_ID) _jwt = ar.to_jwt(key=_keys, algorithm="HS256") req = self.srv.parse_jwt_request(txt=_jwt) assert isinstance(req, AuthorizationRequest) assert req["response_type"] == ["code"] assert req["client_id"] == CLIENT_ID assert req["redirect_uri"] == "http://foobar.example.com/oaclient" assert req["state"] == "cold" def test_server_parse_token_request(self): atr = AccessTokenRequest(grant_type="authorization_code", code="SplxlOBeZQQYbYS6WxSbIA", redirect_uri="https://client.example.com/cb", client_id=CLIENT_ID, extra="foo") uenc = atr.to_urlencoded() tr = self.srv.parse_token_request(body=uenc) assert isinstance(tr, AccessTokenRequest) assert _eq(tr.keys(), ['code', 'redirect_uri', 'grant_type', 'client_id', 'extra']) assert tr["grant_type"] == "authorization_code" assert tr["code"] == "SplxlOBeZQQYbYS6WxSbIA" assert tr["extra"] == "foo" def test_server_parse_refresh_token_request(self): ratr = RefreshAccessTokenRequest(refresh_token="ababababab", client_id="Client_id") uenc = ratr.to_urlencoded() tr = self.srv.parse_refresh_token_request(body=uenc) assert isinstance(tr, RefreshAccessTokenRequest) assert tr["refresh_token"] == "ababababab" assert tr["client_id"] == "Client_id" def test_parse_urlencoded(self): loc = "http://example.com/userinfo?access_token=access_token" qdict = self.srv._parse_urlencoded(loc) assert qdict["access_token"] == ["access_token"] def test_parse_authorization_request(self): areq = AuthorizationRequest(response_type="code", client_id="client_id", redirect_uri="http://example.com/authz", scope=["openid"], state="state0", nonce="N0nce") qdict = self.srv.parse_authorization_request(query=areq.to_urlencoded()) assert _eq(qdict.keys(), ['nonce', 'state', 'redirect_uri', 'response_type', 'client_id', 'scope']) assert qdict["state"] == "state0" def test_parse_token_request(self): treq = AccessTokenRequest(code="code", redirect_uri="http://example.com/authz", client_id=CLIENT_ID, grant_type='authorization_code') qdict = self.srv.parse_token_request(body=treq.to_urlencoded()) assert isinstance(qdict, AccessTokenRequest) assert _eq(qdict.keys(), ['code', 'redirect_uri', 'client_id', 'grant_type']) assert qdict["client_id"] == CLIENT_ID assert qdict["code"] == "code" def test_parse_userinfo_requesr(self): uireq = UserInfoRequest(access_token="access_token") uencq = uireq.to_urlencoded() qdict = self.srv.parse_user_info_request(data=uencq) assert _eq(qdict.keys(), ['access_token']) assert qdict["access_token"] == "access_token" url = "https://example.org/userinfo?{}".format(uencq) qdict = self.srv.parse_user_info_request(data=url) assert _eq(qdict.keys(), ['access_token']) assert qdict["access_token"] == "access_token" def test_parse_registration_request(self): regreq = RegistrationRequest(contacts=["*****@*****.**"], redirect_uris=[ "http://example.org/jqauthz"], application_name="pacubar", client_id=CLIENT_ID, operation="register", application_type="web") request = self.srv.parse_registration_request( data=regreq.to_urlencoded()) assert isinstance(request, RegistrationRequest) assert _eq(request.keys(), ['redirect_uris', 'contacts', 'client_id', 'application_name', 'operation', 'application_type', 'response_types']) assert request["application_name"] == "pacubar" assert request["operation"] == "register" def test_parse_refresh_session_request(self): rsreq = RefreshSessionRequest(id_token="id_token", redirect_url="http://example.com/authz", state="state0") uencq = rsreq.to_urlencoded() request = self.srv.parse_refresh_session_request(query=uencq) assert isinstance(request, RefreshSessionRequest) assert _eq(request.keys(), ['id_token', 'state', 'redirect_url']) assert request["id_token"] == "id_token" url = "https://example.org/userinfo?{}".format(uencq) request = self.srv.parse_refresh_session_request(url=url) assert isinstance(request, RefreshSessionRequest) assert _eq(request.keys(), ['id_token', 'state', 'redirect_url']) assert request["id_token"] == "id_token" def test_parse_check_session_request(self): csreq = CheckSessionRequest( id_token=IDTOKEN.to_jwt(key=KC_SYM_S.get(alg2keytype("HS256")), algorithm="HS256")) request = self.srv.parse_check_session_request( query=csreq.to_urlencoded()) assert isinstance(request, IdToken) assert _eq(request.keys(), ['nonce', 'sub', 'aud', 'iss', 'exp', 'iat']) assert request["aud"] == ["client_1"] def test_parse_end_session_request(self): esreq = EndSessionRequest( id_token=IDTOKEN.to_jwt(key=KC_SYM_S.get(alg2keytype("HS256")), algorithm="HS256"), redirect_url="http://example.org/jqauthz", state="state0") request = self.srv.parse_end_session_request( query=esreq.to_urlencoded()) assert isinstance(request, EndSessionRequest) assert _eq(request.keys(), ['id_token', 'redirect_url', 'state']) assert request["state"] == "state0" assert request["id_token"]["aud"] == ["client_1"] def test_parse_open_id_request(self): userinfo_claims = Claims(name={"essential": True}, nickname=None, email={"essential": True}, email_verified={"essential": True}, picture=None) id_token_claims = Claims(auth_time={"essential": True, "acr": {"values": [ "urn:mace:incommon:iap:silver"]}}) claims_req = ClaimsRequest(userinfo=userinfo_claims, id_token=id_token_claims) oidreq = OpenIDRequest(response_type=["code", "id_token"], client_id=CLIENT_ID, redirect_uri="https://client.example.com/cb", scope="openid profile", state="n-0S6_WzA2Mj", nonce="af0ifjsldkj", max_age=86400, claims=claims_req) request = self.srv.parse_open_id_request(data=oidreq.to_json(), sformat="json") assert isinstance(request, OpenIDRequest) assert _eq(request.keys(), ['nonce', 'claims', 'state', 'redirect_uri', 'response_type', 'client_id', 'scope', 'max_age']) assert request["nonce"] == "af0ifjsldkj" assert "email" in request["claims"]["userinfo"] def test_make_id_token(self): self.srv.keyjar["http://oic.example/rp"] = KC_RSA session = {"sub": "user0", "client_id": "http://oic.example/rp"} issuer = "http://oic.example/idp" code = "abcdefghijklmnop" _idt = self.srv.make_id_token(session, loa="2", issuer=issuer, code=code, access_token="access_token") algo = "RS256" ckey = self.srv.keyjar.get_signing_key(alg2keytype(algo), session["client_id"]) _signed_jwt = _idt.to_jwt(key=ckey, algorithm="RS256") idt = IdToken().from_jwt(_signed_jwt, keyjar=self.srv.keyjar) _jwt = JWT().unpack(_signed_jwt) lha = left_hash(code.encode("utf-8"), func="HS" + _jwt.headers["alg"][-3:]) assert lha == idt["c_hash"] atr = AccessTokenResponse(id_token=_signed_jwt, access_token="access_token", token_type="Bearer") atr["code"] = code assert atr.verify(keyjar=self.srv.keyjar)
class TestServer(object): @pytest.fixture(autouse=True) def create_server(self): self.srv = Server() self.srv.keyjar = KEYJ def test_parse_authz_req(self): ar = AuthorizationRequest( response_type=["code"], client_id="foobar", redirect_uri="http://foobar.example.com/oaclient", state="cold", nonce="NONCE", scope=["openid"], ) # query string uencq = ar.to_urlencoded() areq = self.srv.parse_authorization_request(query=uencq) assert isinstance(areq, AuthorizationRequest) assert areq["response_type"] == ["code"] assert areq["client_id"] == "foobar" assert areq["redirect_uri"] == "http://foobar.example.com/oaclient" assert areq["state"] == "cold" # urlencoded urluenc = "https://example.com/authz?{}".format(uencq) areq = self.srv.parse_authorization_request(url=urluenc) assert isinstance(areq, AuthorizationRequest) assert areq["response_type"] == ["code"] assert areq["client_id"] == "foobar" assert areq["redirect_uri"] == "http://foobar.example.com/oaclient" assert areq["state"] == "cold" def test_parse_authz_req_jwt(self): ar = AuthorizationRequest( response_type=["code"], client_id=CLIENT_ID, redirect_uri="http://foobar.example.com/oaclient", state="cold", nonce="NONCE", scope=["openid"], ) _keys = self.srv.keyjar.get_verify_key(owner=CLIENT_ID) _jwt = ar.to_jwt(key=_keys, algorithm="HS256") req = self.srv.parse_jwt_request(txt=_jwt) assert isinstance(req, AuthorizationRequest) assert req["response_type"] == ["code"] assert req["client_id"] == CLIENT_ID assert req["redirect_uri"] == "http://foobar.example.com/oaclient" assert req["state"] == "cold" def test_server_parse_token_request(self): atr = AccessTokenRequest( grant_type="authorization_code", code="SplxlOBeZQQYbYS6WxSbIA", redirect_uri="https://client.example.com/cb", client_id=CLIENT_ID, extra="foo", ) uenc = atr.to_urlencoded() tr = self.srv.parse_token_request(body=uenc) assert isinstance(tr, AccessTokenRequest) assert _eq( tr.keys(), ["code", "redirect_uri", "grant_type", "client_id", "extra"]) assert tr["grant_type"] == "authorization_code" assert tr["code"] == "SplxlOBeZQQYbYS6WxSbIA" assert tr["extra"] == "foo" def test_server_parse_refresh_token_request(self): ratr = RefreshAccessTokenRequest(refresh_token="ababababab", client_id="Client_id") uenc = ratr.to_urlencoded() tr = self.srv.parse_refresh_token_request(body=uenc) assert isinstance(tr, RefreshAccessTokenRequest) assert tr["refresh_token"] == "ababababab" assert tr["client_id"] == "Client_id" def test_parse_urlencoded(self): loc = "http://example.com/userinfo?access_token=access_token" qdict = self.srv._parse_urlencoded(loc) assert qdict["access_token"] == ["access_token"] def test_parse_authorization_request(self): areq = AuthorizationRequest( response_type="code", client_id="client_id", redirect_uri="http://example.com/authz", scope=["openid"], state="state0", nonce="N0nce", ) qdict = self.srv.parse_authorization_request( query=areq.to_urlencoded()) assert _eq( qdict.keys(), [ "nonce", "state", "redirect_uri", "response_type", "client_id", "scope" ], ) assert qdict["state"] == "state0" def test_parse_token_request(self): treq = AccessTokenRequest( code="code", redirect_uri="http://example.com/authz", client_id=CLIENT_ID, grant_type="authorization_code", ) qdict = self.srv.parse_token_request(body=treq.to_urlencoded()) assert isinstance(qdict, AccessTokenRequest) assert _eq(qdict.keys(), ["code", "redirect_uri", "client_id", "grant_type"]) assert qdict["client_id"] == CLIENT_ID assert qdict["code"] == "code" def test_parse_userinfo_requesr(self): uireq = UserInfoRequest(access_token="access_token") uencq = uireq.to_urlencoded() qdict = self.srv.parse_user_info_request(data=uencq) assert _eq(qdict.keys(), ["access_token"]) assert qdict["access_token"] == "access_token" url = "https://example.org/userinfo?{}".format(uencq) qdict = self.srv.parse_user_info_request(data=url) assert _eq(qdict.keys(), ["access_token"]) assert qdict["access_token"] == "access_token" def test_parse_registration_request(self): regreq = RegistrationRequest( contacts=["*****@*****.**"], redirect_uris=["http://example.org/jqauthz"], application_name="pacubar", client_id=CLIENT_ID, operation="register", application_type="web", ) request = self.srv.parse_registration_request( data=regreq.to_urlencoded()) assert isinstance(request, RegistrationRequest) assert _eq( request.keys(), [ "redirect_uris", "contacts", "client_id", "application_name", "operation", "application_type", "response_types", ], ) assert request["application_name"] == "pacubar" assert request["operation"] == "register" def test_parse_refresh_session_request(self): rsreq = RefreshSessionRequest(id_token="id_token", redirect_url="http://example.com/authz", state="state0") uencq = rsreq.to_urlencoded() request = self.srv.parse_refresh_session_request(query=uencq) assert isinstance(request, RefreshSessionRequest) assert _eq(request.keys(), ["id_token", "state", "redirect_url"]) assert request["id_token"] == "id_token" url = "https://example.org/userinfo?{}".format(uencq) request = self.srv.parse_refresh_session_request(url=url) assert isinstance(request, RefreshSessionRequest) assert _eq(request.keys(), ["id_token", "state", "redirect_url"]) assert request["id_token"] == "id_token" def test_parse_check_session_request(self): csreq = CheckSessionRequest(id_token=IDTOKEN.to_jwt( key=KC_SYM_S.get(alg2keytype("HS256")), algorithm="HS256")) request = self.srv.parse_check_session_request( query=csreq.to_urlencoded()) assert isinstance(request, IdToken) assert _eq(request.keys(), ["nonce", "sub", "aud", "iss", "exp", "iat"]) assert request["aud"] == ["client_1"] def test_parse_end_session_request(self): esreq = EndSessionRequest( id_token=IDTOKEN.to_jwt(key=KC_SYM_S.get(alg2keytype("HS256")), algorithm="HS256"), redirect_url="http://example.org/jqauthz", state="state0", ) request = self.srv.parse_end_session_request( query=esreq.to_urlencoded()) assert isinstance(request, EndSessionRequest) assert _eq(request.keys(), ["id_token", "redirect_url", "state"]) assert request["state"] == "state0" assert request["id_token"]["aud"] == ["client_1"] def test_parse_open_id_request(self): userinfo_claims = Claims( name={"essential": True}, nickname=None, email={"essential": True}, email_verified={"essential": True}, picture=None, ) id_token_claims = Claims( auth_time={ "essential": True, "acr": { "values": ["urn:mace:incommon:iap:silver"] }, }) claims_req = ClaimsRequest(userinfo=userinfo_claims, id_token=id_token_claims) oidreq = OpenIDRequest( response_type=["code", "id_token"], client_id=CLIENT_ID, redirect_uri="https://client.example.com/cb", scope="openid profile", state="n-0S6_WzA2Mj", nonce="af0ifjsldkj", max_age=86400, claims=claims_req, ) request = self.srv.parse_open_id_request(data=oidreq.to_json(), sformat="json") assert isinstance(request, OpenIDRequest) assert _eq( request.keys(), [ "nonce", "claims", "state", "redirect_uri", "response_type", "client_id", "scope", "max_age", ], ) assert request["nonce"] == "af0ifjsldkj" assert "email" in request["claims"]["userinfo"] def test_make_id_token(self): self.srv.keyjar["http://oic.example/idp"] = KC_RSA session = {"sub": "user0", "client_id": "http://oic.example/rp"} issuer = "http://oic.example/idp" code = "abcdefghijklmnop" _idt = self.srv.make_id_token(session, loa="2", issuer=issuer, code=code, access_token="access_token") algo = "RS256" ckey = self.srv.keyjar.get_signing_key(alg2keytype(algo), issuer) _signed_jwt = _idt.to_jwt(key=ckey, algorithm="RS256") idt = IdToken().from_jwt(_signed_jwt, keyjar=self.srv.keyjar) _jwt = JWT().unpack(_signed_jwt) lha = left_hash(code.encode("utf-8"), func="HS" + _jwt.headers["alg"][-3:]) assert lha == idt["c_hash"] atr = AccessTokenResponse(id_token=_signed_jwt, access_token="access_token", token_type="Bearer") atr["code"] = code assert atr.verify(keyjar=self.srv.keyjar)
class Provider(AProvider): def __init__(self, name, sdb, cdb, function, userdb, urlmap=None, ca_certs="", jwt_keys=None): AProvider.__init__(self, name, sdb, cdb, function, urlmap) self.server = Server(jwt_keys=jwt_keys, ca_certs=ca_certs) self.keystore = self.server.keystore self.userdb = userdb self.function = function self.endpoints = [] self.baseurl = "" self.cert = [] self.cert_encryption = [] self.cookie_func = None self.cookie_name = "pyoidc" self.seed = "" self.cookie_ttl = 0 self.test_mode = False self.jwk = [] def _id_token(self, session, loa="2", keytype="rsa", code=None, access_token=None, user_info=None): _idtoken = self.server.make_id_token(session, loa, self.name, keytype, code, access_token, user_info) logger.debug("id_token: %s" % unpack(_idtoken)[1]) return _idtoken def _error(self, environ, start_response, error, descr=None): response = ErrorResponse(error=error, error_description=descr) resp = Response(response.to_json(), content="application/json", status="400 Bad Request") return resp(environ, start_response) def _authz_error(self, environ, start_response, error, descr=None): response = AuthorizationErrorResponse(error=error) if descr: response["error_description"]=descr resp = Response(response.to_json(), content="application/json", status="400 Bad Request") return resp(environ, start_response) def _redirect_authz_error(self, error, redirect_uri, descr=None): err = ErrorResponse(error=error) if descr: err.error_description = descr location = err.request(redirect_uri) return Redirect(location) def _verify_redirect_uri(self, areq): # MUST NOT contain a fragment try: _redirect_uri = areq["redirect_uri"] part = urlparse.urlparse(_redirect_uri) if part.fragment: raise ValueError match = False for registered in self.cdb[areq["client_id"]]["redirect_uris"]: if _redirect_uri == registered: match=True break elif _redirect_uri.startswith(registered): match=True break if not match: raise AssertionError return None except Exception: logger.error("Faulty redirect_uri: %s" % areq["redirect_uri"]) logger.info("Registered redirect_uris: %s" % ( self.cdb[areq["client_id"]]["redirect_uris"],)) response = AuthorizationErrorResponse(error="invalid_request", error_description="Faulty redirect_uri") return Response(response.to_json(), content="application/json", status="400 Bad Request") def _parse_openid_request(self, request, redirect_uri, jwt_key): try: return OpenIDRequest().from_jwt(request, jwt_key) except Exception, err: logger.error("Faulty request: %s" % request) logger.error("Verfied with JWT_keys: %s" % jwt_key) logger.error("Exception: %s" % (err.__class__.__name__,)) openid_req = OpenIDRequest().from_jwt(request, jwt_key, verify=False) logger.error("Request: %s" % openid_req.to_dict()) return self._redirect_authz_error("invalid_openid_request_object", redirect_uri)
class Provider(AProvider): def __init__(self, name, sdb, cdb, authn_method, userinfo, authz, client_authn, symkey, urlmap=None, ca_certs="", keyjar=None, hostname=""): AProvider.__init__(self, name, sdb, cdb, authn_method, authz, client_authn, symkey, urlmap) self.userinfo = userinfo self.server = Server(ca_certs=ca_certs) if keyjar: self.server.keyjar = keyjar self.keyjar = self.server.keyjar self.endpoints = [] self.baseurl = "" self.cert = [] self.cert_encryption = [] if authn_method: self.cookie_func = authn_method.create_cookie else: self.cookie_func = None self.cookie_name = "pyoidc" self.seed = "" self.sso_ttl = 0 self.test_mode = False self.jwks_uri = [] self.authn_as = None self.preferred_id_type = "public" self.hostname = hostname or socket.gethostname self.register_endpoint = "%s%s" % (self.baseurl, "register") def id_token_as_signed_jwt(self, session, loa="2", alg="RS256", code=None, access_token=None, user_info=None): logger.debug("Signing alg: %s [%s]" % (alg, alg2keytype(alg))) _idt = self.server.make_id_token(session, loa, self.name, alg, code, access_token, user_info) logger.debug("id_token: %s" % _idt.to_dict()) # My signing key if its RS*, can use client secret if HS* if alg.startswith("HS"): logger.debug("client_id: %s" % session["client_id"]) ckey = self.keyjar.get_signing_key(alg2keytype(alg), session["client_id"]) else: for b in self.keyjar[""]: logger.debug("OC3 server keys: %s" % b) ckey = self.keyjar.get_signing_key(alg2keytype(alg), "") logger.debug("ckey: %s" % ckey) _signed_jwt = _idt.to_jwt(key=ckey, algorithm=alg) return _signed_jwt def _error_response(self, error, descr=None): logger.error("%s" % error) response = ErrorResponse(error=error, error_description=descr) return Response(response.to_json(), content="application/json", status="400 Bad Request") def _error(self, error, descr=None): response = ErrorResponse(error=error, error_description=descr) return Response(response.to_json(), content="application/json", status="400 Bad Request") def _authz_error(self, error, descr=None): response = AuthorizationErrorResponse(error=error) if descr: response["error_description"] = descr return Response(response.to_json(), content="application/json", status="400 Bad Request") def _redirect_authz_error(self, error, redirect_uri, descr=None): err = ErrorResponse(error=error) if descr: err["error_description"] = descr location = err.request(redirect_uri) return Redirect(location) def _verify_redirect_uri(self, areq): """ MUST NOT contain a fragment MAY contain query component :return: An error response if the redirect URI is faulty otherwise None """ try: _redirect_uri = urlparse.unquote(areq["redirect_uri"]) part = urlparse.urlparse(_redirect_uri) if part.fragment: raise URIError("Contains fragment") (_base, _query) = urllib.splitquery(_redirect_uri) if _query: _query = urlparse.parse_qs(_query) match = False for regbase, rquery in self.cdb[areq["client_id"]]["redirect_uris"]: if _base == regbase or _redirect_uri.startswith(regbase): # every registered query component must exist in the # redirect_uri if rquery: for key, vals in rquery.items(): assert key in _query for val in vals: assert val in _query[key] match = True break if not match: raise RedirectURIError("Doesn't match any registered uris") # ignore query components that are not registered return None except Exception, err: logger.error("Faulty redirect_uri: %s" % areq["redirect_uri"]) try: _cinfo = self.cdb[areq["client_id"]] except KeyError: logger.info("Unknown client: %s" % areq["client_id"]) raise UnknownClient(areq["client_id"]) else: logger.info("Registered redirect_uris: %s" % _cinfo) raise RedirectURIError("Faulty redirect_uri: %s" % err)
class Provider(AProvider): def __init__(self, name, sdb, cdb, authn_broker, userinfo, authz, client_authn, symkey, urlmap=None, ca_certs="", keyjar=None, hostname="", template_lookup=None, verify_login_template=None): AProvider.__init__(self, name, sdb, cdb, authn_broker, authz, client_authn, symkey, urlmap) self.endp.extend([UserinfoEndpoint, RegistrationEndpoint, EndSessionEndpoint]) self.userinfo = userinfo self.server = Server(ca_certs=ca_certs) if keyjar: self.server.keyjar = keyjar self.template_lookup = template_lookup self.verify_login_template = verify_login_template self.keyjar = self.server.keyjar self.baseurl = "" self.cert = [] self.cert_encryption = [] self.cookie_name = "pyoidc" self.seed = "" self.sso_ttl = 0 self.test_mode = False self.jwks_uri = [] self.authn_as = None self.preferred_id_type = "public" self.hostname = hostname or socket.gethostname self.register_endpoint = "%s%s" % (self.baseurl, "register") def id_token_as_signed_jwt(self, session, loa="2", alg="RS256", code=None, access_token=None, user_info=None): logger.debug("Signing alg: %s [%s]" % (alg, alg2keytype(alg))) _idt = self.server.make_id_token(session, loa, self.name, alg, code, access_token, user_info) logger.debug("id_token: %s" % _idt.to_dict()) # My signing key if its RS*, can use client secret if HS* if alg.startswith("HS"): logger.debug("client_id: %s" % session["client_id"]) ckey = self.keyjar.get_signing_key(alg2keytype(alg), session["client_id"]) else: if "" in self.keyjar: for b in self.keyjar[""]: logger.debug("OC3 server keys: %s" % b) ckey = self.keyjar.get_signing_key(alg2keytype(alg), "") logger.debug("ckey: %s" % ckey) _signed_jwt = _idt.to_jwt(key=ckey, algorithm=alg) return _signed_jwt def _parse_openid_request(self, request): return OpenIDRequest().from_jwt(request, keyjar=self.keyjar) def _parse_id_token(self, id_token, redirect_uri): try: return IdToken().from_jwt(id_token, keyjar=self.keyjar) except Exception, err: logger.error("Faulty id_token: %s" % id_token) logger.error("Exception: %s" % (err.__class__.__name__,)) id_token = IdToken().from_jwt(id_token, verify=False) logger.error("IdToken: %s" % id_token.to_dict()) return self._redirect_authz_error("invalid_id_token_object", redirect_uri)