Chapter 36. Using Ansible to delegate authentication for IdM users to external identity providers
Configure external identity provider references using Ansible to enable IdM users to authenticate through OAuth 2-compatible providers while receiving Kerberos tickets.
You can use the idp ansible-freeipa module to associate users with external identity providers (IdP) that support the OAuth 2 device authorization flow. If an IdP reference and an associated IdP user ID exist, you can use them to enable IdP authentication for an IdM user with the user ansible-freeipa module. Afterward, these users receive RHEL Identity Management (IdM) single sign-on capabilities with Kerberos tickets after performing authentication and authorization at the external IdP.
36.1. The benefits of connecting IdM to an external IdP Copy linkLink copied to clipboard!
As an administrator, you might want to allow users stored in an external identity source, such as a cloud services provider, to access RHEL systems joined to your Identity Management (IdM) environment. To achieve this, you can delegate the authentication and authorization process of issuing Kerberos tickets for these users to that external entity.
You can use this feature to expand IdM’s capabilities and allow users stored in external identity providers (IdPs) to access Linux systems managed by IdM.
36.2. How IdM incorporates logins via external IdPs Copy linkLink copied to clipboard!
SSSD 2.7.0 contains the sssd-idp package, which implements the idp Kerberos pre-authentication method. This authentication method follows the OAuth 2.0 Device Authorization Grant flow to delegate authorization decisions to external IdPs:
-
An IdM client user initiates OAuth 2.0 Device Authorization Grant flow, for example, by attempting to retrieve a Kerberos TGT with the
kinitutility at the command line. - A special code and website link are sent from the Authorization Server to the IdM KDC backend.
- The IdM client displays the link and the code to the user. In this example, the IdM client outputs the link and code on the command line.
The user opens the website link in a browser, which can be on another host, a mobile phone, and so on:
- The user enters the special code.
- If necessary, the user logs in to the OAuth 2.0-based IdP.
- The user is prompted to authorize the client to access information.
- The user confirms access at the original device prompt. In this example, the user hits the Enter key at the command line.
- The IdM KDC backend polls the OAuth 2.0 Authorization Server for access to user information.
36.3. Using Ansible to create a reference to an external identity provider Copy linkLink copied to clipboard!
Configure an external identity provider (IdP) reference in Identity Management (IdM) using Ansible to enable OAuth 2.0 authentication delegation.
In the example below, you use the idp ansible-freeipa module to configure a reference to the github external IdP.
Prerequisites
You have registered IdM as an OAuth application to your external IdP, and generated a client ID and client secret on the device that an IdM user will be using to authenticate to IdM. The example assumes that:
- my_github_account_name is the github user whose account the IdM user will be using to authenticate to IdM.
-
The
client IDis 2efe1acffe9e8ab869f4. -
The
client secretis 656a5228abc5f9545c85fa626aecbf69312d398c.
- Your IdM servers are using SSSD 2.7.0 or later.
You have configured your Ansible control node to meet the following requirements:
- You are using Ansible version 2.15 or later.
-
You have installed the
ansible-freeipapackage. - The example assumes that in the ~/MyPlaybooks/ directory, you have created an Ansible inventory file with the fully-qualified domain name (FQDN) of the IdM server.
-
The example assumes that the secret.yml Ansible vault stores your
ipaadmin_passwordand that you have access to a file that stores the password protecting the secret.yml file.
-
The target node, that is the node on which the
freeipa.ansible_freeipamodule is executed, is part of the IdM domain as an IdM client, server or replica.
Procedure
On your Ansible control node, create an configure-external-idp-reference.yml playbook:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - Save the file.
Run the Ansible playbook. Specify the playbook file, the file storing the password protecting the secret.yml file, and the inventory file:
ansible-playbook --vault-password-file=password_file -v -i inventory configure-external-idp-reference.yml
$ ansible-playbook --vault-password-file=password_file -v -i inventory configure-external-idp-reference.ymlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
On an IdM client, verify that the output of the
ipa idp-showcommand shows the IdP reference you have created.ipa idp-show github_idp
[idmuser@idmclient ~]$ ipa idp-show github_idpCopy to Clipboard Copied! Toggle word wrap Toggle overflow
36.4. Using Ansible to enable an IdM user to authenticate via an external IdP Copy linkLink copied to clipboard!
Associate an external identity provider reference with an Identity Management (IdM) user using Ansible, enabling them to authenticate through OAuth 2.0.
In the example below, you use Ansible to associate an external IdP reference named github_idp with the IdM user named idm-user-with-external-idp. As a result of the procedure, the user is able to use the my_github_account_name github identity to authenticate as idm-user-with-external-idp to IdM.
Prerequisites
- Your IdM client and IdM servers are using SSSD 2.7.0 or later.
- You have created a reference to an external IdP in IdM. See Using Ansible to create a reference to an external identity provider.
You have configured your Ansible control node to meet the following requirements:
- You are using Ansible version 2.15 or later.
-
You have installed the
ansible-freeipapackage. - The example assumes that in the ~/MyPlaybooks/ directory, you have created an Ansible inventory file with the fully-qualified domain name (FQDN) of the IdM server.
-
The example assumes that the secret.yml Ansible vault stores your
ipaadmin_passwordand that you have access to a file that stores the password protecting the secret.yml file.
-
The target node, that is the node on which the
freeipa.ansible_freeipamodule is executed, is part of the IdM domain as an IdM client, server or replica.
Procedure
On your Ansible control node, create an enable-user-to-authenticate-via-external-idp.yml playbook:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - Save the file.
Run the Ansible playbook. Specify the playbook file, the file storing the password protecting the secret.yml file, and the inventory file:
ansible-playbook --vault-password-file=password_file -v -i inventory enable-user-to-authenticate-via-external-idp.yml
$ ansible-playbook --vault-password-file=password_file -v -i inventory enable-user-to-authenticate-via-external-idp.ymlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Log in to an IdM client and verify that the output of the
ipa user-showcommand for the idm-user-with-external-idp user displays references to the IdP:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
36.5. Retrieving an IdM ticket-granting ticket as an external IdP user Copy linkLink copied to clipboard!
If you have delegated authentication for an Identity Management (IdM) user to an external identity provider (IdP), the IdM user can request a Kerberos ticket-granting ticket (TGT) by authenticating to the external IdP.
Complete this procedure to:
- Retrieve and store an anonymous Kerberos ticket locally.
-
Request the TGT for the idm-user-with-external-idp user by using
kinitwith the-Toption to enable Flexible Authentication via Secure Tunneling (FAST) channel to provide a secure connection between the Kerberos client and Kerberos Distribution Center (KDC).
Prerequisites
- You have created a reference to an external IdP in IdM. See Using Ansible to create a reference to an external identity provider.
- You have associated an external IdP reference with the user account. See Using Ansible to enable an IdM user to authenticate via an external IdP.
- The user that you are initially logged in as has write permissions on a directory in the local filesystem.
Procedure
Use Anonymous PKINIT to obtain a Kerberos ticket and store it in a file named
./fast.ccache.kinit -n -c ./fast.ccache
$ kinit -n -c ./fast.ccacheCopy to Clipboard Copied! Toggle word wrap Toggle overflow Optional: View the retrieved ticket:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Begin authenticating as the IdM user, using the
-Toption to enable the FAST communication channel.kinit -T ./fast.ccache idm-user-with-external-idp Authenticate at https://oauth2.idp.com:8443/auth/realms/master/device?user_code=YHMQ-XKTL and press ENTER.:
[root@client ~]# kinit -T ./fast.ccache idm-user-with-external-idp Authenticate at https://oauth2.idp.com:8443/auth/realms/master/device?user_code=YHMQ-XKTL and press ENTER.:Copy to Clipboard Copied! Toggle word wrap Toggle overflow - In a browser, authenticate as the user at the website provided in the command output.
- At the command line, press the Enter key to finish the authentication process.
Verification
Display your Kerberos ticket information and confirm that the line
config: pa_typeshows152for pre-authentication with an external IdP.Copy to Clipboard Copied! Toggle word wrap Toggle overflow The
pa_type = 152indicates external IdP authentication.
36.6. Logging in to an IdM client via SSH as an external IdP user Copy linkLink copied to clipboard!
To log in to an IdM client by using SSH as an external identity provider (IdP) user, begin the login process on the command line. When prompted, authenticate at the website associated with the IdP, and finish the process at the Identity Management (IdM) client.
Prerequisites
- You have created a reference to an external IdP in IdM. See Using Ansible to create a reference to an external identity provider.
- You have associated an external IdP reference with the user account. See Using Ansible to enable an IdM user to authenticate via an external IdP.
Procedure
Attempt to log in to the IdM client via SSH.
ssh idm-user-with-external-idp@client.idm.example.com (idm-user-with-external-idp@client.idm.example.com) Authenticate at https://oauth2.idp.com:8443/auth/realms/main/device?user_code=XYFL-ROYR and press ENTER.
[user@client ~]$ ssh idm-user-with-external-idp@client.idm.example.com (idm-user-with-external-idp@client.idm.example.com) Authenticate at https://oauth2.idp.com:8443/auth/realms/main/device?user_code=XYFL-ROYR and press ENTER.Copy to Clipboard Copied! Toggle word wrap Toggle overflow - In a browser, authenticate as the user at the website provided in the command output.
- At the command line, press the Enter key to finish the authentication process.
Verification
Display your Kerberos ticket information and confirm that the line
config: pa_typeshows152for pre-authentication with an external IdP.Copy to Clipboard Copied! Toggle word wrap Toggle overflow
36.7. The provider option in the ipaidp Ansible module Copy linkLink copied to clipboard!
Review the supported external identity providers (IdPs) and their configuration templates for the ipaidp Ansible module.
The following IdPs support OAuth 2.0 device authorization grant flow:
- Microsoft Identity Platform, including Azure AD
- GitHub
- Keycloak, including Red Hat Single Sign-On (SSO)
- Okta
When using the ipaidp ansible-freeipa module to create a reference to one of these external IdPs, you can specify the IdP type with the provider option in your ansible-freeipa playbook task, which expands into additional options as described below:
provider: microsoftMicrosoft Azure IdPs allow parametrization based on the Azure tenant ID, which you can specify with the
organizationoption. If you need support for the live.com IdP, specify the optionorganization common.Choosing
provider: microsoftexpands to use the following options. The value of theorganizationoption replaces the string${ipaidporg}in the table.Expand Option Value auth_uri: URIhttps://login.microsoftonline.com/${ipaidporg}/oauth2/v2.0/authorizedev_auth_uri: URIhttps://login.microsoftonline.com/${ipaidporg}/oauth2/v2.0/devicecodetoken_uri: URIhttps://login.microsoftonline.com/${ipaidporg}/oauth2/v2.0/tokenuserinfo_uri: URIhttps://graph.microsoft.com/oidc/userinfokeys_uri: URIhttps://login.microsoftonline.com/common/discovery/v2.0/keysscope: STRopenid emailidp_user_id: STRemailprovider: googleChoosing
provider: googleexpands to use the following options:Expand Option Value auth_uri: URIhttps://accounts.google.com/o/oauth2/authdev_auth_uri: URIhttps://oauth2.googleapis.com/device/codetoken_uri: URIhttps://oauth2.googleapis.com/tokenuserinfo_uri: URIhttps://openidconnect.googleapis.com/v1/userinfokeys_uri: URIhttps://www.googleapis.com/oauth2/v3/certsscope: STRopenid emailidp_user_id: STRemailprovider: githubChoosing
provider: githubexpands to use the following options:Expand Option Value auth_uri: URIhttps://github.com/login/oauth/authorizedev_auth_uri: URIhttps://github.com/login/device/codetoken_uri: URIhttps://github.com/login/oauth/access_tokenuserinfo_uri: URIhttps://openidconnect.googleapis.com/v1/userinfokeys_uri: URIhttps://api.github.com/userscope: STRuseridp_user_id: STRloginprovider: keycloakWith Keycloak, you can define multiple realms or organizations. Since it is often a part of a custom deployment, both base URL and realm ID are required, and you can specify them with the
base_urlandorganizationoptions in youripaidpplaybook task:Copy to Clipboard Copied! Toggle word wrap Toggle overflow Choosing
provider: keycloakexpands to use the following options. The value you specify in thebase_urloption replaces the string${ipaidpbaseurl}in the table, and the value you specify for theorganization `option replaces the string `${ipaidporg}.Expand Option Value auth_uri: URIhttps://${ipaidpbaseurl}/realms/${ipaidporg}/protocol/openid-connect/authdev_auth_uri: URIhttps://${ipaidpbaseurl}/realms/${ipaidporg}/protocol/openid-connect/auth/devicetoken_uri: URIhttps://${ipaidpbaseurl}/realms/${ipaidporg}/protocol/openid-connect/tokenuserinfo_uri: URIhttps://${ipaidpbaseurl}/realms/${ipaidporg}/protocol/openid-connect/userinfoscope: STRopenid emailidp_user_id: STRemailprovider: oktaAfter registering a new organization in Okta, a new base URL is associated with it. You can specify this base URL with the
base_urloption in theipaidpplaybook task:Copy to Clipboard Copied! Toggle word wrap Toggle overflow Choosing
provider: oktaexpands to use the following options. The value you specify for thebase_urloption replaces the string${ipaidpbaseurl}in the table.Expand Option Value auth_uri: URIhttps://${ipaidpbaseurl}/oauth2/v1/authorizedev_auth_uri: URIhttps://${ipaidpbaseurl}/oauth2/v1/device/authorizetoken_uri: URIhttps://${ipaidpbaseurl}/oauth2/v1/tokenuserinfo_uri: URIhttps://${ipaidpbaseurl}/oauth2/v1/userinfoscope: STRopenid emailidp_user_id: STRemail