Esempio n. 1
0
def test_verify_id_token_missing_c_hash():
    code = 'AccessCode1'

    idt = IdToken(**{
        "sub": "553df2bcf909104751cfd8b2",
        "aud": [
            "5542958437706128204e0000",
            "554295ce3770612820620000"
            ],
        "auth_time": 1441364872,
        "azp": "554295ce3770612820620000",
        })

    kj = KeyJar()
    kj.add_symmetric("", 'dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ', ['sig'])
    kj.add_symmetric("https://sso.qa.7pass.ctf.prosiebensat1.com",
                     'dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ', ['sig'])
    packer = JWT(kj, sign_alg='HS256',
                 iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
                 lifetime=3600)
    _jws = packer.pack(**idt.to_dict())
    msg = AuthorizationResponse(code=code, id_token=_jws)
    with pytest.raises(MissingRequiredAttribute):
        verify_id_token(msg, check_hash=True, keyjar=kj,
                        iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
                        client_id="554295ce3770612820620000")
Esempio n. 2
0
def test_verify_id_token_at_hash_and_chash():
    token = 'AccessTokenWhichCouldBeASignedJWT'
    at_hash = left_hash(token)
    code = 'AccessCode1'
    c_hash = left_hash(code)

    idt = IdToken(**{
        "sub": "553df2bcf909104751cfd8b2",
        "aud": [
            "5542958437706128204e0000",
            "554295ce3770612820620000"
            ],
        "auth_time": 1441364872,
        "azp": "554295ce3770612820620000",
        "at_hash": at_hash,
        'c_hash': c_hash
        })

    kj = KeyJar()
    kj.add_symmetric("", 'dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ', ['sig'])
    kj.add_symmetric("https://sso.qa.7pass.ctf.prosiebensat1.com",
                     'dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ', ['sig'])
    packer = JWT(kj, sign_alg='HS256',
                 iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
                 lifetime=3600)
    _jws = packer.pack(**idt.to_dict())
    msg = AuthorizationResponse(access_token=token, id_token=_jws, code=code)
    verify_id_token(msg, check_hash=True, keyjar=kj,
                    iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
                    client_id="554295ce3770612820620000")
Esempio n. 3
0
def test_verify_id_token_at_hash_fail():
    token = 'AccessTokenWhichCouldBeASignedJWT'
    token2 = 'ACompletelyOtherAccessToken'
    lhsh = left_hash(token)

    idt = IdToken(**{
        "sub": "553df2bcf909104751cfd8b2",
        "aud": [
            "5542958437706128204e0000",
            "554295ce3770612820620000"
            ],
        "auth_time": 1441364872,
        "azp": "554295ce3770612820620000",
        "at_hash": lhsh
        })

    kj = KeyJar()
    kj.add_symmetric("", 'dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ', ['sig'])
    kj.add_symmetric("https://sso.qa.7pass.ctf.prosiebensat1.com",
                     'dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ', ['sig'])
    packer = JWT(kj, sign_alg='HS256',
                 iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
                 lifetime=3600)
    _jws = packer.pack(**idt.to_dict())
    msg = AuthorizationResponse(access_token=token2, id_token=_jws)
    with pytest.raises(AtHashError):
        verify_id_token(msg, check_hash=True, keyjar=kj,
                        iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
                        client_id="554295ce3770612820620000")
Esempio n. 4
0
    def test_check_session_endpoint(self):
        session = {"sub": "UserID", "client_id": "number5"}
        idtoken = self.provider.id_token_as_signed_jwt(session)
        csr = CheckSessionRequest(id_token=idtoken)

        info = self.provider.check_session_endpoint(request=csr.to_urlencoded())
        idt = IdToken().deserialize(info.message, "json")
        assert _eq(idt.keys(), ['sub', 'aud', 'iss', 'acr', 'exp', 'iat'])
        assert idt["iss"] == self.provider.name + "/"
Esempio n. 5
0
 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)
Esempio n. 6
0
def _faulty_id_token():
    idval = {'nonce': 'KUEYfRM2VzKDaaKD', 'sub': 'EndUserSubject',
             'iss': 'https://alpha.cloud.nds.rub.de', 'exp': 1420823073,
             'iat': 1420822473, 'aud': 'TestClient'}
    idts = IdToken(**idval)

    _signed_jwt = idts.to_jwt(key=[SYMKEY], algorithm="HS256")

    # Mess with the signed id_token
    p = _signed_jwt.split(".")
    p[2] = "aaa"

    return ".".join(p)
Esempio n. 7
0
def test_check_session_endpoint():
    server = provider_init
    print server.name

    session = {"sub": "UserID", "client_id": "number5"}
    idtoken = server.id_token_as_signed_jwt(session)
    csr = CheckSessionRequest(id_token=idtoken)

    info = server.check_session_endpoint(request=csr.to_urlencoded())
    print info
    idt = IdToken().deserialize(info.message, "json")
    print idt.keys()
    assert _eq(idt.keys(), ['sub', 'aud', 'iss', 'acr', 'exp', 'iat'])
    assert idt["iss"] == server.name
Esempio n. 8
0
    def _faulty_id_token(self):
        idval = {'nonce': 'KUEYfRM2VzKDaaKD', 'sub': 'EndUserSubject',
                 'iss': 'https://alpha.cloud.nds.rub.de', 'exp': 1420823073,
                 'iat': 1420822473, 'aud': 'TestClient'}
        idts = IdToken(**idval)

        _signed_jwt = idts.to_jwt(key=[SYMKey(key="TestPassword")],
                                  algorithm="HS256")

        # Mess with the signed id_token
        p = _signed_jwt.split(".")
        p[2] = "aaa"

        return ".".join(p)
Esempio n. 9
0
    def test_wrong_alg(self):
        idval = {'nonce': 'KUEYfRM2VzKDaaKD', 'sub': 'EndUserSubject',
                 'iss': 'https://alpha.cloud.nds.rub.de', 'exp': 1420823073,
                 'iat': 1420822473, 'aud': 'TestClient'}
        idts = IdToken(**idval)
        key = SYMKey(key="TestPassword")
        _signed_jwt = idts.to_jwt(key=[key], algorithm="HS256")

        _info = {"access_token": "accessTok", "id_token": _signed_jwt,
                 "token_type": "Bearer", "expires_in": 3600}

        at = AccessTokenResponse(**_info)
        with pytest.raises(WrongSigningAlgorithm):
            at.verify(key=[key], algs={"sign": "HS512"})
