Exemple #1
0
    def refresh_token_grant_type(self, areq):
        at = self.token_handler.refresh_access_token(self.baseurl,
                                                     areq['access_token'],
                                                     'refresh_token')

        atr = AccessTokenResponse(**by_schema(AccessTokenResponse, **at))
        return Response(atr.to_json(), content="application/json")
Exemple #2
0
    def code_grant_type(self, areq):
        # assert that the code is valid
        try:
            _info = self.sdb[areq["code"]]
        except KeyError:
            err = TokenErrorResponse(error="invalid_grant",
                                     error_description="Unknown access grant")
            return Response(err.to_json(),
                            content="application/json",
                            status="401 Unauthorized")

        authzreq = json.loads(_info['authzreq'])
        if 'code_verifier' in areq:
            try:
                _method = authzreq['code_challenge_method']
            except KeyError:
                _method = 'S256'

            resp = self.verify_code_challenge(areq['code_verifier'],
                                              authzreq['code_challenge'],
                                              _method)
            if resp:
                return resp

        if 'state' in areq:
            if self.sdb[areq['code']]['state'] != areq['state']:
                err = TokenErrorResponse(error="unauthorized_client")
                return Unauthorized(err.to_json(), content="application/json")

        resp = self.token_scope_check(areq, _info)
        if resp:
            return resp

        # If redirect_uri was in the initial authorization request
        # verify that the one given here is the correct one.
        if "redirect_uri" in _info:
            assert areq["redirect_uri"] == _info["redirect_uri"]

        issue_refresh = False
        if 'scope' in authzreq and 'offline_access' in authzreq['scope']:
            if authzreq['response_type'] == 'code':
                issue_refresh = True

        try:
            _tinfo = self.sdb.upgrade_to_token(areq["code"],
                                               issue_refresh=issue_refresh)
        except AccessCodeUsed:
            err = TokenErrorResponse(error="invalid_grant",
                                     error_description="Access grant used")
            return Response(err.to_json(),
                            content="application/json",
                            status="401 Unauthorized")

        logger.debug("_tinfo: %s" % _tinfo)

        atr = AccessTokenResponse(**by_schema(AccessTokenResponse, **_tinfo))

        logger.debug("AccessTokenResponse: %s" % atr)

        return Response(atr.to_json(), content="application/json")
Exemple #3
0
def test_flow():
    cli = PoPClient()

    # Client creates access token request
    atreq = AccessTokenRequest(grant_type="authorization_code",
                               code="SplxlOBeZQQYbYS6WxSbIA",
                               redirect_uri="https://client.example.com/cb")

    # adds key information, also connects the new key to the state value used
    atreq = cli.update(atreq, 'state')

    assert 'key' in atreq

    pas = PoPAS('https://example.com/as')
    pas.keyjar = init_keyjar()
    # Key is in the JSON string representation
    finger_print = pas.store_key(json.loads(atreq['key']))
    access_token = pas.create_access_token(finger_print)
    # The AS constructs the access token response
    atrsp = AccessTokenResponse(access_token=access_token,
                                token_type="bearer",
                                state='state')

    # The client receives the response and connects the key to the access token
    cli.handle_access_token_response(atrsp)

    assert access_token in cli.token2key
    assert cli.token2key[access_token] == cli.state2key['state']

    # Time for the client to access the Resource Server
    url = 'https://example.com/rs?foo=bar&format=json'
    headers = {'Content-type': 'application/www-form-encoded'}
    body = 'access_token={}'.format(access_token)

    # creates the POP token using signed HTTP request
    cb = PoPCallBack(cli.token2key[atrsp['access_token']], cli.alg)
    kwargs = cb('POST', url, headers=headers, body=body)
    assert kwargs['Authorization'].startswith('pop ')
    pop_token = kwargs['Authorization'][4:]

    assert len(pop_token.split('.')) == 3  # simple JWS check

    # now to the RS
    rs = PoPRS()

    # The AS gets a token introspection request
    # verifies the correctness of the access token
    # and if correct constructs the token introspection response
    tir = pas.token_introspection(atrsp['access_token'])

    # The RS binds the received key to the access token
    rs.store_key(access_token, tir)

    # The RS verifies the correctness of the POP token
    res = rs.eval_signed_http_request(pop_token, access_token, 'POST', url,
                                      headers, body)

    # YEY :-)
    assert res
Exemple #4
0
    def do_access_token_response(self, access_token, atinfo, state,
                                 refresh_token=None):
        _tinfo = {'access_token': access_token, 'expires_in': atinfo['exp'],
                  'token_type': 'bearer', 'state': state}
        try:
            _tinfo['scope'] = atinfo['scope']
        except KeyError:
            pass

        if refresh_token:
            _tinfo['refresh_token'] = refresh_token

        return AccessTokenResponse(**by_schema(AccessTokenResponse, **_tinfo))