python - 在python中使用public_key进行KeyCloak解码

标签 python jwt keycloak decoding

我不知道如何解码来自 keycloak 公钥和证书的结果。
我应该使用哪一个来解码?我只有 access_token
并已尝试使用 cert 和 public_key

结果来自:https://keycloak.some.domain/auth/realms/name-realm/

{
"realm": "name-realm",
"public_key": "some-secert-stringMIIBIsome-secert-stringknhFmdCmX9lu1EJNEsome-secert-string",
"token-service": "https://keycloak.some.domain/auth/realms/name-realm/protocol/openid-connect",
"account-service": "https://keycloak.some.domain/auth/realms/name-realm/account",
"tokens-not-before": 0
}

结果来自:https://keycloak.some.domain/auth/realms/epf-uat/protocol/openid-connect/certs
{
"keys": [
{
"kid": "WtJZKhwIsome-secert-stringA",
"kty": "RSA",
"alg": "RS256",
"use": "sig",
"n": "xtG3QzVml8lxYQz1FaesgZ2-TPR2h_NqGHwRsome-secert-stringH2Bd5Dncsome-secert-stringEHVBAd75gzIPh_wTsome-secert-stringiAw",
"e": "AQAB",
"x5c": [
"some-secert-string"
],
"x5t": "y-Ksome-secert-stringMViQ",
"x5t#S256": "vvsome-secert-stringbosome-secert-stringtE8QW2vnmw60NJfaDJlVE"
}
]
}

我已经尝试使用 https://github.com/mpdavis/python-jose 来解码 jwt。
这里的样本:

环境:
keycloak_algorithm = ["RS256"]
keycloak_domain = "https://keycloak.some.domain/auth/realms/some-realm/"
keycloak_audience = "https://login.some-domain.com"

验证文件
token = CLEANED_BEARER_TOKEN_FROM_CLIENT
jsonurl = urlopen(setting.keycloak_domain)
algorithms = setting.keycloak_algorithm
audience = setting.keycloak_audience
issuer = setting.keycloak_domain

jwks = json.loads(jsonurl.read())

try:
    payload = jwt.decode(token, jwks["public_key"], algorithms=algorithms, audience=audience, issuer=issuer)
except jwt.ExpiredSignatureError:
   raise AuthError("Token is expired. Please update your token.", 401)
except jwt.JWTClaimsError as e:
   raise AuthError("Invalid claims. " + str(e), 401)
except jwt.JWTError as e:
    raise AuthError("JWT Error." + str(e), 401)
except Exception as e:
    raise AuthError("Unable to parse authentication token. " + str(e), 401)

如果我使用域( 没有 protocol/openid-connect/certs 端点),这里的结果:
AuthError: ('Unable to parse authentication token. Could not deserialize key data.', 401)
在这里,如果我使用 protocol/openid-connect/certs 端点:
AuthError: ('JWT Error.Signature verification failed.', 401)
我不知道为什么这 2 件事(public_key 和 certs)无法解码。

其他注意事项:
  • 我正在使用 FastApi ( https://fastapi.tiangolo.com/ )
  • 有 Express js 的工作部分。所以我只从带有 python 应用程序的 express js 中使用身份验证。 (express js 将通过提供 access_code 到达端点)
  • 最佳答案

    public_key 似乎采用 base64 编码的 DER 格式。你应该能够像这样使用它:

    from base64 import b64decode
    
    import jwt
    from cryptography.hazmat.primitives import serialization
    
    r = requests.get("https://keycloak.some.domain/auth/realms/name-realm/")
    r.raise_for_status()
    key_der_base64 = r.json()["public_key"]
    key_der = b64decode(key_der_base64.encode())
    
    public_key = serialization.load_der_public_key(key_der)
    
    payload = jwt.decode(token, public_key, algorithms=["RS256"])
    
    但是,请注意 https://keycloak.some.domain/auth/realms/name-realm/ 端点似乎不遵循任何正式标准。使用 /certs 端点可能会更好,如图 here 所示:
    import jwt
    from jwt import PyJWKClient
    
    url = "https://keycloak.some.domain/auth/realms/epf-uat/protocol/openid-connect/certs"
    jwks_client = PyJWKClient(url)
    signing_key = jwks_client.get_signing_key_from_jwt(token)
    payload = jwt.decode(token, signing_key.key, algorithms=["RS256"])
    

    关于python - 在python中使用public_key进行KeyCloak解码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59764606/

    相关文章:

    javascript - Python网页抓取选择下拉菜单

    python - 如何在Python中生成JWT断言

    python - Flask 重定向时返回 JWT token

    java - Keycloak中如何根据@PathVariable或@RequestBody定义访问条件?

    redirect - 为什么 keycloak 删除重定向 uri 中的 SSL?

    Python SFTP : Use SFTP to put memory stream into remote folder. 类似于 FTP storbinary

    python - 在 Django 中,管理移动站点和桌面站点的最佳方法是什么?

    python - 从多列的 value_counts 中排除项目

    javascript - 在nodejs中多次尝试记录后锁定用户

    angular - 如何在身份验证服务器上为 SPA - REST 架构配置客户端并进行验证?