Esempio n. 10
0
def test_id_token():
    idt = IdToken(
        **{
            "sub": "553df2bcf909104751cfd8b2",
            "aud": ["5542958437706128204e0000", "554295ce3770612820620000"],
            "auth_time": 1441364872,
            "azp": "554295ce3770612820620000",
            "at_hash": "L4Ign7TCAD_EppRbHAuCyw",
            "iat": 1441367116,
            "exp": 1441374316,
            "iss": "https://sso.qa.7pass.ctf.prosiebensat1.com"
        })

    idt.verify()
    def test_session_expiration_set_to_configured_lifetime(
            self, time_mock, utc_time_sans_frac_mock):
        timestamp = time.mktime(datetime(2017, 1, 1).timetuple())
        time_mock.return_value = timestamp
        utc_time_sans_frac_mock.return_value = int(timestamp)

        exp_time = 10
        state = 'test_state'
        nonce = 'test_nonce'
        id_token = IdToken(iss=self.PROVIDER_BASEURL,
                           aud=self.CLIENT_ID,
                           sub='sub1',
                           exp=int(timestamp) + exp_time,
                           iat=int(timestamp),
                           nonce=nonce)
        token_response = {
            'access_token': 'test',
            'token_type': 'Bearer',
            'id_token': id_token.to_jwt()
        }
        token_endpoint = self.PROVIDER_BASEURL + '/token'
        responses.add(responses.POST, token_endpoint, json=token_response)

        session_lifetime = 1234
        self.app.config['PERMANENT_SESSION_LIFETIME'] = session_lifetime
        self.init_app(
            provider_metadata_extras={'token_endpoint': token_endpoint})

        with self.app.test_client() as client:
            with client.session_transaction() as session:
                UserSession(session, self.PROVIDER_NAME)
                session['destination'] = '/'
                session['state'] = state
                session['nonce'] = nonce
            resp = client.get('/redirect_uri?state={}&code=test'.format(state))

        cookies = SimpleCookie()
        cookies.load(resp.headers['Set-Cookie'])
        session_cookie_expiration = cookies[
            self.app.config['SESSION_COOKIE_NAME']]['expires']
        try:
            parsed_expiration = datetime.strptime(session_cookie_expiration,
                                                  '%a, %d-%b-%Y %H:%M:%S GMT')
        except ValueError:
            parsed_expiration = datetime.strptime(session_cookie_expiration,
                                                  '%a, %d %b %Y %H:%M:%S GMT')
        cookie_lifetime = (parsed_expiration -
                           datetime.utcnow()).total_seconds()
        assert cookie_lifetime == pytest.approx(session_lifetime, abs=1)
Esempio n. 12
0
    def _create_signed_id_token(self,
                                client_id,  # type: str
                                sub,  # type: str
                                user_claims=None,  # type: Optional[Mapping[str, Union[str, List[str]]]]
                                nonce=None,  # type: Optional[str]
                                authorization_code=None,  # type: Optional[str]
                                access_token_value=None,  # type: Optional[str]
                                extra_id_token_claims=None):  # type: Optional[Mappings[str, Union[str, List[str]]]]
        # type: (...) -> str
        """
        Creates a signed ID Token.
        :param client_id: who the ID Token is intended for
        :param sub: who the ID Token is regarding
        :param user_claims: any claims about the user to be included
        :param nonce: nonce from the authentication request
        :param authorization_code: the authorization code issued together with this ID Token
        :param access_token_value: the access token issued together with this ID Token
        :param extra_id_token_claims: any extra claims that should be included in the ID Token
        :return: a JWS, containing the ID Token as payload
        """

        alg = self.clients[client_id].get('id_token_signed_response_alg',
                                          self.configuration_information['id_token_signing_alg_values_supported'][0])
        args = {}

        hash_alg = 'HS{}'.format(alg[-3:])
        if authorization_code:
            args['c_hash'] = jws.left_hash(authorization_code.encode('utf-8'), hash_alg)
        if access_token_value:
            args['at_hash'] = jws.left_hash(access_token_value.encode('utf-8'), hash_alg)

        if user_claims:
            args.update(user_claims)

        if extra_id_token_claims:
            args.update(extra_id_token_claims)

        id_token = IdToken(iss=self.configuration_information['issuer'],
                           sub=sub,
                           aud=client_id,
                           iat=time.time(),
                           exp=time.time() + self.id_token_lifetime,
                           **args)

        if nonce:
            id_token['nonce'] = nonce

        logger.debug('signed id_token with kid=%s using alg=%s', self.signing_key, alg)
        return id_token.to_jwt([self.signing_key], alg)
    def test_logout_handles_provider_without_end_session_endpoint(self):
        authn = self.init_app()
        id_token = IdToken(**{'sub': 'sub1', 'nonce': 'nonce'})
        logout_view_mock = self.get_view_mock()
        with self.app.test_request_context('/logout'):
            UserSession(flask.session, self.PROVIDER_NAME).update(
                access_token='test_access_token',
                id_token=id_token.to_dict(),
                id_token_jwt=id_token.to_jwt(),
                userinfo={'sub': 'user1'})

            logout_result = authn.oidc_logout(logout_view_mock)()
            assert all(k not in flask.session for k in UserSession.KEYS)

        self.assert_view_mock(logout_view_mock, logout_result)
Esempio n. 14
0
    def test_wrong_alg(self):
        _now = time_util.utc_time_sans_frac()
        idval = {'nonce': 'KUEYfRM2VzKDaaKD', 'sub': 'EndUserSubject',
                 'iss': 'https://alpha.cloud.nds.rub.de', 'exp': _now + 3600,
                 'iat': _now, 'aud': 'TestClient'}
        idts = IdToken(**idval)
        key = SYMKey(key="TestPassword")
        _signed_jwt = idts.to_jwt(key=[key], algorithm="HS256")

        _info = {"access_token": "accessTok", "id_token": _signed_jwt,
                 "token_type": "Bearer", "expires_in": 3600}

        at = AccessTokenResponse(**_info)
        with pytest.raises(WrongSigningAlgorithm):
            at.verify(key=[key], algs={"sign": "HS512"})
Esempio n. 15
0
    def test_session_expiration_set_to_id_token_exp(self):
        token_endpoint = ISSUER + '/token'
        userinfo_endpoint = ISSUER + '/userinfo'
        exp_time = 10
        epoch_int = int(time.mktime(datetime(2017, 1, 1).timetuple()))
        id_token = IdToken(
            **{
                'sub': 'sub1',
                'iat': epoch_int,
                'iss': ISSUER,
                'aud': 'foo',
                'nonce': 'test',
                'exp': epoch_int + exp_time
            })
        token_response = {
            'access_token': 'test',
            'token_type': 'Bearer',
            'id_token': id_token.to_jwt()
        }
        userinfo_response = {'sub': 'sub1'}
        responses.add(responses.POST,
                      token_endpoint,
                      body=json.dumps(token_response),
                      content_type='application/json')
        responses.add(responses.POST,
                      userinfo_endpoint,
                      body=json.dumps(userinfo_response),
                      content_type='application/json')
        authn = OIDCAuthentication(self.app,
                                   provider_configuration_info={
                                       'issuer': ISSUER,
                                       'token_endpoint': token_endpoint,
                                       'userinfo_endpoint': userinfo_endpoint
                                   },
                                   client_registration_info={
                                       'client_id': 'foo',
                                       'client_secret': 'foo'
                                   })

        self.app.config.update({'SESSION_PERMANENT': True})
        with self.app.test_request_context(
                '/redirect_uri?state=test&code=test'):
            flask.session['destination'] = '/'
            flask.session['state'] = 'test'
            flask.session['nonce'] = 'test'
            authn._handle_authentication_response()
            assert flask.session.permanent
            assert int(flask.session.permanent_session_lifetime) == exp_time
Esempio n. 16
0
    def test_server_authorization_endpoint_id_token(self):
        bib = {"scope": ["openid"],
               "state": "id-6da9ca0cc23959f5f33e8becd9b08cae",
               "redirect_uri": "http://localhost:8087/authz",
               "response_type": ["code", "id_token"],
               "client_id": "a1b2c3",
               "nonce": "Nonce",
               "prompt": ["none"]}

        req = AuthorizationRequest(**bib)
        areq = AuthorizationRequest(response_type="code",
                                    client_id="client_1",
                                    redirect_uri="http://example.com/authz",
                                    scope=["openid"], state="state000")

        sdb = self.server.sdb
        ae = AuthnEvent("userX")
        sid = sdb.create_authz_session(ae, areq)
        sdb.do_sub(sid)
        _info = sdb[sid]
        # All this is jut removed when the id_token is constructed
        # The proper information comes from the session information
        _user_info = IdToken(iss="https://foo.example.om", sub="foo",
                             aud=bib["client_id"], exp=epoch_in_a_while(minutes=10),
                             acr="2", nonce=bib["nonce"])

        print self.server.keyjar.issuer_keys
        print _user_info.to_dict()
        idt = self.server.id_token_as_signed_jwt(_info, access_token="access_token",
                                                 user_info=_user_info)

        req["id_token"] = idt
        query_string = req.to_urlencoded()

        # client_id not in id_token["aud"] so login required
        resp = self.server.authorization_endpoint(request=query_string, cookie="FAIL")

        print resp
        assert "error=login_required" in resp.message

        req["client_id"] = "client_1"
        query_string = req.to_urlencoded()

        # client_id is in id_token["aud"] so no login required
        resp = self.server.authorization_endpoint(request=query_string, cookie="FAIL")

        print resp.message
        assert resp.message.startswith("http://localhost:8087/authz")
