def test_get_session_management_id(self): now = utc_time_sans_frac() smid = "session_management_id" idval = { "nonce": "KUEYfRM2VzKDaaKD", "sub": "EndUserSubject", "iss": "https://example.com", "exp": now + 3600, "iat": now, "aud": self.consumer.client_id, "sid": smid, } idts = IdToken(**idval) _signed_jwt = idts.to_jwt(key=KC_RSA.keys(), algorithm="RS256") _state = "state" self.consumer.sdb[_state] = { "redirect_uris": ["https://example.org/cb"] } resp = AuthorizationResponse(id_token=_signed_jwt, state=_state) self.consumer.consumer_config["response_type"] = ["id_token"] self.consumer.parse_authz(resp.to_urlencoded()) assert self.consumer.sso_db["state"]["smid"] == smid assert session_get(self.consumer.sso_db, "smid", smid) == [_state]
def test_id_token_hint_aud_does_not_match_client_id(self): id_token = self._auth_with_id_token() assert session_get(self.provider.sdb, "sub", id_token["sub"]) # verify we got valid session # add another aud and an azp. id_token_hint = id_token.to_jwt(algorithm="none") # Mess with the session DB _sid = list(self.provider.sdb._db.storage.keys())[0] self.provider.sdb[_sid]["client_id"] = "something else" resp = self.provider.end_session_endpoint( urlencode({"id_token_hint": id_token_hint})) assert isinstance(resp, Response) assert resp.status_code == 400
def test_end_session_endpoint_with_cookie_wrong_client(self): # Need cookie and ID Token to figure this out id_token = self._auth_with_id_token() assert session_get(self.provider.sdb, "sub", id_token["sub"]) id_token_hint = id_token.to_jwt(algorithm="none") # Wrong client_id cookie = self._create_cookie("username", "a1b2c3") resp = self.provider.end_session_endpoint(urlencode( {"id_token_hint": id_token_hint}), cookie=cookie) assert isinstance(resp, Response) _err = ErrorResponse().from_json(resp.message) assert _err["error"] == "invalid_request"
def test_end_session_endpoint_with_wrong_cookie(self): # Need cookie and ID Token to figure this out id_token = self._auth_with_id_token() assert session_get(self.provider.sdb, "sub", id_token["sub"]) # verify we got valid session id_token_hint = id_token.to_jwt(algorithm="none") cookie = self._create_cookie("diggins", "number5") resp = self.provider.end_session_endpoint(urlencode( {"id_token_hint": id_token_hint}), cookie=cookie) assert isinstance(resp, Response) _err = ErrorResponse().from_json(resp.message) assert _err["error"] == "invalid_request" assert _err["error_description"] == "Wrong user"
def test_id_token_hint_multiple_aud(self): id_token = self._auth_with_id_token() assert session_get(self.provider.sdb, "sub", id_token["sub"]) # verify we got valid session self.provider.cdb["number5"]["post_logout_redirect_uris"] = [ ("https://example.com/plru", "") ] # add another aud and an azp. id_token["azp"] = id_token["aud"][0] id_token["aud"].append("foobar") id_token_hint = id_token.to_jwt(algorithm="none") resp = self.provider.end_session_endpoint( urlencode({"id_token_hint": id_token_hint})) assert isinstance(resp, SeeOther)
def test_end_session_endpoint_with_id_token_hint_only(self): id_token = self._auth_with_id_token() assert session_get(self.provider.sdb, "sub", id_token["sub"]) id_token_hint = id_token.to_jwt(algorithm="none") resp = self.provider.end_session_endpoint( urlencode({"id_token_hint": id_token_hint})) # returns a SeeOther instance p = urlparse(resp.message) qs = parse_qs(p.query) jwt_info = self.provider.unpack_signed_jwt(qs["sjwt"][0]) assert jwt_info["uid"] == "username" assert jwt_info["client_id"] == "number5" assert jwt_info["redirect_uri"] == "https://example.com/post_logout"
def backchannel_logout(self, request: Optional[str] = None, request_args: Optional[Dict] = None) -> str: """ Receives a back channel logout request. :param request: A urlencoded request :param request_args: The request as a dictionary :return: A Session Identifier """ if request: req = BackChannelLogoutRequest().from_urlencoded(request) elif request_args is not None: req = BackChannelLogoutRequest(**request_args) else: raise ValueError("Missing request specification") kwargs = { "aud": self.client_id, "iss": self.issuer, "keyjar": self.keyjar } try: req.verify(**kwargs) except (MessageException, ValueError, NotForMe) as err: raise MessageException("Bogus logout request: {}".format(err)) # Find the subject through 'sid' or 'sub' try: sub = req["logout_token"]["sub"] except KeyError: # verify has guaranteed that there will be a sid if sub is missing sm_id = req["logout_token"]["sid"] _sid = session_get(self.sso_db, "smid", sm_id) else: _sid = session_extended_get(self.sso_db, sub, "issuer", req["logout_token"]["iss"]) return _sid