예제 #1
0
 def test_generate_signed(self) -> None:
     session_id = generate_session_id(signed=True, secret_key="abc")
     token = generate_jwt_token(session_id, signed=True, secret_key="abc")
     assert '.' in token
     decoded = json.loads(_base64_decode(token.split('.')[0], encoding='utf-8'))
     assert "session_id" in decoded
     assert decoded['session_id'] == session_id
     assert check_token_signature(token, secret_key="abc", signed=True)
     assert not check_token_signature(token, secret_key="qrs", signed=True)
예제 #2
0
 def test_payload_signed(self):
     session_id = generate_session_id(signed=True, secret_key="abc")
     token = generate_jwt_token(session_id, signed=True, secret_key="abc", extra_payload=dict(foo=10))
     assert '.' in token
     decoded = json.loads(_base64_decode(token.split('.')[0], encoding='utf-8'))
     assert 'session_id' in decoded
     session_id = get_session_id(token)
     assert check_token_signature(token, secret_key="abc", signed=True)
     assert not check_token_signature(token, secret_key="qrs", signed=True)
     assert decoded['foo'] == 10
예제 #3
0
 def test_payload_signed(self):
     session_id = generate_session_id(signed=True, secret_key="abc")
     token = generate_jwt_token(session_id,
                                signed=True,
                                secret_key="abc",
                                extra_payload=dict(foo=10))
     assert '.' in token
     decoded = json.loads(_b64_to_utf8(token.split('.')[0]))
     assert _TOKEN_ZLIB_KEY in decoded
     assert 'session_id' in decoded
     session_id = get_session_id(token)
     assert check_token_signature(token, secret_key="abc", signed=True)
     assert not check_token_signature(token, secret_key="qrs", signed=True)
     payload = get_token_payload(token)
     assert _TOKEN_ZLIB_KEY not in payload
     assert payload['foo'] == 10
예제 #4
0
    async def get_session(self):
        token = self.get_argument("bokeh-token", default=None)
        session_id = self.get_argument("bokeh-session-id", default=None)
        if 'Bokeh-Session-Id' in self.request.headers:
            if session_id is not None:
                log.debug("Server received session ID in request argument and header, expected only one")
                raise HTTPError(status_code=403, reason="session ID was provided as an argument and header")
            session_id = self.request.headers.get('Bokeh-Session-Id')

        if token is not None:
            if session_id is not None:
                log.debug("Server received both token and session ID, expected only one")
                raise HTTPError(status_code=403, reason="Both token and session ID were provided")
            session_id = get_session_id(token)
        elif session_id is None:
            if self.application.generate_session_ids:
                session_id = generate_session_id(secret_key=self.application.secret_key,
                                                 signed=self.application.sign_sessions)
            else:
                log.debug("Server configured not to generate session IDs and none was provided")
                raise HTTPError(status_code=403, reason="No bokeh-session-id provided")

        if token is None:
            if self.application.include_headers is None:
                excluded_headers = (self.application.exclude_headers or [])
                allowed_headers = [header for header in self.request.headers
                                   if header not in excluded_headers]
            else:
                allowed_headers = self.application.include_headers
            headers = {k: v for k, v in self.request.headers.items()
                       if k in allowed_headers}

            if self.application.include_cookies is None:
                excluded_cookies = (self.application.exclude_cookies or [])
                allowed_cookies = [cookie for cookie in self.request.cookies
                                   if cookie not in excluded_cookies]
            else:
                allowed_cookies = self.application.include_cookies
            cookies = {k: v.value for k, v in self.request.cookies.items()
                       if k in allowed_cookies}

            payload = {'headers': headers, 'cookies': cookies}
            payload.update(self.application_context.application.process_request(self.request))
            token = generate_jwt_token(session_id,
                                       secret_key=self.application.secret_key,
                                       signed=self.application.sign_sessions,
                                       expiration=self.application.session_token_expiration,
                                       extra_payload=payload)

        if not check_token_signature(token,
                                     secret_key=self.application.secret_key,
                                     signed=self.application.sign_sessions):
            log.error("Session id had invalid signature: %r", session_id)
            raise HTTPError(status_code=403, reason="Invalid token or session ID")

        session = await self.application_context.create_session_if_needed(session_id, self.request, token)

        return session