Esempio n. 17
0
    def test_complete_auth_token_idtoken_cipher_downgrade(self):
        _state = "state0"
        self.consumer.consumer_config["response_type"] = ["id_token", "token"]
        self.consumer.provider_info = ProviderConfigurationResponse(
            issuer="https://example.com")  # abs min
        self.consumer.authz_req = {}  # Store AuthzReq with state as key

        args = {
            "client_id": self.consumer.client_id,
            "response_type": self.consumer.consumer_config["response_type"],
            "scope": ["openid"],
            "nonce": "nonce",
        }
        token = IdToken(
            iss="https://example.com",
            aud="client_1",
            sub="some_sub",
            exp=1565348600,
            iat=1565348300,
            nonce="nonce",
        )
        # Downgrade the algorithm to `none`
        location = (
            "https://example.com/cb?state=state0&access_token=token&token_type=bearer&"
            "scope=openid&id_token={}".format(
                token.to_jwt(key=KC_RSA.keys(), algorithm="none")))
        with responses.RequestsMock() as rsps:
            rsps.add(
                responses.GET,
                "https://example.com/authorization",
                status=302,
                headers={"location": location},
            )
            result = self.consumer.do_authorization_request(state=_state,
                                                            request_args=args)
            query = parse_qs(urlparse(result.request.url).query)
            assert query["client_id"] == ["client_1"]
            assert query["scope"] == ["openid"]
            assert query["response_type"] == ["id_token token"]
            assert query["state"] == ["state0"]
            assert query["nonce"] == ["nonce"]
            assert query["redirect_uri"] == ["https://example.com/cb"]

        parsed = urlparse(result.headers["location"])

        with freeze_time("2019-08-09 11:00:00"):
            with pytest.raises(WrongSigningAlgorithm):
                self.consumer.parse_authz(query=parsed.query)
Esempio n. 18
0
 def test_oidc_logout_redirects_to_provider(self):
     end_session_endpoint = 'https://provider.example.com/end_session'
     post_logout_uri = 'https://client.example.com/post_logout'
     authn = OIDCAuthentication(self.app,
                                provider_configuration_info={'issuer': ISSUER,
                                                             'end_session_endpoint': end_session_endpoint},
                                client_registration_info={'client_id': 'foo',
                                                          'post_logout_redirect_uris': [post_logout_uri]})
     callback_mock = MagicMock()
     callback_mock.__name__ = 'test_callback'  # required for Python 2
     id_token = IdToken(**{'sub': 'sub1', 'nonce': 'nonce'})
     with self.app.test_request_context('/logout'):
         flask.session['id_token_jwt'] = id_token.to_jwt()
         resp = authn.oidc_logout(callback_mock)()
     assert resp.status_code == 303
     assert not callback_mock.called
Esempio n. 19
0
    def test_logout_handles_provider_without_end_session_endpoint(self):
        post_logout_uri = 'https://client.example.com/post_logout'
        authn = OIDCAuthentication(self.app,
                                   provider_configuration_info={'issuer': ISSUER},
                                   client_registration_info={'client_id': 'foo',
                                                             'post_logout_redirect_uris': [post_logout_uri]})
        id_token = IdToken(**{'sub': 'sub1', 'nonce': 'nonce'})
        with self.app.test_request_context('/logout'):
            flask.session['access_token'] = 'abcde'
            flask.session['userinfo'] = {'foo': 'bar', 'abc': 'xyz'}
            flask.session['id_token'] = id_token.to_dict()
            flask.session['id_token_jwt'] = id_token.to_jwt()
            end_session_redirect = authn._logout()

            assert all(k not in flask.session for k in ['access_token', 'userinfo', 'id_token', 'id_token_jwt'])
            assert end_session_redirect is None
Esempio n. 20
0
    def test_token_endpoint_with_extra_claims(
            self, context, frontend_config_with_extra_id_token_claims,
            authn_req):
        frontend = self.create_frontend(
            frontend_config_with_extra_id_token_claims)

        user_id = "test_user"
        self.insert_client_in_client_db(frontend, authn_req["redirect_uri"])
        self.insert_user_in_user_db(frontend, user_id)
        authn_req["response_type"] = "code"
        authn_resp = frontend.provider.authorize(authn_req, user_id)

        context.request = AccessTokenRequest(
            redirect_uri=authn_req["redirect_uri"],
            code=authn_resp["code"]).to_dict()
        credentials = "{}:{}".format(CLIENT_ID, CLIENT_SECRET)
        basic_auth = urlsafe_b64encode(
            credentials.encode("utf-8")).decode("utf-8")
        context.request_authorization = "Basic {}".format(basic_auth)

        response = frontend.token_endpoint(context)
        parsed = AccessTokenResponse().deserialize(response.message, "json")
        assert parsed["access_token"]

        id_token = IdToken().from_jwt(parsed["id_token"],
                                      key=[frontend.signing_key])
        assert id_token["email"] == "*****@*****.**"
Esempio n. 21
0
    def do_post_logout_redirect(self, end_session_request):
        # type: (oic.oic.message.EndSessionRequest) -> oic.oic.message.EndSessionResponse
        if 'post_logout_redirect_uri' not in end_session_request:
            return None

        client_id = None
        if 'id_token_hint' in end_session_request:
            id_token = IdToken().from_jwt(end_session_request['id_token_hint'],
                                          key=[self.signing_key])
            client_id = id_token['aud'][0]

        if 'post_logout_redirect_uri' in end_session_request:
            if not client_id:
                return None
            if not end_session_request[
                    'post_logout_redirect_uri'] in self.clients[client_id].get(
                        'post_logout_redirect_uris', []):
                return None

        end_session_response = EndSessionResponse()
        if 'state' in end_session_request:
            end_session_response['state'] = end_session_request['state']

        return end_session_response.request(
            end_session_request['post_logout_redirect_uri'])
Esempio n. 22
0
def test_id_token():
    idt = IdToken(**{
        "sub": "553df2bcf909104751cfd8b2",
        "aud": [
            "5542958437706128204e0000",
            "554295ce3770612820620000"
        ],
        "auth_time": 1441364872,
        "azp": "554295ce3770612820620000",
        "at_hash": "L4Ign7TCAD_EppRbHAuCyw",
        "iat": 1441367116,
        "exp": 1441374316,
        "iss": "https://sso.qa.7pass.ctf.prosiebensat1.com"
    })

    idt.verify()
Esempio n. 23
0
    def test_hybrid_flow(self):
        self.authn_request_args['response_type'] = 'code id_token token'
        auth_req = AuthorizationRequest().from_dict(self.authn_request_args)
        resp = self.provider.authorize(auth_req,
                                       TEST_USER_ID,
                                       extra_id_token_claims={'foo': 'bar'})

        assert resp['state'] == self.authn_request_args['state']
        assert resp['code'] in self.provider.authz_state.authorization_codes

        assert resp['access_token'] in self.provider.authz_state.access_tokens
        assert resp[
            'expires_in'] == self.provider.authz_state.access_token_lifetime
        assert resp['token_type'] == 'Bearer'

        id_token = IdToken().from_jwt(resp['id_token'],
                                      key=[self.provider.signing_key])
        assert_id_token_base_claims(resp['id_token'],
                                    self.provider.signing_key, self.provider,
                                    self.authn_request_args)
        assert id_token["c_hash"] == jws.left_hash(
            resp['code'].encode('utf-8'), 'HS256')
        assert id_token["at_hash"] == jws.left_hash(
            resp['access_token'].encode('utf-8'), 'HS256')
        assert id_token['foo'] == 'bar'
