Browse Source
Merge pull request #331 from ecederstrand/token-exchange
Support Token Exchange
pull/333/head
v1.2.0
Richard Nemeth
3 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with
29 additions and
1 deletions
-
CHANGELOG.md
-
README.md
-
docs/source/conf.py
-
src/keycloak/keycloak_openid.py
|
|
@ -46,3 +46,4 @@ All notable changes to this project will be documented in this file. |
|
|
|
## [master] |
|
|
|
|
|
|
|
* Renamed `KeycloakOpenID.well_know` to `KeycloakOpenID.well_known` |
|
|
|
* Add `KeycloakOpenID.token_exchange` to support Token Exchange |
|
|
@ -76,6 +76,9 @@ config_well_known = keycloak_openid.well_known() |
|
|
|
token = keycloak_openid.token("user", "password") |
|
|
|
token = keycloak_openid.token("user", "password", totp="012345") |
|
|
|
|
|
|
|
# Get token using Token Exchange |
|
|
|
token = keycloak_openid.exchange_token(token['access_token'], "my_client", "other_client", "some_user") |
|
|
|
|
|
|
|
# Get Userinfo |
|
|
|
userinfo = keycloak_openid.userinfo(token['access_token']) |
|
|
|
|
|
|
|
|
|
@ -77,7 +77,7 @@ release = "0.0.0" |
|
|
|
# |
|
|
|
# This is also used if you do content translation via gettext catalogs. |
|
|
|
# Usually you set "language" from the command line for these cases. |
|
|
|
language = None |
|
|
|
language = "en" |
|
|
|
|
|
|
|
# List of patterns, relative to source directory, that match files and |
|
|
|
# directories to ignore when looking for source files. |
|
|
|
|
|
@ -254,6 +254,30 @@ class KeycloakOpenID: |
|
|
|
data_raw = self.connection.raw_post(URL_TOKEN.format(**params_path), data=payload) |
|
|
|
return raise_error_from_response(data_raw, KeycloakGetError) |
|
|
|
|
|
|
|
def exchange_token(self, token: str, client_id: str, audience: str, subject: str) -> dict: |
|
|
|
""" |
|
|
|
Use a token to obtain an entirely different token. See |
|
|
|
https://www.keycloak.org/docs/latest/securing_apps/index.html#_token-exchange |
|
|
|
|
|
|
|
:param token: |
|
|
|
:param client_id: |
|
|
|
:param audience: |
|
|
|
:param subject: |
|
|
|
:return: |
|
|
|
""" |
|
|
|
params_path = {"realm-name": self.realm_name} |
|
|
|
payload = { |
|
|
|
"grant_type": ["urn:ietf:params:oauth:grant-type:token-exchange"], |
|
|
|
"client_id": client_id, |
|
|
|
"subject_token": token, |
|
|
|
"requested_token_type": "urn:ietf:params:oauth:token-type:refresh_token", |
|
|
|
"audience": audience, |
|
|
|
"requested_subject": subject, |
|
|
|
} |
|
|
|
payload = self._add_secret_key(payload) |
|
|
|
data_raw = self.connection.raw_post(URL_TOKEN.format(**params_path), data=payload) |
|
|
|
return raise_error_from_response(data_raw, KeycloakGetError) |
|
|
|
|
|
|
|
def userinfo(self, token): |
|
|
|
""" |
|
|
|
The userinfo endpoint returns standard claims about the authenticated user, |
|
|
|