You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

428 lines
11 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
4 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
4 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
2 years ago
2 years ago
6 years ago
6 years ago
6 years ago
5 years ago
7 years ago
  1. [![CircleCI](https://github.com/marcospereirampj/python-keycloak/actions/workflows/daily.yaml/badge.svg)](https://github.com/marcospereirampj/python-keycloak/)
  2. [![Documentation Status](https://readthedocs.org/projects/python-keycloak/badge/?version=latest)](http://python-keycloak.readthedocs.io/en/latest/?badge=latest)
  3. # Python Keycloak
  4. For review- see https://github.com/marcospereirampj/python-keycloak
  5. **python-keycloak** is a Python package providing access to the Keycloak API.
  6. ## Installation
  7. ### Via Pypi Package:
  8. `$ pip install python-keycloak`
  9. ### Manually
  10. `$ python setup.py install`
  11. ## Dependencies
  12. python-keycloak depends on:
  13. - Python 3
  14. - [requests](https://requests.readthedocs.io)
  15. - [python-jose](http://python-jose.readthedocs.io/en/latest/)
  16. - [urllib3](https://urllib3.readthedocs.io/en/stable/)
  17. ### Tests Dependencies
  18. - [tox](https://tox.readthedocs.io/)
  19. - [pytest](https://docs.pytest.org/en/latest/)
  20. - [pytest-cov](https://github.com/pytest-dev/pytest-cov)
  21. - [wheel](https://github.com/pypa/wheel)
  22. ## Bug reports
  23. Please report bugs and feature requests at
  24. https://github.com/marcospereirampj/python-keycloak/issues
  25. ## Documentation
  26. The documentation for python-keycloak is available on [readthedocs](http://python-keycloak.readthedocs.io).
  27. ## Contributors
  28. - [Agriness Team](http://www.agriness.com/pt/)
  29. - [Marcos Pereira](marcospereira.mpj@gmail.com)
  30. - [Martin Devlin](https://bitbucket.org/devlinmpearson/)
  31. - [Shon T. Urbas](https://bitbucket.org/surbas/)
  32. - [Markus Spanier](https://bitbucket.org/spanierm/)
  33. - [Remco Kranenburg](https://bitbucket.org/Remco47/)
  34. - [Armin](https://bitbucket.org/arminfelder/)
  35. - [njordr](https://bitbucket.org/njordr/)
  36. - [Josha Inglis](https://bitbucket.org/joshainglis/)
  37. - [Alex](https://bitbucket.org/alex_zel/)
  38. - [Ewan Jone](https://bitbucket.org/kisamoto/)
  39. - [Lukas Martini](https://github.com/lutoma)
  40. - [Adamatics](https://www.adamatics.com)
  41. ## Usage
  42. ### Keycloak OpenID
  43. #### Well-known
  44. ```python
  45. from keycloak import KeycloakOpenID
  46. # Configure client
  47. keycloak_openid = KeycloakOpenID(
  48. server_url="http://localhost:8080/",
  49. client_id="example_client",
  50. realm_name="example_realm",
  51. client_secret_key="secret",
  52. )
  53. # Get WellKnow
  54. config_well_known = keycloak_openid.well_known()
  55. ```
  56. #### User authentication
  57. ```python
  58. # Get Token
  59. token = keycloak_openid.token("user", "password")
  60. token = keycloak_openid.token("user", "password", totp="012345")
  61. ```
  62. #### User info
  63. ```python
  64. # Get Userinfo
  65. userinfo = keycloak_openid.userinfo(token['access_token'])
  66. ```
  67. #### Token refresh
  68. ```python
  69. # Refresh token
  70. token = keycloak_openid.refresh_token(token['refresh_token'])
  71. # Logout
  72. keycloak_openid.logout(token['refresh_token'])
  73. ```
  74. #### Certificates
  75. ```python
  76. # Get Certs
  77. certs = keycloak_openid.certs()
  78. ```
  79. #### RPT
  80. ```python
  81. # Get RPT (Entitlement)
  82. token = keycloak_openid.token("user", "password")
  83. rpt = keycloak_openid.entitlement(token["access_token"], "resource_id")
  84. # Instropect RPT
  85. token_rpt_info = keycloak_openid.introspect(
  86. keycloak_openid.introspect(
  87. token["access_token"], rpt=rpt["rpt"], token_type_hint="requesting_party_token"
  88. )
  89. )
  90. ```
  91. #### Token inspection
  92. ```python
  93. # Introspect Token
  94. token_info = keycloak_openid.introspect(token["access_token"])
  95. # Decode Token
  96. KEYCLOAK_PUBLIC_KEY = (
  97. "-----BEGIN PUBLIC KEY-----\n" + keycloak_openid.public_key() + "\n-----END PUBLIC KEY-----"
  98. )
  99. options = {"verify_signature": True, "verify_aud": True, "verify_exp": True}
  100. token_info = keycloak_openid.decode_token(
  101. token["access_token"], key=KEYCLOAK_PUBLIC_KEY, options=options
  102. )
  103. ```
  104. #### Permissions
  105. ```python
  106. # Get permissions by token
  107. token = keycloak_openid.token("user", "password")
  108. keycloak_openid.load_authorization_config("example-authz-config.json")
  109. policies = keycloak_openid.get_policies(
  110. token["access_token"], method_token_info="decode", key=KEYCLOAK_PUBLIC_KEY
  111. )
  112. permissions = keycloak_openid.get_permissions(
  113. token["access_token"], method_token_info="introspect"
  114. )
  115. ```
  116. #### UMA permissions
  117. ```python
  118. # Get UMA-permissions by token
  119. token = keycloak_openid.token("user", "password")
  120. permissions = keycloak_openid.uma_permissions(token["access_token"])
  121. # Get UMA-permissions by token with specific resource and scope requested
  122. token = keycloak_openid.token("user", "password")
  123. permissions = keycloak_openid.uma_permissions(token["access_token"], permissions="Resource#Scope")
  124. # Get auth status for a specific resource and scope by token
  125. token = keycloak_openid.token("user", "password")
  126. auth_status = keycloak_openid.has_uma_access(token["access_token"], "Resource#Scope")
  127. ```
  128. ### Keycloak Admin
  129. ```python
  130. from keycloak import KeycloakAdmin
  131. keycloak_admin = KeycloakAdmin(
  132. server_url="http://localhost:8080/auth/",
  133. username="example-admin",
  134. password="secret",
  135. realm_name="master",
  136. user_realm_name="only_if_other_realm_than_master",
  137. client_secret_key="client-secret",
  138. verify=True,
  139. )
  140. ```
  141. #### User handling
  142. ```python
  143. # Add user
  144. new_user = keycloak_admin.create_user(
  145. {
  146. "email": "example@example.com",
  147. "username": "example@example.com",
  148. "enabled": True,
  149. "firstName": "Example",
  150. "lastName": "Example",
  151. }
  152. )
  153. # Add user and raise exception if username already exists
  154. # exist_ok currently defaults to True for backwards compatibility reasons
  155. new_user = keycloak_admin.create_user(
  156. {
  157. "email": "example@example.com",
  158. "username": "example@example.com",
  159. "enabled": True,
  160. "firstName": "Example",
  161. "lastName": "Example",
  162. },
  163. exist_ok=False,
  164. )
  165. # Add user and set password
  166. new_user = keycloak_admin.create_user(
  167. {
  168. "email": "example@example.com",
  169. "username": "example@example.com",
  170. "enabled": True,
  171. "firstName": "Example",
  172. "lastName": "Example",
  173. "credentials": [
  174. {
  175. "value": "secret",
  176. "type": "password",
  177. }
  178. ],
  179. }
  180. )
  181. # Add user and specify a locale
  182. new_user = keycloak_admin.create_user(
  183. {
  184. "email": "example@example.fr",
  185. "username": "example@example.fr",
  186. "enabled": True,
  187. "firstName": "Example",
  188. "lastName": "Example",
  189. "attributes": {"locale": ["fr"]},
  190. }
  191. )
  192. # User counter
  193. count_users = keycloak_admin.users_count()
  194. # Get users Returns a list of users, filtered according to query parameters
  195. users = keycloak_admin.get_users({})
  196. # Get user ID from name
  197. user_id_keycloak = keycloak_admin.get_user_id("example@example.com")
  198. # Get User
  199. user = keycloak_admin.get_user("user-id-keycloak")
  200. # Update User
  201. response = keycloak_admin.update_user(
  202. user_id="user-id-keycloak", payload={"firstName": "Example Update"}
  203. )
  204. # Update User Password
  205. response = keycloak_admin.set_user_password(
  206. user_id="user-id-keycloak", password="secret", temporary=True
  207. )
  208. # Get User Credentials
  209. credentials = keycloak_admin.get_credentials(user_id="user_id")
  210. # Get User Credential by ID
  211. credential = keycloak_admin.get_credential(user_id="user_id", credential_id="credential_id")
  212. # Delete User Credential
  213. response = keycloak_admin.delete_credential(user_id="user_id", credential_id="credential_id")
  214. # Delete User
  215. response = keycloak_admin.delete_user(user_id="user-id-keycloak")
  216. # Get consents granted by the user
  217. consents = keycloak_admin.consents_user(user_id="user-id-keycloak")
  218. ```
  219. #### Sending emails
  220. ```python
  221. # Send User Action
  222. response = keycloak_admin.send_update_account(
  223. user_id="user-id-keycloak", payload=json.dumps(["UPDATE_PASSWORD"])
  224. )
  225. # Send Verify Email
  226. response = keycloak_admin.send_verify_email(user_id="user-id-keycloak")
  227. ```
  228. #### User sessions
  229. ```python
  230. # Get sessions associated with the user
  231. sessions = keycloak_admin.get_sessions(user_id="user-id-keycloak")
  232. ```
  233. #### Server info
  234. ```python
  235. # Get themes, social providers, auth providers, and event listeners available on this server
  236. server_info = keycloak_admin.get_server_info()
  237. ```
  238. #### Clients handling
  239. ```python
  240. # Get clients belonging to the realm Returns a list of clients belonging to the realm
  241. clients = keycloak_admin.get_clients()
  242. # Get client - id (not client-id) from client by name
  243. client_id = keycloak_admin.get_client_id("my-client")
  244. # Get representation of the client - id of client (not client-id)
  245. client = keycloak_admin.get_client(client_id="client_id")
  246. ```
  247. #### Roles handling
  248. ```python
  249. # Get all roles for the realm or client
  250. realm_roles = keycloak_admin.get_realm_roles()
  251. # Get all roles for the client
  252. client_roles = keycloak_admin.get_client_roles(client_id="client_id")
  253. # Get client role
  254. role = keycloak_admin.get_client_role(client_id="client_id", role_name="role_name")
  255. # Warning: Deprecated
  256. # Get client role id from name
  257. role_id = keycloak_admin.get_client_role_id(client_id="client_id", role_name="test")
  258. # Create client role
  259. keycloak_admin.create_client_role(
  260. client_role_id="client_id", payload={"name": "roleName", "clientRole": True}
  261. )
  262. # Assign client role to user. Note that BOTH role_name and role_id appear to be required.
  263. keycloak_admin.assign_client_role(
  264. client_id="client_id", user_id="user_id", role_id="role_id", role_name="test"
  265. )
  266. # Retrieve client roles of a user.
  267. keycloak_admin.get_client_roles_of_user(user_id="user_id", client_id="client_id")
  268. # Retrieve available client roles of a user.
  269. keycloak_admin.get_available_client_roles_of_user(user_id="user_id", client_id="client_id")
  270. # Retrieve composite client roles of a user.
  271. keycloak_admin.get_composite_client_roles_of_user(user_id="user_id", client_id="client_id")
  272. # Delete client roles of a user.
  273. keycloak_admin.delete_client_roles_of_user(
  274. client_id="client_id", user_id="user_id", roles={"id": "role-id"}
  275. )
  276. keycloak_admin.delete_client_roles_of_user(
  277. client_id="client_id", user_id="user_id", roles=[{"id": "role-id_1"}, {"id": "role-id_2"}]
  278. )
  279. # Get client role id from name
  280. role_id = keycloak_admin.get_client_role_id(client_id=client_id, role_name="test")
  281. # Get all roles for the realm or client
  282. realm_roles = keycloak_admin.get_roles()
  283. # Assign client role to user. Note that BOTH role_name and role_id appear to be required.
  284. keycloak_admin.assign_client_role(
  285. client_id=client_id, user_id=user_id, role_id=role_id, role_name="test"
  286. )
  287. # Assign realm roles to user
  288. keycloak_admin.assign_realm_roles(user_id=user_id, roles=realm_roles)
  289. ```
  290. #### Authorization services
  291. ```python
  292. # Get all client authorization resources
  293. client_resources = get_client_authz_resources(client_id="client_id")
  294. # Get all client authorization scopes
  295. client_scopes = get_client_authz_scopes(client_id="client_id")
  296. # Get all client authorization permissions
  297. client_permissions = get_client_authz_permissions(client_id="client_id")
  298. # Get all client authorization policies
  299. client_policies = get_client_authz_policies(client_id="client_id")
  300. ```
  301. #### Groups handling
  302. ```python
  303. # Create new group
  304. group = keycloak_admin.create_group({"name": "Example Group"})
  305. # Get all groups
  306. groups = keycloak_admin.get_groups()
  307. # Get group
  308. group = keycloak_admin.get_group(group_id="group_id")
  309. # Get group by name
  310. group = keycloak_admin.get_group_by_path(path="/group/subgroup", search_in_subgroups=True)
  311. # Function to trigger user sync from provider
  312. sync_users(storage_id="storage_di", action="action")
  313. ```
  314. #### Identity providers
  315. ```python
  316. # Get all ID Providers
  317. idps = keycloak_admin.get_idps()
  318. ```
  319. #### Realm handling
  320. ```python
  321. # Create a new Realm
  322. keycloak_admin.create_realm(payload={"realm": "demo"}, skip_exists=False)
  323. ```