Esempio n. 24
0
    def test_handle_authn_response_returns_id_token_for_verified_affiliation(
            self, signing_key_path, context, scope_value, affiliation):
        authn_req = AuthorizationRequest(
            scope='openid ' + scope_value,
            client_id='client1',
            redirect_uri='https://client.example.com',
            response_type='id_token')
        context.state[self.frontend.name] = {
            'oidc_request': authn_req.to_urlencoded()
        }
        internal_response = InternalResponse(
            AuthenticationInformation(None, str(datetime.now()),
                                      'https://idp.example.com'))
        internal_response.attributes['affiliation'] = [affiliation]
        internal_response.user_id = 'user1'

        resp = self.frontend.handle_authn_response(context, internal_response)
        auth_resp = AuthorizationResponse().from_urlencoded(
            urlparse(resp.message).fragment)

        id_token = IdToken().from_jwt(
            auth_resp['id_token'],
            key=[RSAKey(key=rsa_load(signing_key_path))])
        assert id_token['iss'] == self.frontend.base_url
        assert id_token['aud'] == ['client1']
        assert id_token['auth_time'] == internal_response.auth_info.timestamp
Esempio n. 25
0
def test_id_token():
    _now = time_util.utc_time_sans_frac()

    idt = IdToken(
        **{
            "sub": "553df2bcf909104751cfd8b2",
            "aud": ["5542958437706128204e0000", "554295ce3770612820620000"],
            "auth_time": 1441364872,
            "azp": "554295ce3770612820620000",
            "at_hash": "L4Ign7TCAD_EppRbHAuCyw",
            "iat": _now,
            "exp": _now + 3600,
            "iss": "https://sso.qa.7pass.ctf.prosiebensat1.com",
        })

    idt.verify()
Esempio n. 26
0
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)
Esempio n. 27
0
 def test_configurable_userinfo_endpoint_method_is_used(self, method):
     state = 'state'
     nonce = 'nonce'
     sub = 'foobar'
     authn = OIDCAuthentication(
         self.app,
         provider_configuration_info={
             'issuer': ISSUER,
             'token_endpoint': '/token'
         },
         client_registration_info={'client_id': 'foo'},
         userinfo_endpoint_method=method)
     authn.client.do_access_token_request = MagicMock(
         return_value=AccessTokenResponse(
             **{
                 'id_token': IdToken(**{
                     'sub': sub,
                     'nonce': nonce
                 }),
                 'access_token': 'access_token'
             }))
     userinfo_request_mock = MagicMock(return_value=OpenIDSchema(
         **{'sub': sub}))
     authn.client.do_user_info_request = userinfo_request_mock
     with self.app.test_request_context('/redirect_uri?code=foo&state=' +
                                        state):
         flask.session['state'] = state
         flask.session['nonce'] = nonce
         flask.session['destination'] = '/'
         authn._handle_authentication_response()
     userinfo_request_mock.assert_called_with(method=method, state=state)
Esempio n. 28
0
def test_verify_token_encrypted_no_key():
    idt = IdToken(sub='553df2bcf909104751cfd8b2', aud=['5542958437706128204e0000', '554295ce3770612820620000'],
                  auth_time=1441364872, azp='554295ce3770612820620000')
    kj = KeyJar()
    kb = KeyBundle()
    kb.do_local_der(os.path.join(os.path.dirname(__file__), 'data', 'keys', 'cert.key'), 'some', ['enc', 'sig'])
    kj.add_kb('', kb)
    kj.add_kb('https://sso.qa.7pass.ctf.prosiebensat1.com', kb)

    packer = JWT(kj, lifetime=3600, iss='https://sso.qa.7pass.ctf.prosiebensat1.com', encrypt=True)
    _jws = packer.pack(**idt.to_dict())
    msg = AuthorizationResponse(id_token=_jws)
    # Do not pass they keyjar with keys
    with pytest.raises(VerificationError):
        verify_id_token(msg, keyjar=KeyJar(),
                        iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
                        client_id="554295ce3770612820620000")
Esempio n. 29
0
    def test_verify_id_token_reject_wrong_aud(self, monkeypatch):
        issuer = "https://provider.example.com"
        monkeypatch.setattr(self.client, "provider_info", {"issuer": issuer})
        id_token = IdToken(**dict(iss=issuer, aud=["nobody"]))

        with pytest.raises(OtherError) as exc:
            self.client._verify_id_token(id_token)
        assert "me" in str(exc.value)
Esempio n. 30
0
def test_verify_token_encrypted():
    idt = IdToken(sub='553df2bcf909104751cfd8b2', aud=['5542958437706128204e0000', '554295ce3770612820620000'],
                  auth_time=1441364872, azp='554295ce3770612820620000')
    kj = KeyJar()
    kb = KeyBundle()
    kb.do_local_der(os.path.join(os.path.dirname(__file__), 'data', 'keys', 'cert.key'), 'some', ['enc', 'sig'])
    kj.add_kb('', kb)
    kj.add_kb('https://sso.qa.7pass.ctf.prosiebensat1.com', kb)

    packer = JWT(kj, lifetime=3600, iss='https://sso.qa.7pass.ctf.prosiebensat1.com', encrypt=True)
    _jws = packer.pack(**idt.to_dict())
    msg = AuthorizationResponse(id_token=_jws)
    vidt = verify_id_token(msg, keyjar=kj,
                           iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
                           client_id="554295ce3770612820620000")
    assert vidt
    assert vidt.jwe_header == {'enc': 'A128CBC-HS256', 'alg': 'RSA1_5', 'cty': 'JWT'}
Esempio n. 31
0
def test_faulty_id_token():
    _faulty_signed_jwt = _faulty_id_token()
    try:
        _ = IdToken().from_jwt(_faulty_signed_jwt, key=[SYMKEY])
    except BadSignature:
        pass
    else:
        assert False

    # What if no verification key is given ?
    # Should also result in an exception
    try:
        _ = IdToken().from_jwt(_faulty_signed_jwt)
    except MissingSigningKey:
        pass
    else:
        assert False
Esempio n. 32
0
    def _func(self, environ):
        res = {}
        msg = None
        for msg in environ["item"]:
            if msg.type() == "AuthorizationResponse":
                break

        keys = environ["client"].keystore.get_keys("ver", owner=None)
        idt = IdToken().deserialize(msg["id_token"], "jwt", key=keys)
        if idt.to_dict() == environ["item"][-1].to_dict():
            pass
        else:
            self._status = self.status
            res["message"] = " ".join([
                    "My deserialization of the IDToken differs from what the",
                    "checkID response"])
        return res
Esempio n. 33
0
    def test_authorize_id_token_includes_typ_header(self):
        self.authn_request_args['response_type'] = 'id_token'
        auth_req = AuthorizationRequest().from_dict(self.authn_request_args)
        resp = self.provider.authorize(auth_req, TEST_USER_ID)

        id_token = IdToken().from_jwt(resp['id_token'],
                                      key=[self.provider.signing_key])
        assert id_token.jws_header['typ'] == 'JWT'
