def token_endpoint(self, authn="", **kwargs): """ This is where clients come to get their access tokens """ logger.debug("- token -") body = kwargs["request"] logger.debug("body: %s" % body) areq = AccessTokenRequest().deserialize(body, "urlencoded") try: self.client_authn(self, areq, authn) except FailedAuthentication as err: logger.error(err) err = TokenErrorResponse(error="unauthorized_client", error_description="%s" % err) return Response(err.to_json(), content="application/json", status_code=401) logger.debug("AccessTokenRequest: %s" % areq) _grant_type = areq["grant_type"] if _grant_type == "authorization_code": return self.code_grant_type(areq) elif _grant_type == 'client_credentials': return self.client_credentials_grant_type(areq) elif _grant_type == 'password': return self.password_grant_type(areq) elif _grant_type == 'refresh_token': return self.refresh_token_grant_type(areq) else: raise UnSupported('grant_type: {}'.format(_grant_type))
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
def test_private_key_jwt(): cli = Client("FOO") cli.token_endpoint = "https://example.com/token" cli.keyjar[""] = KC_RSA cis = AccessTokenRequest() pkj = PrivateKeyJWT(cli) http_args = pkj.construct(cis, algorithm="RS256") assert http_args == {} cas = cis["client_assertion"] header, claim, crypto, header_b64, claim_b64 = jwkest.unpack(cas) jso = json.loads(claim) assert _eq(jso.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"]) print header assert header == {'alg': 'RS256'}
def test_client_secret_jwt(): cli = Client("Foo") cli.token_endpoint = "https://example.com/token" cli.client_secret = "foobar" csj = ClientSecretJWT(cli) cis = AccessTokenRequest() http_args = csj.construct(cis, algorithm="HS256") print http_args assert cis["client_assertion_type"] == JWT_BEARER assert "client_assertion" in cis cas = cis["client_assertion"] _jwt = JWT().unpack(cas) jso = json.loads(_jwt.part[1]) assert _eq(jso.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"]) print _jwt.headers assert _jwt.headers == {'alg': 'HS256'} _rj = JWS() info = _rj.verify_compact(cas, [SYMKey(key=cli.client_secret)]) assert _eq(info.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])