Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding method for api key based authN #4

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,10 @@ main2.py
s3air-authz-config.json
Last Modified:
01/26/2018 00:45:53
(timezone is UTC)
(timezone is UTC)

.
.env_pypath
.vscode/settings.json
test/testAuth.py
test/constants.py
8 changes: 5 additions & 3 deletions keycloak_wrapper/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from .wrapper import access_token, well_known, user_info, introspect, realm_users, realm_users_count, user_keycloak_id, \
user_attributes, get_user, realm_clients, client_keycloak_id, get_client, client_roles, create_role, get_role_id, \
assign_role_to_user, user_roles, refresh_token, create_user, delete_user
from .wrapper import access_token, well_known, user_info, introspect, \
realm_users, realm_users_count, user_keycloak_id, user_attributes, \
get_user, realm_clients, client_keycloak_id, get_client, client_roles, \
create_role, get_role_id, assign_role_to_user, user_roles, refresh_token, \
create_user, delete_user, access_token_sa # noqa: F401
9 changes: 6 additions & 3 deletions keycloak_wrapper/keycloak_patterns.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
USER_TOKEN = "realms/{realm-name}/protocol/openid-connect/token"
WELL_KNOWN = "realms/{realm-name}/.well-known/openid-configuration"
USER_INFO = "realms/{realm-name}/protocol/openid-connect/userinfo"
USER_INTROSPECTION = "realms/{realm-name}/protocol/openid-connect/token/introspect"
USER_INTROSPECTION = "realms/{realm-name}/protocol/openid-connect/token/" + \
"introspect"

## These URLS are used with Realm's admin credentials
# These URLS are used with Realm's admin credentials
ADMIN_REALM_USERS = "admin/realms/{realm-name}/users"
ADMIN_USERS_COUNT = "admin/realms/{realm-name}/users/count"
ADMIN_GET_USER = "admin/realms/{realm-name}/users/{id}"
ADMIN_CLIENTS = "admin/realms/{realm-name}/clients"
ADMIN_GET_CLIENT = "admin/realms/{realm-name}/clients/{id}"
ADMIN_CLIENT_ROLES = "admin/realms/{realm-name}/clients/{id}/roles"
ADMIN_ASSIGN_USER_CLIENT_ROLES = "admin/realms/{realm-name}/users/{id}/role-mappings/clients/{client-id}"
ADMIN_ASSIGN_USER_CLIENT_ROLES = "admin/realms/{realm-name}/users/{id}/" + \
"role-mappings/clients/{client-id}"
ADMIN_AUTH = "auth/realms/{realm-name}/protocol/openid-connect/token"
129 changes: 93 additions & 36 deletions keycloak_wrapper/wrapper.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import requests
import json
import requests
from urllib.parse import urljoin

from keycloak_wrapper.keycloak_patterns import USER_TOKEN, WELL_KNOWN, USER_INFO, USER_INTROSPECTION, ADMIN_REALM_USERS, \
ADMIN_USERS_COUNT, ADMIN_GET_USER, ADMIN_CLIENTS, ADMIN_GET_CLIENT, ADMIN_CLIENT_ROLES, \
ADMIN_ASSIGN_USER_CLIENT_ROLES
from keycloak_wrapper.keycloak_patterns import USER_TOKEN, WELL_KNOWN, \
USER_INFO, USER_INTROSPECTION, ADMIN_REALM_USERS, ADMIN_USERS_COUNT, \
ADMIN_GET_USER, ADMIN_CLIENTS, ADMIN_GET_CLIENT, ADMIN_CLIENT_ROLES, \
ADMIN_ASSIGN_USER_CLIENT_ROLES, ADMIN_AUTH