Esempio n. 34
0
def test_server_authorization_endpoint_id_token():
    provider = provider_init

    bib = {
        "scope": ["openid"],
        "state": "id-6da9ca0cc23959f5f33e8becd9b08cae",
        "redirect_uri": "http://localhost:8087/authz",
        "response_type": ["code", "id_token"],
        "client_id": "a1b2c3",
        "nonce": "Nonce",
        "prompt": ["none"]
    }

    req = AuthorizationRequest(**bib)
    AREQ = AuthorizationRequest(response_type="code",
                                client_id="client_1",
                                redirect_uri="http://example.com/authz",
                                scope=["openid"],
                                state="state000")

    sdb = SessionDB()
    sid = sdb.create_authz_session("userX", AREQ)

    _info = sdb[sid]
    _user_info = IdToken(iss="https://foo.example.om",
                         sub="foo",
                         aud=bib["client_id"],
                         exp=epoch_in_a_while(minutes=10),
                         acr="2",
                         nonce=bib["nonce"])

    print provider.keyjar.issuer_keys
    print _user_info.to_dict()
    idt = provider.id_token_as_signed_jwt(_info,
                                          access_token="access_token",
                                          user_info=_user_info)

    req["id_token"] = idt

    QUERY_STRING = req.to_urlencoded()

    resp = provider.authorization_endpoint(request=QUERY_STRING)

    print resp
    assert "error=login_required" in resp.message
Esempio n. 35
0
    def test_verify_iat_in_future_expired(self):
        now = time_util.utc_time_sans_frac()

        idt = IdToken(
            **{
                "sub": "553df2bcf909104751cfd8b2",
                "aud":
                ["5542958437706128204e0000", "554295ce3770612820620000"],
                "auth_time": 1441364872,
                "azp": "554295ce3770612820620000",
                "at_hash": "L4Ign7TCAD_EppRbHAuCyw",
                "iat": now + 3600,
                "exp": now,
                "iss": "https://sso.qa.7pass.ctf.prosiebensat1.com",
            })

        with pytest.raises(EXPError):
            idt.verify(skew=7200)
Esempio n. 36
0
    def logout_user(self, subject_identifier=None, end_session_request=None):
        # type: (Optional[str], Optional[oic.oic.message.EndSessionRequest]) -> None
        if not end_session_request:
            end_session_request = EndSessionRequest()
        if 'id_token_hint' in end_session_request:
            id_token = IdToken().from_jwt(end_session_request['id_token_hint'], key=[self.signing_key])
            subject_identifier = id_token['sub']

        self.authz_state.delete_state_for_subject_identifier(subject_identifier)
Esempio n. 37
0
    def _faulty_id_token(self):
        idval = {
            "nonce": "KUEYfRM2VzKDaaKD",
            "sub": "EndUserSubject",
            "iss": "https://alpha.cloud.nds.rub.de",
            "exp": 1420823073,
            "iat": 1420822473,
            "aud": "TestClient",
        }
        idts = IdToken(**idval)

        _signed_jwt = idts.to_jwt(key=[SYMKey(key="TestPassword")], algorithm="HS256")

        # Mess with the signed id_token
        p = _signed_jwt.split(".")
        p[2] = "aaa"

        return ".".join(p)
Esempio n. 38
0
def test_wrong_alg():
    idval = {'nonce': 'KUEYfRM2VzKDaaKD', 'sub': 'EndUserSubject',
             'iss': 'https://alpha.cloud.nds.rub.de', 'exp': 1420823073,
             'iat': 1420822473, 'aud': 'TestClient'}
    idts = IdToken(**idval)
    key = SYMKey(key="TestPassword")
    _signed_jwt = idts.to_jwt(key=[key], algorithm="HS256")

    _info = {"access_token": "accessTok", "id_token": _signed_jwt,
             "token_type": "Bearer", "expires_in": 3600}

    at = AccessTokenResponse(**_info)
    try:
        at.verify(key=[key], algs={"sign": "HS512"})
    except WrongSigningAlgorithm:
        pass
    else:
        raise
    def test_logout_redirects_to_provider_if_end_session_endpoint_is_configured(
            self, post_logout_redirect_uri):
        end_session_endpoint = 'https://provider.example.com/end_session'
        client_metadata = {}
        if post_logout_redirect_uri:
            client_metadata['post_logout_redirect_uris'] = [
                post_logout_redirect_uri
            ]

        authn = self.init_app(provider_metadata_extras={
            'end_session_endpoint': end_session_endpoint
        },
                              client_metadata_extras=client_metadata)
        logout_view_mock = self.get_view_mock()
        id_token = IdToken(**{'sub': 'sub1', 'nonce': 'nonce'})

        # register logout view
        view_func = authn.oidc_logout(logout_view_mock)
        self.app.add_url_rule('/logout', view_func=view_func)

        with self.app.test_request_context('/logout'):
            UserSession(flask.session, self.PROVIDER_NAME).update(
                access_token='test_access_token',
                id_token=id_token.to_dict(),
                id_token_jwt=id_token.to_jwt(),
                userinfo={'sub': 'user1'})
            end_session_redirect = view_func()
            # ensure user session has been cleared
            assert all(k not in flask.session for k in UserSession.KEYS)
            parsed_request = dict(
                parse_qsl(
                    urlparse(end_session_redirect.headers['Location']).query))
            assert parsed_request['state'] == flask.session[
                'end_session_state']

        assert end_session_redirect.status_code == 303
        assert end_session_redirect.location.startswith(end_session_endpoint)
        assert IdToken().from_jwt(parsed_request['id_token_hint']) == id_token

        expected_post_logout_redirect_uri = post_logout_redirect_uri if post_logout_redirect_uri else 'http://{}/logout'.format(
            self.CLIENT_DOMAIN)
        assert parsed_request[
            'post_logout_redirect_uri'] == expected_post_logout_redirect_uri
        assert not logout_view_mock.called
Esempio n. 40
0
def test_check_session_endpoint():
    server = provider_init
    print server.name

#    server.keyjar["number5"] = KeyChain({"hmac":CDB["number5"]["client_secret"]},
#                                        usage=["ver"])

    session = {"sub": "UserID", "client_id": "number5"}
    idtoken = server.id_token_as_signed_jwt(session)
    csr = CheckSessionRequest(id_token=idtoken)
    environ = BASE_ENVIRON.copy()
    environ["QUERY_STRING"] = csr.to_urlencoded()

    info = server.check_session_endpoint(environ, start_response)
    print info
    idt = IdToken().deserialize(info[0], "json")
    print idt.keys()
    assert _eq(idt.keys(), ['sub', 'aud', 'iss', 'acr', 'exp', 'iat'])
    assert idt["iss"] == server.name
Esempio n. 41
0
    def test_faulty_idtoken(self):
        idval = {'nonce': 'KUEYfRM2VzKDaaKD', 'sub': 'EndUserSubject',
                 'iss': 'https://alpha.cloud.nds.rub.de', 'exp': 1420823073,
                 'iat': 1420822473, 'aud': 'TestClient'}
        idts = IdToken(**idval)
        key = SYMKey(key="TestPassword")
        _signed_jwt = idts.to_jwt(key=[key], algorithm="HS256")

        # Mess with the signed id_token
        p = _signed_jwt.split(".")
        p[2] = "aaa"
        _faulty_signed_jwt = ".".join(p)

        _info = {"access_token": "accessTok", "id_token": _faulty_signed_jwt,
                 "token_type": "Bearer", "expires_in": 3600}

        at = AccessTokenResponse(**_info)
        with pytest.raises(BadSignature):
            at.verify(key=[key])
