Keycloak idp well known url support (#10527)

* first commit

* add and fixe test

* add example

* fragment and sanity

* sanity

* sanity

* Update plugins/modules/keycloak_identity_provider.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update changelogs/fragments/10527-keycloak-idp-well-known-url-support.yml

---------

Co-authored-by: Andre Desrosiers <andre.desrosiers@ssss.gouv.qc.ca>
Co-authored-by: Felix Fontein <felix@fontein.de>
This commit is contained in:
desand01 2025-08-04 14:01:05 -04:00 committed by GitHub
commit 7ffeaaa16d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 182 additions and 1 deletions

View file

@ -0,0 +1,20 @@
<!--
Copyright (c) Ansible Project
GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
SPDX-License-Identifier: GPL-3.0-or-later
-->
# Running keycloak_identity_provider module integration test
To run Keycloak component info module's integration test, start a keycloak server using Docker:
docker run -d --rm --name mykeycloak -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=password quay.io/keycloak/keycloak:latest start-dev --http-relative-path /auth
Run integration tests:
ansible-test integration -v keycloak_identity_provider --allow-unsupported --docker fedora35 --docker-network host
Cleanup:
docker stop mykeycloak

View file

@ -3,6 +3,15 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
- name: Delete realm if exists
community.general.keycloak_realm:
auth_keycloak_url: "{{ url }}"
auth_realm: "{{ admin_realm }}"
auth_username: "{{ admin_user }}"
auth_password: "{{ admin_password }}"
realm: "{{ realm }}"
state: absent
- name: Create realm
community.general.keycloak_realm:
auth_keycloak_url: "{{ url }}"
@ -62,7 +71,7 @@
- result.existing == {}
- result.end_state.alias == "{{ idp }}"
- result.end_state.mappers != []
- result.end_state.config.client_secret = "**********"
- result.end_state.config.clientSecret == "**********"
- name: Update existing identity provider (no change)
community.general.keycloak_identity_provider:
@ -277,3 +286,79 @@
that:
- result is not changed
- result.end_state == {}
- name: Create IDP realm
community.general.keycloak_realm:
auth_keycloak_url: "{{ url }}"
auth_realm: "{{ admin_realm }}"
auth_username: "{{ admin_user }}"
auth_password: "{{ admin_password }}"
id: "{{ idp_realm }}"
realm: "{{ idp_realm }}"
state: present
- name: Create new identity provider with fromUrl
community.general.keycloak_identity_provider:
auth_keycloak_url: "{{ url }}"
auth_realm: "{{ admin_realm }}"
auth_username: "{{ admin_user }}"
auth_password: "{{ admin_password }}"
realm: "{{ realm }}"
alias: "{{ idp_fromurl }}"
display_name: OpenID Connect IdP from url
enabled: true
provider_id: oidc
config:
fromUrl: "{{ url }}/realms/{{ idp_realm }}/.well-known/openid-configuration"
clientAuthMethod: client_secret_post
clientId: clientid
clientSecret: clientsecret
syncMode: FORCE
state: present
register: result
- name: Debug
debug:
var: result
- name: Assert identity provider created with IDP endpoints
assert:
that:
- result is changed
- result.end_state.config.authorizationUrl == "{{ url }}/realms/{{ idp_realm }}/protocol/openid-connect/auth"
- result.end_state.config.issuer == "{{ url }}/realms/{{ idp_realm }}"
- result.end_state.config.jwksUrl == "{{ url }}/realms/{{ idp_realm }}/protocol/openid-connect/certs"
- result.end_state.config.logoutUrl == "{{ url }}/realms/{{ idp_realm }}/protocol/openid-connect/logout"
- result.end_state.config.tokenUrl == "{{ url }}/realms/{{ idp_realm }}/protocol/openid-connect/token"
- result.end_state.config.userInfoUrl == "{{ url }}/realms/{{ idp_realm }}/protocol/openid-connect/userinfo"
- name: Create new identity provider with fromUrl and exclusion should fail
community.general.keycloak_identity_provider:
auth_keycloak_url: "{{ url }}"
auth_realm: "{{ admin_realm }}"
auth_username: "{{ admin_user }}"
auth_password: "{{ admin_password }}"
realm: "{{ realm }}"
alias: "mustfail"
display_name: Failed OpenID Connect IdP from url
enabled: true
provider_id: oidc
config: "{{ config | combine(endpoint) }}"
state: present
vars:
config:
fromUrl: "{{ url }}/realms/{{ idp_realm }}/.well-known/openid-configuration"
clientAuthMethod: client_secret_post
clientId: clientid
clientSecret: clientsecret
endpoint: "{{ '{\"' + item + '\": \"' + url + '/realms/' + idp_realm + '/protocol/openid-connect/' + item + '\"}' }}"
with_items: ['userInfoUrl', 'authorizationUrl', 'tokenUrl', 'logoutUrl', 'issuer', 'jwksUrl']
register: result
ignore_errors: true
- name: Check failure of identity provider creation with fromUrl and userInfoUrl
assert:
that:
- result is not changed
- result is failed
- result.results | selectattr('failed', 'equalto', false) | list | length == 0

View file

@ -9,3 +9,6 @@ admin_user: admin
admin_password: password
realm: myrealm
idp: myidp
idp_realm: myidprealm
idp_fromurl: myidpfromurl