async def test__autocreate_signed_session_doc(ManagedServerLoop) -> None:
    application = Application()
    with ManagedServerLoop(application, sign_sessions=True, secret_key='foo') as server:
        sessions = server.get_sessions('/')
        assert 0 == len(sessions)

        response = await http_get(server.io_loop, url(server))
        html = response.body
        token = extract_token_from_json(html)
        sessionid = get_session_id(token)

        sessions = server.get_sessions('/')
        assert 1 == len(sessions)
        assert sessionid == sessions[0].id

        assert check_token_signature(token, signed=True, secret_key='foo')
예제 #6
0
    async def connect(self):
        log.info('WebSocket connection opened')

        subprotocols = self.scope["subprotocols"]
        if len(subprotocols) != 2 or subprotocols[0] != 'bokeh':
            self.close()
            raise RuntimeError("Subprotocol header is not 'bokeh'")

        token = subprotocols[1]
        if token is None:
            self.close()
            raise RuntimeError("No token received in subprotocol header")

        now = calendar.timegm(dt.datetime.now().utctimetuple())
        payload = get_token_payload(token)
        if 'session_expiry' not in payload:
            self.close()
            raise RuntimeError("Session expiry has not been provided")
        elif now >= payload['session_expiry']:
            self.close()
            raise RuntimeError("Token is expired.")
        elif not check_token_signature(token,
                                       signed=False,
                                       secret_key=None):
            session_id = get_session_id(token)
            log.error("Token for session %r had invalid signature", session_id)
            raise RuntimeError("Invalid token signature")

        def on_fully_opened(future):
            e = future.exception()
            if e is not None:
                # this isn't really an error (unless we have a
                # bug), it just means a client disconnected
                # immediately, most likely.
                log.debug("Failed to fully open connlocksection %r", e)

        future = self._async_open(token)

        # rewrite above line using asyncio
        # this task is scheduled to run soon once context is back to event loop
        task = asyncio.ensure_future(future)
        task.add_done_callback(on_fully_opened)
        await self.accept("bokeh")
예제 #7
0
    def open(self):
        ''' Initialize a connection to a client.

        Returns:
            None

        '''
        log.info('WebSocket connection opened')
        token = self._token

        if self.selected_subprotocol != 'bokeh':
            self.close()
            raise ProtocolError("Subprotocol header is not 'bokeh'")
        elif token is None:
            self.close()
            raise ProtocolError("No token received in subprotocol header")

        now = calendar.timegm(dt.datetime.utcnow().utctimetuple())
        payload = get_token_payload(token)
        if 'session_expiry' not in payload:
            self.close()
            raise ProtocolError("Session expiry has not been provided")
        elif now >= payload['session_expiry']:
            self.close()
            raise ProtocolError("Token is expired.")
        elif not check_token_signature(token,
                                       signed=self.application.sign_sessions,
                                       secret_key=self.application.secret_key):
            session_id = get_session_id(token)
            log.error("Token for session %r had invalid signature", session_id)
            raise ProtocolError("Invalid token signature")

        try:
            self.application.io_loop.spawn_callback(self._async_open,
                                                    self._token)
        except Exception as e:
            # this isn't really an error (unless we have a
            # bug), it just means a client disconnected
            # immediately, most likely.
            log.debug("Failed to fully open connection %r", e)
예제 #8
0
 def test_string_encoding_does_not_affect_session_id_check(self) -> None:
     # originates from #6653
     session_id = generate_session_id(signed=True, secret_key="abc")
     token = generate_jwt_token(session_id, signed=True, secret_key="abc")
     assert check_token_signature(token, secret_key="abc", signed=True)
예제 #9
0
 def test_check_signature_with_signing_disabled(self) -> None:
     assert check_token_signature("gobbledygook",
                                  secret_key="abc",
                                  signed=False)
예제 #10
0
 def test_check_signature_of_junk_with_hyphen_in_it(self) -> None:
     assert not check_token_signature(
         "foo-bar-baz", secret_key="abc", signed=True)
예제 #11
0
 def test_check_signature_of_empty_string(self) -> None:
     assert not check_token_signature("", secret_key="abc", signed=True)
예제 #12
0
 def test_check_signature_of_unsigned(self) -> None:
     # secret shouldn't be used
     token = generate_jwt_token(generate_session_id(),
                                signed=False,
                                secret_key="abc")
     assert not check_token_signature(token, secret_key="abc", signed=True)