Esempio n. 42
0
def assert_id_token_base_claims(jws, verification_key, provider, auth_req):
    id_token = IdToken().from_jwt(jws, key=[verification_key])
    assert id_token['nonce'] == auth_req['nonce']
    assert id_token['iss'] == ISSUER
    assert provider.authz_state.get_user_id_for_subject_identifier(
        id_token['sub']) == TEST_USER_ID
    assert id_token['iat'] == MOCK_TIME.return_value
    assert id_token['exp'] == id_token['iat'] + provider.id_token_lifetime
    assert TEST_CLIENT_ID in id_token['aud']

    return id_token
Esempio n. 43
0
    def test_faulty_idtoken(self):
        _now = time_util.utc_time_sans_frac()
        idval = {'nonce': 'KUEYfRM2VzKDaaKD', 'sub': 'EndUserSubject',
                 'iss': 'https://alpha.cloud.nds.rub.de', 'exp': _now + 3600,
                 'iat': _now, 'aud': 'TestClient'}
        idts = IdToken(**idval)
        key = SYMKey(key="TestPassword")
        _signed_jwt = idts.to_jwt(key=[key], algorithm="HS256")

        # Mess with the signed id_token
        p = _signed_jwt.split(".")
        p[2] = "aaa"
        _faulty_signed_jwt = ".".join(p)

        _info = {"access_token": "accessTok", "id_token": _faulty_signed_jwt,
                 "token_type": "Bearer", "expires_in": 3600}

        at = AccessTokenResponse(**_info)
        with pytest.raises(BadSignature):
            at.verify(key=[key])
Esempio n. 44
0
def logout(request, next_page=None):
    if not "op" in request.session.keys():
        return auth_logout_view(request, next_page)

    client = CLIENTS[request.session["op"]]

    # User is by default NOT redirected to the app - it stays on an OP page after logout.
    # Here we determine if a redirection to the app was asked for and is possible.
    if next_page is None and "next" in request.GET.keys():
        next_page = request.GET['next']
    if next_page is None and "next" in request.session.keys():
        next_page = request.session['next']
    extra_args = {}
    if "post_logout_redirect_uris" in client.registration_response.keys() and len(
            client.registration_response["post_logout_redirect_uris"]) > 0:
        if next_page is not None:
            # First attempt a direct redirection from OP to next_page
            next_page_url = resolve_url(next_page)
            urls = [url for url in client.registration_response["post_logout_redirect_uris"] if next_page_url in url]
            if len(urls) > 0:
                extra_args["post_logout_redirect_uri"] = urls[0]
            else:
                # It is not possible to directly redirect from the OP to the page that was asked for.
                # We will try to use the redirection point - if the redirection point URL is registered that is.
                next_page_url = resolve_url('openid_logout_cb')
                urls = [url for url in client.registration_response["post_logout_redirect_uris"] if
                        next_page_url in url]
                if len(urls) > 0:
                    extra_args["post_logout_redirect_uri"] = urls[0]
                else:
                    # Just take the first registered URL as a desperate attempt to come back to the application
                    extra_args["post_logout_redirect_uri"] = client.registration_response["post_logout_redirect_uris"][
                        0]
    else:
        # No post_logout_redirect_uris registered at the OP - no redirection to the application is possible anyway
        pass

    # Redirect client to the OP logout page
    try:
        request_args = None
        if 'id_token' in request.session.keys():
            request_args = {'id_token': IdToken(**request.session['id_token'])}
        res = client.do_end_session_request(state=request.session["state"],
                                            extra_args=extra_args, request_args=request_args)
        resp = HttpResponse(content_type=res.headers["content-type"], status=res.status_code, content=res._content)
        for key, val in res.headers.items():
            resp[key] = val
        return resp
    finally:
        # Always remove Django session stuff - even if not logged out from OP. Don't wait for the callback as it may never come.
        auth_logout(request)
        if next_page:
            request.session['next'] = next_page
Esempio n. 45
0
    def test_logout_handles_provider_without_end_session_endpoint(self):
        post_logout_uri = 'https://client.example.com/post_logout'
        authn = OIDCAuthentication(
            self.app,
            provider_configuration_info={'issuer': ISSUER},
            client_registration_info={
                'client_id': 'foo',
                'post_logout_redirect_uris': [post_logout_uri]
            })
        id_token = IdToken(**{'sub': 'sub1', 'nonce': 'nonce'})
        with self.app.test_request_context('/logout'):
            flask.session['access_token'] = 'abcde'
            flask.session['userinfo'] = {'foo': 'bar', 'abc': 'xyz'}
            flask.session['id_token'] = id_token.to_dict()
            flask.session['id_token_jwt'] = id_token.to_jwt()
            end_session_redirect = authn._logout()

            assert all(
                k not in flask.session for k in
                ['access_token', 'userinfo', 'id_token', 'id_token_jwt'])
            assert end_session_redirect is None
Esempio n. 46
0
    def test_authorization_endpoint_id_token(self):
        bib = {
            "scope": ["openid"],
            "state": "id-6da9ca0cc23959f5f33e8becd9b08cae",
            "redirect_uri": "http://localhost:8087/authz",
            "response_type": ["code", "id_token"],
            "client_id": "a1b2c3",
            "nonce": "Nonce",
            "prompt": ["none"]
        }

        req = AuthorizationRequest(**bib)
        areq = AuthorizationRequest(response_type="code",
                                    client_id="client_1",
                                    redirect_uri="http://example.com/authz",
                                    scope=["openid"],
                                    state="state000")

        sdb = self.provider.sdb
        ae = AuthnEvent("userX", "salt")
        sid = sdb.create_authz_session(ae, areq)
        sdb.do_sub(sid, "client_salt")
        _info = sdb[sid]
        # All this is jut removed when the id_token is constructed
        # The proper information comes from the session information
        _user_info = IdToken(iss="https://foo.example.om",
                             sub="foo",
                             aud=bib["client_id"],
                             exp=epoch_in_a_while(minutes=10),
                             acr="2",
                             nonce=bib["nonce"])

        idt = self.provider.id_token_as_signed_jwt(_info,
                                                   access_token="access_token",
                                                   user_info=_user_info)

        req["id_token"] = idt
        query_string = req.to_urlencoded()

        # client_id not in id_token["aud"] so login required
        resp = self.provider.authorization_endpoint(request=query_string,
                                                    cookie="FAIL")
        parsed_resp = parse_qs(urlparse(resp.message).fragment)
        assert parsed_resp["error"][0] == "login_required"

        req["client_id"] = "client_1"
        query_string = req.to_urlencoded()

        # client_id is in id_token["aud"] so no login required
        resp = self.provider.authorization_endpoint(request=query_string,
                                                    cookie="FAIL")

        assert resp.message.startswith("http://localhost:8087/authz")
Esempio n. 47
0
    def _func(self, conv):
        res = {}
        instance = None
        for instance, msg in conv.protocol_response:
            if instance.type() == "AuthorizationResponse":
                break

        kj = conv.client.keyjar
        keys = {}
        for issuer in kj.keys():
            keys.update(kj.get("ver", issuer=issuer))

        idt = IdToken().deserialize(instance["id_token"], "jwt", key=keys)
        if idt.to_dict() == conv.protocol_response[-1][0].to_dict():
            pass
        else:
            self._status = self.status
            res["message"] = " ".join([
                "My deserialization of the IDToken differs from what the",
                "checkID response"])
        return res