def access_token(keycloak_url, realm, client_id, client_secret, username, password):
def access_token_sa(keycloak_url, realm, client_id, client_secret):
"""
keycloak_url: KEYCLOAK URL (http://xxxxx/auth)
realm: KEYCLOAK REALM NAME
Expand All @@ -18,9 +18,31 @@ def access_token(keycloak_url, realm, client_id, client_secret, username, passwo
password: KEYCLOAK user's PASSWORD
"""
params = {"realm-name": realm}
payload = {"username": username, "password": password, "grant_type": "password", "client_id": client_id,
payload = {"grant_type": "client_credentials", "client_id": client_id,
"client_secret": client_secret}
response = requests.post(url=urljoin(keycloak_url, USER_TOKEN).format(**params), data=payload).json()
response = requests.post(url=urljoin(keycloak_url, ADMIN_AUTH).format(
**params), data=payload)
response.raise_for_status()
access_token = response.json()
return access_token


def access_token(keycloak_url, realm, client_id, client_secret, username=None,
password=None):
"""
keycloak_url: KEYCLOAK URL (http://xxxxx/auth)
realm: KEYCLOAK REALM NAME
client_id: KEYCLOAK CLIENT NAME
client_secret: KEYCLOAK CLIENT SECRET
username: KEYCLOAK user's USERNAME
password: KEYCLOAK user's PASSWORD
"""
params = {"realm-name": realm}
payload = {"username": username, "password": password,
"grant_type": "password", "client_id": client_id,
"client_secret": client_secret}
response = requests.post(url=urljoin(keycloak_url, USER_TOKEN).format(
**params), data=payload).json()
return response


Expand All @@ -34,7 +56,8 @@ def well_known(keycloak_url, realm, access_token):
"""
params = {"realm-name": realm}
headers = {"Authorization": "Bearer " + access_token}
response = requests.get(url=urljoin(keycloak_url, WELL_KNOWN).format(**params), headers=headers).json()
response = requests.get(url=urljoin(keycloak_url, WELL_KNOWN).format(
**params), headers=headers).json()
return response


Expand All @@ -48,7 +71,8 @@ def user_info(keycloak_url, realm, access_token):
"""
params = {"realm-name": realm}
headers = {"Authorization": "Bearer " + access_token}
response = requests.get(url=urljoin(keycloak_url, USER_INFO).format(**params), headers=headers).json()
response = requests.get(url=urljoin(keycloak_url, USER_INFO).format(
**params), headers=headers).json()
return response


Expand All @@ -63,8 +87,11 @@ def introspect(keycloak_url, realm, client_id, client_secret, access_token):
:return: KEYCLOAK USER DETAILED INFORMATION
"""
params = {"realm-name": realm}
payload = {"token": access_token, "client_id": client_id, "client_secret": client_secret}
response = requests.post(url=urljoin(keycloak_url, USER_INTROSPECTION).format(**params), data=payload).json()
payload = {"token": access_token, "client_id": client_id,
"client_secret": client_secret}
response = requests.post(url=urljoin(keycloak_url,
USER_INTROSPECTION).format(**params),
data=payload).json()
return response


Expand All @@ -78,7 +105,9 @@ def realm_users(keycloak_url, realm, admin_token):
"""
params = {"realm-name": realm}
headers = {"Authorization": "Bearer " + admin_token}
response = requests.get(url=urljoin(keycloak_url, ADMIN_REALM_USERS).format(**params), headers=headers).json()
response = requests.get(url=urljoin(keycloak_url,
ADMIN_REALM_USERS).format(**params),
headers=headers).json()
return response


Expand All @@ -92,7 +121,9 @@ def realm_users_count(keycloak_url, realm, admin_token):
"""
params = {"realm-name": realm}
headers = {"Authorization": "Bearer " + admin_token}
response = requests.get(url=urljoin(keycloak_url, ADMIN_USERS_COUNT).format(**params), headers=headers).json()
response = requests.get(url=urljoin(keycloak_url,
ADMIN_USERS_COUNT).format(**params),
headers=headers).json()
return response


Expand Down Expand Up @@ -125,7 +156,8 @@ def get_user(keycloak_url, realm, admin_token, username):
user_id = user_keycloak_id(keycloak_url, realm, admin_token, username)
params = {"realm-name": realm, "id": user_id}
headers = {"Authorization": "Bearer " + admin_token}
response = requests.get(url=urljoin(keycloak_url, ADMIN_GET_USER).format(**params), headers=headers).json()
response = requests.get(url=urljoin(keycloak_url, ADMIN_GET_USER).format(
**params), headers=headers).json()
return response


Expand Down Expand Up @@ -156,7 +188,8 @@ def realm_clients(keycloak_url, realm, admin_token):
"""
params = {"realm-name": realm}
headers = {"Authorization": "Bearer " + admin_token}
response = requests.get(url=urljoin(keycloak_url, ADMIN_CLIENTS).format(**params), headers=headers).json()
response = requests.get(url=urljoin(keycloak_url, ADMIN_CLIENTS).format(
**params), headers=headers).json()
return response


Expand Down Expand Up @@ -185,10 +218,12 @@ def get_client(keycloak_url, realm, admin_token, client_name):
:param client_name: client name
:return: client internal keycloak id
"""
keycloak_id = client_keycloak_id(keycloak_url, realm, admin_token, client_name)
keycloak_id = client_keycloak_id(keycloak_url, realm, admin_token,
client_name)
params = {"realm-name": realm, "id": keycloak_id}
headers = {"Authorization": "Bearer " + admin_token}
response = requests.get(url=urljoin(keycloak_url, ADMIN_GET_CLIENT).format(**params), headers=headers).json()
response = requests.get(url=urljoin(keycloak_url, ADMIN_GET_CLIENT).format(
**params), headers=headers).json()
return response


Expand All @@ -201,10 +236,13 @@ def client_roles(keycloak_url, realm, admin_token, client_name):
:param client_name: client name
:return: client internal keycloak id
"""
keycloak_id = client_keycloak_id(keycloak_url, realm, admin_token, client_name)
keycloak_id = client_keycloak_id(keycloak_url, realm, admin_token,
client_name)
params = {"realm-name": realm, "id": keycloak_id}
headers = {"Authorization": "Bearer " + admin_token}
response = requests.get(url=urljoin(keycloak_url, ADMIN_CLIENT_ROLES).format(**params), headers=headers).json()
response = requests.get(url=urljoin(keycloak_url,
ADMIN_CLIENT_ROLES).format(**params),
headers=headers).json()
return response


Expand All @@ -218,11 +256,15 @@ def create_role(keycloak_url, realm, admin_token, client_name, new_role_name):
:param new_role_name: role name
:return:
"""
keycloak_id = client_keycloak_id(keycloak_url, realm, admin_token, client_name)
keycloak_id = client_keycloak_id(keycloak_url, realm, admin_token,
client_name)
params = {"realm-name": realm, "id": keycloak_id}
headers = {"Authorization": "Bearer " + admin_token, "Content-Type": "application/json"}
headers = {"Authorization": "Bearer " + admin_token,
"Content-Type": "application/json"}
payload = {"name": new_role_name, "clientRole": "True"}
response = requests.post(url=urljoin(keycloak_url, ADMIN_CLIENT_ROLES).format(**params), headers=headers,
response = requests.post(url=urljoin(keycloak_url,
ADMIN_CLIENT_ROLES).format(**params),
headers=headers,
data=json.dumps(payload)).status_code
return response

Expand All @@ -244,7 +286,8 @@ def get_role_id(keycloak_url, realm, admin_token, client_name, role_name):
return None


def assign_role_to_user(keycloak_url, realm, admin_token, client_name, role_name, username):
def assign_role_to_user(keycloak_url, realm, admin_token, client_name,
role_name, username):
"""

:param keycloak_url: KEYCLOAK URL (http://xxxxx/auth)
Expand All @@ -255,14 +298,19 @@ def assign_role_to_user(keycloak_url, realm, admin_token, client_name, role_name
:param username: keycloak username
:return:
"""
role_id = get_role_id(keycloak_url, realm, admin_token, client_name, role_name)
keycloak_id = client_keycloak_id(keycloak_url, realm, admin_token, client_name)
role_id = get_role_id(keycloak_url, realm, admin_token, client_name,
role_name)
keycloak_id = client_keycloak_id(keycloak_url, realm, admin_token,
client_name)
user_id = user_keycloak_id(keycloak_url, realm, admin_token, username)
headers = {"Authorization": "Bearer " + admin_token, "Content-Type": "application/json"}
headers = {"Authorization": "Bearer " + admin_token,
"Content-Type": "application/json"}
params = {"realm-name": realm, "id": user_id, "client-id": keycloak_id}
payload = [{"id": role_id, "name": role_name}]
response = requests.post(url=urljoin(keycloak_url, ADMIN_ASSIGN_USER_CLIENT_ROLES).format(**params),
headers=headers, data=json.dumps(payload)).status_code
response = requests.post(url=urljoin(keycloak_url,
ADMIN_ASSIGN_USER_CLIENT_ROLES).format(**params),
headers=headers,
data=json.dumps(payload)).status_code
return response


Expand All @@ -276,14 +324,16 @@ def user_roles(keycloak_url, realm, client_name, client_secret, access_token):
:param access_token: user's access token
:return:
"""
introspection = introspect(keycloak_url, realm, client_name, client_secret, access_token)
introspection = introspect(keycloak_url, realm, client_name, client_secret,
access_token)
if client_name in introspection['resource_access'].keys():
return introspection['resource_access'][client_name]["roles"]
else:
return "the current user has not roles"


def refresh_token(keycloak_url, realm, client_name, client_secret, refresh_token):
def refresh_token(keycloak_url, realm, client_name, client_secret,
refresh_token):
"""

:param keycloak_url: KEYCLOAK URL (http://xxxxx/auth)
Expand All @@ -294,9 +344,11 @@ def refresh_token(keycloak_url, realm, client_name, client_secret, refresh_token
:return:
"""
params = {"realm-name": realm}
payload = {"client_id": client_name, "grant_type": "refresh_token", "refresh_token": refresh_token,
payload = {"client_id": client_name, "grant_type": "refresh_token",
"refresh_token": refresh_token,
"client_secret": client_secret}
response = requests.post(url=urljoin(keycloak_url, USER_TOKEN).format(**params), data=payload).json()
response = requests.post(url=urljoin(keycloak_url, USER_TOKEN).format(
**params), data=payload).json()
return response


Expand All @@ -306,13 +358,16 @@ def create_user(keycloak_url, realm, admin_token, payload):
:param keycloak_url: KEYCLOAK URL (http://xxxxx/auth)
:param realm: KEYCLOAK REALM NAME
:param admin_token: REALM Admin access token
:parame payload: POST REQUEST PAYLOAD
:param payload: POST REQUEST PAYLOAD
:return: KEYCLOAK USER ID
"""
params = {"realm-name": realm}
headers = {"Authorization": "Bearer " + admin_token, "Content-Type": "application/json",
headers = {"Authorization": "Bearer " + admin_token,
"Content-Type": "application/json",
"Accept": "application/json"}
response = requests.post(url=urljoin(keycloak_url, ADMIN_REALM_USERS).format(**params), headers=headers,
response = requests.post(url=urljoin(keycloak_url,
ADMIN_REALM_USERS).format(**params),
headers=headers,
data=json.dumps(payload)).status_code
return response

Expand All @@ -329,5 +384,7 @@ def delete_user(keycloak_url, realm, admin_token, username):
user_id = user_keycloak_id(keycloak_url, realm, admin_token, username)
params = {"realm-name": realm, "id": user_id}
headers = {"Authorization": "Bearer " + access_token}
response = requests.delete(url=urljoin(keycloak_url, ADMIN_GET_USER).format(**params),headers=headers).status_code
response = requests.delete(url=urljoin(keycloak_url,
ADMIN_GET_USER).format(**params),
headers=headers).status_code
return response