I am trying to configure the OIDC to my APIs. It’s expected to be authorized by user requests with a JWT token like Bearer xxxxxx==
.
Here below is my test code with Python, I have created two api endpoints,
- /test/ , by normal JWT auth, and I use it to verify the JWT I generated is valid.
- /test2/, configured with OIDC, this is the target URL.
Both of the api endpoints were linked with a same policy.
import jwt
pub_key = """-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAOn8rRVbujDfvL08ozx6nSS0n5D2GYB5
YQzGdw+lpHceztYpH5EpbabigH2EC3EmYU7dStlEvoZZujH+53Tr7bECAwEAAQ==
-----END PUBLIC KEY-----"""
prv_key = """-----BEGIN RSA PRIVATE KEY-----
MIIBOgIBAAJBAOn8rRVbujDfvL08ozx6nSS0n5D2GYB5YQzGdw+lpHceztYpH5Ep
babigH2EC3EmYU7dStlEvoZZujH+53Tr7bECAwEAAQJAJRIKHfslWX7o+RY1Smym
nt0a9q12xtr0HEEJNeppTxG94zF4LOxieqeHjYMpkcvT0cVIMWdCUgjffI0V9gcE
AQIhAPpFTgSRmiGxBhstwjlvP+1UqA6+vmWHOGLYrjrAUF9xAiEA71fxFtiwRq7g
ghVtxF+0jzUIrs9DtcsaGq94/6tJ0kECIQDtJExn0dt9fzLs/+/g4kRtyuCvkBfz
Niy8pNp6uw2tUQIgUUEQxwnPZl+uNltiBX3cRZXimb4hpZELDq4trNaQ3EECIAD+
8UdQm3xdnaFWwNUlkuNxpVbq9mRvl/ibZhEeXPeS
-----END RSA PRIVATE KEY-----"""
headers = {
"alg": "RS256",
"typ": "JWT"
}
# The policy_id regarding to tyk
kid = '596728c0ad1db8000188f9f5'
aud = "http://10.0.1.145/files/idp_jwks.json"
payload = {
"sub": "0",
"azp": "iPhone-App",
"iat": 1482071636,
"exp": 2167793995,
"kid": kid
}
payload.update({
"iss" : "accounts.google.com",
"aud" : aud
})
print('Payload: ',payload)
encoded = jwt.encode(payload, prv_key, algorithm='RS256', headers=headers)
decoded = jwt.decode(encoded, pub_key, algorithms=['RS256'], audience=aud)
print("Verify Decoded: ", decoded == payload)
JWT = 'Bearer ' + encoded.decode()
print('JWT: ', JWT)
import base64
b64_key = base64.b64encode(pub_key.encode())
print("Base64 PUB key: ", b64_key.decode())
headers = {'Authorization': JWT}
import requests
# A basic API endpoint with normal JWT authentication method.
jwt_verify_url = 'http://localhost/test/'
r1 = requests.get(jwt_verify_url, headers=headers)
print(" ")
if r1.status_code == 200:
print("JWT is verified OK!")
else:
print("JWT is not valid!!!")
# The target endpoint to test OIDC
api_url = 'http://localhost/test2/'
r = requests.get(api_url, headers=headers)
if r.status_code != 200:
print('Status code: {}, Response: {}'.format(r.status_code, r.text))
else:
print("Status code: {}, Request OK!".format(r.status_code))
Output:
Payload: {'sub': '0', 'azp': 'iPhone-App', 'iat': 1482071636, 'exp': 2167793995, 'kid': '596728c0ad1db8000188f9f5', 'iss': 'accounts.google.com', 'aud': 'http://10.0.1.145/files/idp_jwks.json'}
Verify Decoded: True
JWT: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiIwIiwiYXpwIjoiaVBob25lLUFwcCIsImlhdCI6MTQ4MjA3MTYzNiwiZXhwIjoyMTY3NzkzOTk1LCJraWQiOiI1OTY3MjhjMGFkMWRiODAwMDE4OGY5ZjUiLCJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwiYXVkIjoiaHR0cDovLzEwLjAuMS4xNDUvZmlsZXMvaWRwX2p3a3MuanNvbiJ9.ZZdGid4soh7VGAEWHrqpfpAv_gEHL7mbhbreZVh6qDXuXEEh5w1CEfqqUp5wkwMcfWKB05pljZKyFLT56J0hpA
Base64 PUB key: LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZ3d0RRWUpLb1pJaHZjTkFRRUJCUUFEU3dBd1NBSkJBT244clJWYnVqRGZ2TDA4b3p4Nm5TUzBuNUQyR1lCNQpZUXpHZHcrbHBIY2V6dFlwSDVFcGJhYmlnSDJFQzNFbVlVN2RTdGxFdm9aWnVqSCs1M1RyN2JFQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQ==
JWT is verified OK!
Status code: 403, Response: {
"error": "Key not authorised"
}
Error log:
tyk_gateway_1 | time="Jul 13 10:08:46" level=warning msg="JWT Invalid: Validation error. Jwt token validation failed."
tyk_gateway_1 | time="Jul 13 10:08:46" level=warning msg="Attempted access with invalid key." key="[JWT]"
tyk_gateway_1 | time="Jul 13 10:08:46" level=error msg="request error: Key not authorised" api_id=c2b8938b618242426e87327e7332b8d2 org_id=59672879ad1db8000188f9ee path="/" server_name="http://httpbin.org/" user_id= user_ip=172.19.0.1
The log indicates that the token validation failed. Since the URL of JWK was specified in the aud field, is it the correct way configure OIDC with JWK to work?
The referred JWK is
{
"keys": [
{
"alg": "RS256",
"kty": "RSA",
"use": "sig",
"x5c": ["LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZ3d0RRWUpLb1pJaHZjTkFRRUJCUUFEU3dBd1NBSkJBT244clJWYnVqRGZ2TDA4b3p4Nm5TUzBuNUQyR1lCNQpZUXpHZHcrbHBIY2V6dFlwSDVFcGJhYmlnSDJFQzNFbVlVN2RTdGxFdm9aWnVqSCs1M1RyN2JFQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQ==",
"MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJ4AhQ6FGspvMAnBmclAzydVB35i/MJe\nDq+OB5di7YLy3VcH66MJ0NSnEy/s55hgcQQ+IozJK4UTyAyGwRGVxn8CAwEAAQ=="
],
"kid": "596728c0ad1db8000188f9f5",
"x5t": "596728c0ad1db8000188f9f5"
}
]
}