Esempio n. 48
0
def test_server_authorization_endpoint_id_token():
    provider = provider_init

    bib = {"scope": ["openid"],
           "state": "id-6da9ca0cc23959f5f33e8becd9b08cae",
           "redirect_uri": "http://localhost:8087/authz",
           "response_type": ["code", "id_token"],
           "client_id": "a1b2c3",
           "nonce": "Nonce",
           "prompt": ["none"]}

    req = AuthorizationRequest(**bib)
    AREQ = AuthorizationRequest(response_type="code",
                                client_id="client_1",
                                redirect_uri="http://example.com/authz",
                                scope=["openid"], state="state000")

    sdb = SessionDB()
    sid = sdb.create_authz_session("username", AREQ)

    _info = sdb[sid]
    _user_info = IdToken(iss="https://foo.example.om", sub="foo",
                         aud=bib["client_id"], exp=epoch_in_a_while(minutes=10),
                        acr="2", nonce=bib["nonce"])

    print provider.keyjar.issuer_keys
    print _user_info.to_dict()
    idt = provider.id_token_as_signed_jwt(_info, access_token="access_token",
                                          user_info=_user_info)

    req["id_token"] = idt

    environ = BASE_ENVIRON.copy()
    environ["QUERY_STRING"] = req.to_urlencoded()

    resp = provider.authorization_endpoint(environ, start_response)

    print resp
    line = resp[0]
    assert "error=login_required" in line
Esempio n. 49
0
def test_verify_id_token_iss_not_in_keyjar():
    idt = IdToken(**{
        "sub": "553df2bcf909104751cfd8b2",
        "aud": [
            "5542958437706128204e0000",
            "554295ce3770612820620000"
            ],
        "auth_time": 1441364872,
        "azp": "554295ce3770612820620000",
        })

    kj = KeyJar()
    kj.add_symmetric("", 'dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ', ['sig'])
    kj.add_symmetric("https://sso.qa.7pass.ctf.prosiebensat1.com",
                     'dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ', ['sig'])
    packer = JWT(kj, sign_alg='HS256', lifetime=3600,
                 iss='https://example.com/op')
    _jws = packer.pack(**idt.to_dict())
    msg = AuthorizationResponse(id_token=_jws)
    with pytest.raises(ValueError):
        verify_id_token(msg, check_hash=True, keyjar=kj,
                        iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
                        client_id="554295ce3770612820620000")
Esempio n. 50
0
def test_verify_id_token():
    idt = IdToken(**{
        "sub": "553df2bcf909104751cfd8b2",
        "aud": [
            "5542958437706128204e0000",
            "554295ce3770612820620000"
            ],
        "auth_time": 1441364872,
        "azp": "554295ce3770612820620000",
        })

    kj = KeyJar()
    kj.add_symmetric("", 'dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ', ['sig'])
    kj.add_symmetric("https://sso.qa.7pass.ctf.prosiebensat1.com",
                     'dYMmrcQksKaPkhdgRNYk3zzh5l7ewdDJ', ['sig'])
    packer = JWT(kj, sign_alg='HS256',
                 iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
                 lifetime=3600)
    _jws = packer.pack(**idt.to_dict())
    msg = AuthorizationResponse(id_token=_jws)
    vidt = verify_id_token(msg, keyjar=kj,
                           iss="https://sso.qa.7pass.ctf.prosiebensat1.com",
                           client_id="554295ce3770612820620000")
    assert vidt
Esempio n. 51
0
    def test_logout(self):
        end_session_endpoint = 'https://provider.example.com/end_session'
        post_logout_uri = 'https://client.example.com/post_logout'
        authn = OIDCAuthentication(self.app,
                                   provider_configuration_info={'issuer': ISSUER,
                                                                'end_session_endpoint': end_session_endpoint},
                                   client_registration_info={'client_id': 'foo',
                                                             'post_logout_redirect_uris': [post_logout_uri]})
        id_token = IdToken(**{'sub': 'sub1', 'nonce': 'nonce'})
        with self.app.test_request_context('/logout'):
            flask.session['access_token'] = 'abcde'
            flask.session['userinfo'] = {'foo': 'bar', 'abc': 'xyz'}
            flask.session['id_token'] = id_token.to_dict()
            flask.session['id_token_jwt'] = id_token.to_jwt()
            end_session_redirect = authn._logout()

            assert all(k not in flask.session for k in ['access_token', 'userinfo', 'id_token', 'id_token_jwt'])

            assert end_session_redirect.status_code == 303
            assert end_session_redirect.headers['Location'].startswith(end_session_endpoint)
            parsed_request = dict(parse_qsl(urlparse(end_session_redirect.headers['Location']).query))
            assert parsed_request['state'] == flask.session['end_session_state']
            assert parsed_request['id_token_hint'] == id_token.to_jwt()
            assert parsed_request['post_logout_redirect_uri'] == post_logout_uri
Esempio n. 52
0
    return s1 == s2

CLIENT_SECRET = "abcdefghijklmnop"
CLIENT_ID = "client_1"

KC_HMAC_VS = KeyBundle({"hmac": "abcdefghijklmnop"}, usage=["ver", "sig"])
KC_RSA = KeyBundle(source="file://../oc3/certs/mycert.key", type="rsa",
                  usage=["ver", "sig"])
KC_HMAC_S = KeyBundle({"hmac": "abcdefghijklmnop"}, usage=["sig"])

KEYJ = KeyJar()
KEYJ[""] = [KC_RSA, KC_HMAC_S]
KEYJ["client_1"] = [KC_HMAC_VS]

IDTOKEN = IdToken(iss="http://oic.example.org/", sub="user_id",
                  aud=CLIENT_ID, exp=utc_time_sans_frac()+86400,
                  nonce="N0nce",
                  iat=time.time())

# ----------------- CLIENT --------------------

class TestOICClient():
    def setup_class(self):
        self.client = Client(CLIENT_ID)
        self.client.redirect_uris = ["http://example.com/redirect"]
        self.client.client_secret = CLIENT_SECRET
        self.client.keyjar[""] = KC_RSA

    def test_areq_1(self):
        ar = self.client.construct_AuthorizationRequest(
            request_args={"response_type":["code"]})
Esempio n. 53
0

CLIENT_SECRET = "abcdefghijklmnop"
CLIENT_ID = "client_1"

KC_SYM_S = KeyBundle({"kty": "oct", "key": "abcdefghijklmnop", "use": "sig"})

_key = rsa_load("../oc3/certs/mycert.key")
KC_RSA = KeyBundle({"key": _key, "kty": "RSA", "use": "sig"})

KEYJ = KeyJar()
KEYJ[""] = [KC_RSA, KC_SYM_S]
KEYJ["client_1"] = [KC_SYM_S]

IDTOKEN = IdToken(iss="http://oic.example.org/", sub="user_id",
                  aud=CLIENT_ID, exp=utc_time_sans_frac() + 86400,
                  nonce="N0nce",
                  iat=time.time())

# ----------------- CLIENT --------------------


class TestOICClient():
    def setup_class(self):
        self.client = Client(CLIENT_ID)
        self.client.redirect_uris = ["http://example.com/redirect"]
        self.client.client_secret = CLIENT_SECRET
        self.client.keyjar[""] = KC_RSA

    def test_areq_1(self):
        ar = self.client.construct_AuthorizationRequest(
            request_args={"response_type": ["code"]})
Esempio n. 54
0
from jwkest.jws import alg2keytype
from oic.oic.message import IdToken
from oic.utils.keyio import KeyBundle, KeyJar

__author__ = 'rohe0002'

b0 = KeyBundle(source="http://localhost:8090/exports/jwk.json", src_type="jwk",
               usage=["ver", "dec", "sig"])

b1 = KeyBundle(source="http://localhost:8090/exports/cert.pem", src_type="x509",
               usage=["ver", "dec", "sig"])

print b0
print b1

kj = KeyJar()

kj["foobar"] = [b0, b1]

idt = IdToken().from_dict({"user_id": "diana", "aud": "uo5nowsdL3ck",
                           "iss": "https://localhost:8092", "acr": "2",
                           "exp": 1354442188, "iat": 1354359388})

ckey = kj.get_signing_key(alg2keytype("RS256"), "foobar")
_signed_jwt = idt.to_jwt(key=ckey, algorithm="RS256")
Esempio n. 55
0
CLIENT_SECRET = "abcdefghijklmnop"
CLIENT_ID = "client_1"

rsapub = rsa_load("../oc3/certs/mycert.key")

KEYS = [
    ["abcdefghijklmnop", "hmac", "ver", "client_1"],
    ["abcdefghijklmnop", "hmac", "sig", "client_1"],
    [rsapub, "rsa", "sig", "."],
    [rsapub, "rsa", "ver", "."],
]

SIGN_KEY = {"hmac": ["abcdefghijklmnop"]}
IDTOKEN = IdToken(
    iss="http://oic.example.org/", user_id="user_id", aud=CLIENT_ID, exp=time_sans_frac() + 86400, nonce="N0nce"
)

# ----------------- CLIENT --------------------


class TestOICClient:
    def setup_class(self):
        self.client = Client(CLIENT_ID)
        self.client.redirect_uris = ["http://example.com/redirect"]
        self.client.client_secret = CLIENT_SECRET
        self.client.keystore.set_sign_key(rsapub, "rsa")
        self.client.keystore.set_verify_key(rsapub, "rsa")

    def test_areq_1(self):
        ar = self.client.construct_AuthorizationRequest(request_args={"response_type": ["code"]})
Esempio n. 56
0
    def make_id_token(self, session, loa="2", issuer="",
                      keytype="rsa", code=None, access_token=None,
                      user_info=None):
        #defaults
        inawhile = {"days": 1}
        # Handle the idtoken_claims
        extra = {}
        try:
            oidreq = OpenIDRequest().deserialize(session["oidreq"], "json")
            itc = oidreq["id_token"]
            logger.debug("ID Token claims: %s" % itc.to_dict())
            try:
                inawhile = {"seconds": itc["max_age"]}
            except KeyError:
                inawhile = {}
            if "claims" in itc:
                for key, val in itc["claims"].items():
                    if key == "auth_time":
                        extra["auth_time"] = time_util.utc_time_sans_frac()
                    elif key == "acr":
                        #["2","http://id.incommon.org/assurance/bronze"]
                        extra["acr"] = verify_acr_level(val, loa)
        except KeyError:
            pass

        if user_info is None:
            _args = {}
        else:
            _args = user_info.to_dict()

        # Make sure that there are no name clashes
        for key in ["iss", "user_id", "aud", "exp", "acr", "nonce",
                    "auth_time"]:
            try:
                del _args[key]
            except KeyError:
                pass

        if code:
            _args["c_hash"] = jwt.left_hash(code, "HS256")
        if access_token:
            _args["at_hash"] = jwt.left_hash(access_token, "HS256")

        idt = IdToken(iss=issuer, user_id=session["user_id"],
                      aud = session["client_id"],
                      exp = time_util.epoch_in_a_while(**inawhile), acr=loa,
                      **_args)

        for key, val in extra.items():
            idt[key] = val

        if "nonce" in session:
            idt.nonce = session["nonce"]

        # sign with clients secret key
        _keystore = self.keystore
        if keytype == "hmac":
            ckey = {"hmac":
                        _keystore.get_sign_key("hmac",
                                               owner=session["client_id"])}
            algo = "HS256"
        elif keytype == "rsa": # own asymmetric key
            algo = "RS256"
            ckey = {"rsa": _keystore.get_sign_key("rsa")}
        else:
            algo = "ES256"
            ckey = {"ec":_keystore.get_sign_key("ec")}

        logger.debug("Sign idtoken with '%s'" % (ckey,))

        return idt.to_jwt(key=ckey, algorithm=algo)
Esempio n. 57
0
    def make_id_token(self, session, loa="2", issuer="",
                      alg="RS256", code=None, access_token=None,
                      user_info=None):
        """

        :param session: Session information
        :param loa: Level of Assurance/Authentication context
        :param issuer: My identifier
        :param alg: Which signing algorithm to use for the IdToken
        :param code: Access grant
        :param access_token: Access Token
        :param user_info: If user info are to be part of the IdToken
        :return: IDToken instance
        """
        #defaults
        inawhile = {"days": 1}
        # Handle the idtoken_claims
        extra = {}
        itc = self.id_token_claims(session)
        if itc:
            try:
                inawhile = {"seconds": itc["max_age"]}
            except KeyError:
                inawhile = {}
            if "claims" in itc:
                for key, val in itc["claims"].items():
                    if key == "auth_time":
                        extra["auth_time"] = time_util.utc_time_sans_frac()
                    elif key == "acr":
                        #["2","http://id.incommon.org/assurance/bronze"]
                        extra["acr"] = verify_acr_level(val, loa)

        if user_info is None:
            _args = {}
        else:
            _args = user_info.to_dict()

        # Make sure that there are no name clashes
        for key in ["iss", "sub", "aud", "exp", "acr", "nonce",
                    "auth_time"]:
            try:
                del _args[key]
            except KeyError:
                pass

        halg = "HS%s" % alg[-3:]

        if code:
            _args["c_hash"] = jws.left_hash(code, halg)
        if access_token:
            _args["at_hash"] = jws.left_hash(access_token, halg)

        idt = IdToken(iss=issuer, sub=session["sub"],
                      aud = session["client_id"],
                      exp = time_util.epoch_in_a_while(**inawhile), acr=loa,
                      iat = time_util.utc_now(),
                      **_args)

        for key, val in extra.items():
            idt[key] = val

        if "nonce" in session:
            idt.nonce = session["nonce"]

        return idt
    def __call__(self, request):
        data = request.body

        req = self.provider.parse_token_request(body=data)

        if 'grant_type' not in req:
            return (400, {}, 'Missing grant_type')

        if req['grant_type'] == 'authorization_code':
            authz_code = req['code']
            authz_info = self.provider.authz_codes[authz_code]
            auth_req = authz_info['auth_req']
            client_id = auth_req['client_id']

            if authz_info['used']:
                raise Exception('code already used')
                return (400, {}, 'Invalid authorization code')

            if authz_info['exp'] < time.time():
                raise Exception('code expired')
                return (400, {}, 'Invalid authorization code')

            authz_info['used'] = True

            access_token = {
                'value': rndstr(),
                'expires_in': self.provider.access_token_lifetime,
                'type': 'Bearer'
            }

            at_value = access_token['value']

            self.provider.access_tokens[at_value] = {
                'iat': time.time(),
                'exp': time.time() + self.provider.access_token_lifetime,
                'sub': 'test-sub',
                'client_id': client_id,
                'aud': [client_id],
                'scope': authz_info['granted_scope'],
                'granted_scope': authz_info['granted_scope'],
                'token_type': access_token['type'],
                'auth_req': auth_req
            }

            resp = AccessTokenResponse()
            resp['access_token'] = at_value
            resp['token_type'] = access_token['type']
            resp['expires_in'] = access_token['expires_in']

            resp['refresh_token'] = None

            args = {
                'c_hash': jws.left_hash(authz_code.encode('utf-8'), 'HS256'),
                'at_hash': jws.left_hash(at_value.encode('utf-8'), 'HS256'),
            }

            id_token = IdToken(
                iss=self.config['issuer'],
                sub='test-sub',
                aud=client_id,
                iat=time.time(),
                exp=time.time() + self.provider.id_token_lifetime,
                **args)

            if 'nonce' in auth_req:
                id_token['nonce'] = auth_req['nonce']

            resp['id_token'] = id_token.to_jwt(
                [self.provider.signing_key], 'RS256')

            json_data = resp.to_json()

            return (
                200,
                {
                    'Content-Type': 'application/json',
                    'Cache-Control': 'no-store',
                    'Pragma': 'no-cache',
                },
                json_data
            )

        return (400, {}, 'Unsupported grant_type')