gpe_mw_ansible.rh_sso_multi_realm
= rh-sso-multi-realm
== 概述
该角色旨在为红帽的OpenShift容器平台 (OCP) 提供持久的 Red Hat Single Sign-On (RH-SSO) 安装。
它还允许管理(即:创建和删除)在该RH-SSO安装中可配置数量的SSO _领域_。
此角色可能在以下情况下有价值:
. 教师指导培训 (ILT)、黑客松和研讨会: + 给定在ILT中需要RH-SSO的X名学生,提供一个中央的多领域RH-SSO,其中每位学生被分配自己的领域。 + 学生将获得其分配领域的管理凭证。 + 与每个学生自行提供其RH-SSO的替代方案相比,这种方法可能更受欢迎。
. RH-SSO启用 + 一些学习目标可能包括:
.. 演示在OCP上提供RH-SSO。 + 特别是利用OCP的服务提供x509证书密钥的RH-SSO变体。
.. 与外部SMTP供应商的集成以发送电子邮件并促进用户自我注册流程。 .. 使用OAuth2 访问 和 刷新 令牌调用RH-SSO的REST管理API。
注意:此Ansible角色尚未使用Keycloak-operator。 原因主要是目前实施的操作员无法配置健康检查和限制与请求,详细信息请参阅此处。 与操作员相关的正在进行的jira列表请参见这里。
=== 参考
. 最新的keycloak文档 . RH-SSO for OCP . OCP服务提供证书密钥
=== 假设和前提条件 . 确保在本地计算机上安装了ansible。 + 此ansible角色在Fedora 29上最近测试的ansible版本为:2.6.5-1。
. 该ansible角色假设存在一个具有至少6GB RAM和2个CPU的远程OCP集群。 + 该ansible角色在OCP 3.11.43版本上进行了最新测试。
. 此Ansible角色重度使用在本地计算机上运行的oc
客户端。
确保此oc
客户端位于本地环境的$PATH中,并且版本与您的OCP环境匹配。
. [蓝色]#本地oc客户端需要先验证为集群管理员用户,才能连接到远程OCP环境。#
==== 通配符证书
此ansible角色假设您现有的OCP集群使用合法证书颁发机构(如LetsEncrypt)签名的证书进行配置。
注意:来自红帽合作伙伴演示系统(RHPDS)和红帽开放合作伙伴启用网络(OPEN)的OCP集群研讨会配备了LetsEncrypt证书。 您可以跳过此部分。
获取LetsEncrypt通配符证书并将其应用于您的OCP集群的一个很好的教程可以在以下位置找到:
嘿Tate:如何为开发系统购买有效的SSL证书域名。 ** https://youtu.be/sBcDnQj9_QM ** https://docs.google.com/document/d/1APb8DF9JkbuGA3FaI8cXdSeFU0FsW93auUofPj6n4zo/edit?usp=sharing
嘿Tate:使用certbot免费为您的域名创建有效的通配符SSL证书! ** https://youtu.be/3D4-MWG1Bew ** https://docs.google.com/document/d/1m8FFTybu5VIYkRlWvqqFBsIO3a9GznbLkxZyyEI4vto/edit?usp=sharing
嘿Tate:在本地运行OpenShift和路由,并使用有效的SSL证书。 ** https://youtu.be/JvU5BWE5pS8 ** https://docs.google.com/document/d/1hk3yacNkDWHdcSJb7SOl_9wblVq_hvwlaoVK35P-EVQ/edit?usp=sharing
为您的整个OCP集群提供的通配符证书的替代方法是使用LetsEncrypt证书保护RH-SSO路由。
== RH-SSO部署
=== 环境变量
以下环境变量需要在您将要执行ansible的本地环境的shell中设置。 这些环境变量将在此角色中使用。
更新每个以下内容,然后执行:
echo "export OCP_PROJECT_PREFIX=<您的首字母>" >> ~/.bashrc # 在实验中创建OCP项目时稍后使用 echo "export ocp_sso_admin_id=sso0" >> ~/.bashrc
执行以下操作:
echo "export SSO_SITE_ADMIN_USERNAME=master" >> ~/.bashrc echo "export SSO_SITE_ADMIN_PASSWORD=master" >> ~/.bashrc echo "export rhsso_project=rhsso-$ocp_sso_admin_id" >> ~/.bashrc source ~/.bashrc
OCP通配符DNS在“apps”后; 例如; 2345.openshift.opentlc.com
示例:
Code Ready Containers: SUBDOMAIN_BASE=crc.testing
ravello vm : SUBDOMAIN_BASE=oc whoami --show-server | cut -d'-' -f 2 | cut -d':' -f 1
ocp workshop : SUBDOMAIN_BASE=oc whoami --show-server | cut -d'.' -f 2,3,4,5 | cut -d':' -f 1
echo "export SUBDOMAIN_BASE=oc whoami --show-server | cut -d'.' -f 2,3,4,5 | cut -d':' -f 1
" >> ~/.bashrc
source ~/.bashrc
=== Ansible设置
. 安装此角色: +
$ ansible-galaxy install gpe_mw_ansible.rh_sso_multi_realm --force -p /etc/ansible/roles
- 另外,您也可以像同样安装该角色到本地:
$ ansible-galaxy install gpe_mw_ansible.rh_sso_multi_realm --force -p $HOME/.ansible/roles
. 创建Playbook: +
$ echo "
- hosts: all
become: false
gather_facts: False
vars_files:
roles:
- gpe_mw_ansible.rh_sso_multi_realm " > /tmp/rh_sso_multi_realm.yml
=== 提供RH-SSO
RH-SSO多领域应用的OCP命名空间将由以下用户拥有:{{ocp_sso_admin_id}}。 用户{{ocp_sso_admin_id}}将被分配一个集群配额,以便管理分配给3scale的限制和请求。
. 确保ImageStream在openshift
命名空间内:
.. redhat-sso73-openshift图像流。
+
如果此图像流在openshift
命名空间中不存在,请执行以下操作:
+
$ oc create -f https://raw.githubusercontent.com/jboss-container-images/redhat-sso-7-openshift-image/v7.4.0.GA/templates/sso74-image-stream.json -n openshift
. 执行: +
$ ansible-playbook -i localhost, -c local /tmp/rh_sso_multi_realm.yml
-e"ocp_user_needs_quota=true"
-e"ACTION=create"
-e"SSO_SITE_ADMIN_USERNAME=$SSO_SITE_ADMIN_USERNAME"
-e"SSO_SITE_ADMIN_PASSWORD=$SSO_SITE_ADMIN_PASSWORD"
-e"admin_username=$ocp_sso_admin_id"
-e"subdomain_base=$SUBDOMAIN_BASE"
. 设置一个环境变量,引用新提供的RH-SSO的URL: +
echo "export rhsso_hostname=$(oc get route sso -n rhsso-$ocp_sso_admin_id --template "{{.spec.host}}" -n rhsso-$ocp_sso_admin_id)" >> ~/.bashrc
source ~/.bashrc
. 提供完成后,查看与新RH-SSO服务器相关的证书: +
$ echo '' | openssl s_client -connect oc get route sso -n $rhsso_project --template "{{.spec.host}}"
:443 | more
- 假设您的OCP集群是通过LetsEncrypt证书颁发机构签发的通配符证书进行提供的,响应应包括以下内容:
... subject=CN = master.3295.openshift.opentlc.com
issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3 ...
. 如果OCP集群是通过LetsEncrypt(或其他合法)证书颁发机构提供并已签发通配符证书,您可以通过以下方式查看详细信息: +
$ curl -v -X GET "https://$rhsso_hostname/auth/realms/master/.well-known/openid-configuration" | python -m json.tool
...
- subjectAltName: host "sso-rhsso-sso0.apps.3295.openshift.opentlc.com" matched cert's "*.apps.3295.openshift.opentlc.com"
=== RH-SSO管理员控制台
. 打开网页浏览器并导航到master
领域的控制台:
+
$ echo -en "\nhttps://$rhsso_hostname/auth/admin/master/console\n\n"
. 使用在RH-SSO实例提供时使用的$SSO_SITE_ADMIN_USERNAME和$SSO_SITE_ADMIN_PASSWORD环境变量的值进行身份验证。
. 作为RH-SSO站点管理员,您可以完全访问其所有资源。 + image::images/master_homepage.png[]
=== 删除RH-SSO
$ ansible-playbook -i localhost, -c local /tmp/rh_sso_multi_realm.yml
-e"ACTION=remove"
-e"subdomain_base=$SUBDOMAIN_BASE"
[[realm_mgmt]] == 领域创建/删除
RH-SSO允许创建多个领域。 每个领域与其他领域完全独立。
安装的这一部分有助于为各种用例自动创建领域。
==== SMTP供应商
您可能希望RH-SSO的领域具备发送电子邮件的能力。
例如,作为此ansible角色的一部分配置的通用领域
被配置为用户注册流程,要求新用户通过电子邮件中提供的链接验证注册。
在RH-SSO中,SMTP设置是在一个_领域_的范围内进行配置的。 在提供领域时,您可以指定以下ansible变量:
- smtp_host
- smtp_userid
- smtp_passwd
一些经过此ansible角色测试的具有_免费计划_的SMTP供应商如下所示:
. SocketLabs: 当前提供的免费计划允许每月链接:2000封邮件 . SendGrid: 当前提供的免费计划允许每天链接:100封邮件
=== 通用领域
通过此ansible,可以根据以下变量的值创建可配置数量的SSO领域:first_generic_realm
和last_generic_realm
。
如果last_generic_realm
的值小于1,则不会创建通用领域。
这些通用领域的名称可以通过覆盖ansible变量:_realm_base_name_来进行自定义。
每个SSO领域都允许一个或多个用户注册为该领域的用户。 注册领域用户的默认行为是他们是领域的完全管理员。 显然,该行为仅适合演示和学习场景。
=== KIE领域 如果在创建领域时,将变量_loadKieRealm_设置为true,则将创建一个特定于支持商业和决策管理场景的特殊领域。
. 该_provisioned _kieRealm_的详细信息如下:
.. realmId: kieRealm .. 登录URL: https://$rhsso_hostname/auth/admin/kieRealm/console .. 领域管理员用户ID: ssoRealmAdmin .. 领域管理员密码: pam .. 与KIE相关的角色: ... admin ... kie-server ... kiemgmt ... rest-all
. 与此领域注册的所有用户的详细信息可以通过以下方式识别: +
$ cat templates/kie-realm.json | jq .users
=== CRW领域 如果在创建领域时,将变量_loadCRWRealm_设置为true,则将创建一个特定于支持Code Ready Workspaces的特殊领域。
该_provisioned _crwRealm_的详细信息如下:
. realmId: crwRealm . 登录URL: https://$rhsso_hostname/auth/admin/crwRealm/console . 管理员用户ID: admin . 管理员密码: admin
=== OpenShift领域
如果在创建领域时,将变量_loadOCPRealm_设置为true,则将在您的RH-SSO中创建一个名为ocp-realm
的领域。
其目的是作为链接:身份提供者以进行OCP身份验证。
该_provisioned _ocp-realm_的详细信息如下:
. realmId: ocp-realm . 登录URL: https://$rhsso_hostname/auth/admin/ocp-realm/console . SSO客户端: ocp-client . 管理员用户ID: gpte-mgr . 管理员密码: r3dh4t1! . 与OCP相关的角色: + 无。角色必须由集群管理员分配。
在RH-SSO中提供ocp-realm
之后,需要在OCP的主节点上执行一些附加步骤。
有关这些步骤的详细信息,请参见:{{new_app_output_dir}}/ocp-realm-suggestion.txt。
在master-config.xml
文件的身份提供者部分中,请记得用ocp-client设置覆盖htpasswd部分。
=== 创建领域
. 在您的shell中设置以下环境变量,然后执行如下所示的ansible命令: +
smtp_host= # SMTP提供程序详细信息,允许RH-SSO支持用户注册等功能发送电子邮件 smtp_userid= smtp_passwd=
FIRST_GENERIC_REALM=1 # 将初始化的第一个领域将为: realm$FIRST_GENERIC_REALM LAST_GENERIC_REALM=1 # 将初始化的最后一个领域将为: realm$LAST_GENERIC_REALM ; 如果值小于1,则不会创建通用领域 realm_base_name=realm # 通用领域的基本名称。 默认值为: realm。
loadKieRealm=false # 默认值为false。如果为true,则将初始化一个用于支持红帽过程自动化和决策管理安装的领域
loadCRWRealm=false # 默认值为false。如果为true,则将初始化一个领域以支持红帽代码准备工作区
crw_redirect_url="" # 仅在loadCRWRealm=true时适用。 设置为CodeReadyWorkspace路由的URL。
loadOCPRealm=true # 默认值为false。如果为true,则将配置一个名为ocp-realm的领域,可以用于配置OCP以利用RH-SSO进行身份验证 end_ocp_user=1 # 在ocp-realm中创建的最后一个用户将为: user$end_ocp_user
$ ansible-playbook -i localhost, -c local /tmp/rh_sso_multi_realm.yml
-e"ACTION=realm_mgmt"
-e"create_realms=true"
-e"subdomain_base=$SUBDOMAIN_BASE"
-e"smtp_host=$smtp_host"
-e"smtp_passwd=$smtp_passwd"
-e"smtp_userid=$smtp_userid"
-e"SSO_SITE_ADMIN_USERNAME=$SSO_SITE_ADMIN_USERNAME"
-e"SSO_SITE_ADMIN_PASSWORD=$SSO_SITE_ADMIN_PASSWORD"
-e"admin_username=$ocp_sso_admin_id"
-e"first_generic_realm=$FIRST_GENERIC_REALM"
-e"last_generic_realm=$LAST_GENERIC_REALM"
-e"realm_base_name=$realm_base_name"
-e"loadKieRealm=$loadKieRealm"
-e"loadCRWRealm=$loadCRWRealm"
-e"crw_redirect_url=$crw_redirect_url"
-e"loadOCPRealm=$loadOCPRealm"
-e"end_ocp_user=$end_ocp_user"
-e"rhsso_hostname=$rhsso_hostname"
. 执行完ansible后,控制台消息应写明如下: +
rh-sso-multi-realm : 领域部署完成]
ok: [localhost] => { "msg": [ "create_realms: true", "new_app_output_dir: /home/jbride/provisioning_output/3295.openshift.opentlc.com", "start and end realms = 1 25" ] }
- 创建的每个领域的json表示可以在提到的目录中找到:_new_app_output_dir_。
==== 删除领域
$ ansible-playbook -i localhost, -c local /tmp/rh_sso_multi_realm.yml
-e"ACTION=realm_mgmt"
-e"first_generic_realm=$FIRST_GENERIC_REALM"
-e"last_generic_realm=$LAST_GENERIC_REALM"
-e"subdomain_base=$SUBDOMAIN_BASE"
-e"SSO_SITE_ADMIN_USERNAME=$SSO_SITE_ADMIN_USERNAME"
-e"SSO_SITE_ADMIN_PASSWORD=$SSO_SITE_ADMIN_PASSWORD"
-e"admin_username=$ocp_sso_admin_id"
-e"rhsso_hostname=$rhsso_hostname"
-e"create_realms=false"
== 通用领域:用户注册
本实验的这一部分假定您已经根据本实验的<
本节的目的是为学生提供详细说明,说明如何注册为先前提供的通用SSO领域的用户。 整个部分可以直接复制粘贴到利用此多领域RH-SSO的课程的实验说明中。
. 设置一个与您想要使用的特定领域(例如<领域名称> = realm1...realm20)对应的环境变量: +
$ echo "export rhsso_realm=<领域名称>" >> ~/.bashrc
$ source ~/.bashrc
. 打开网页浏览器并导航到您的目标领域的控制台: +
$ echo -en "\nhttps://$rhsso_hostname/auth/admin/$rhsso_realm/console\n\n"
. 点击注册
链接:
+
image::images/register_link.png[]
. 填写注册表单的所有字段。 确保使用有效的电子邮件。
. 点击注册
。
. 期待您的浏览器被重定向到一个指示需要验证您的电子邮件和帐户的页面:
+
image::images/email_verification.png[]
. 检查您的电子邮件以获取类似以下的验证请求:
+
image::images/registration_email.png[]
. 在电子邮件中,单击电子邮件地址验证
的链接。
. 您的浏览器现在应该重定向到目标SSO领域的主页
+
image::images/realm_homepage.png[]
+
注意:此新注册领域用户对领域的所有设置具有管理访问权限。
. 在您的本地计算机的终端窗口中,设置特定于此新领域用户的环境变量: +
$ realmUserId=<更改我> $ realmPasswd=<更改我>
. 在您的浏览器中,导航到您的领域的客户端
。
+
注意到存在5个默认的SSO客户端。 每个客户端都被配置为允许不同的OAuth2和OIDC协议。
+
image::images/default_sso_clients.png[]
=== 通用领域:探索客户端
在OAuth2术语上下文中,客户端是代表_资源所有者_请求访问受保护资源的应用程序。 资源所有者通常是最终用户(也称为实体),受保护的资源可能是来自该资源所有者/实体的一个或多个机密属性。
RH-SSO允许创建自定义_客户端_。 但是在本实验的目的中,您将使用默认的_客户端_之一,该客户端附带您的_领域_。
==== 审查 realm-management
这是一个_仅限持有人_客户端,稍后将在实验的其他部分与受保护的后端服务相关联。
仅持有者客户端用于不与红帽SSO发起登录的后端服务,但需要有效的ID令牌。
ID令牌通常由后端服务用来通过基于角色的访问控制(RBAC)来确定对资源的访问。
==== 审查 admin-cli
在本实验中,您还定义了一个名为admin-cli
的第二个客户端。 admin-cli
是一个OAuth2客户端。您稍后将在本实验中仅用于测试目的使用admin-cli
。
请注意,admin-cli
已启用使用称为资源所有者密码凭据
的OAuth2流程。
通过此流程,客户端允许用户ID和密码凭据的交换——在本例中即您的SSO用户——以获取访问令牌。 然后可以使用此令牌来访问您的业务服务的REST API。
== 通用领域:端点
=== 概述
您的红帽SSO服务器实现了一个名为well-known
的端点,该端点列出了与红帽单点登录的OAuth2/OpenID Connect实现相关的其他端点和配置选项。
本节的目的是使用户(例如:学生)了解一些OIDC规范的well-known
端点。
这些well-known
端点特定于用户的SSO领域。
红帽SSO还暴露了领域管理端点。 此部分还介绍了几个领域管理端点。
整个部分可以直接复制粘贴到您的课程实验说明中。
您需要在本地计算机上安装以下工具:
. openssl
. keytool
: (来自Java开发工具包)
=== OIDC well-known端点
. 确保您的计算机上安装了jq工具。
. 执行以下命令并研究响应: +
$ curl -X GET "https://$rhsso_hostname/auth/realms/$rhsso_realm/.well-known/openid-configuration" | python -m json.tool
. 查看支持的grant_types_supported
类型列表:
+
$ curl -X GET "https://$rhsso_hostname/auth/realms/$rhsso_realm/.well-known/openid-configuration" | jq -r '.grant_types_supported'
- 示例输出
[ "authorization_code", "implicit", "refresh_token", "password", "client_credentials" ]
- 这些
grant_type_supported
类型对应于红帽SSO服务器支持的各种OAuth2/OpenID Connect流程。
=== OAuth2访问令牌
. 确保$rhsso_realm、$realmUserId和$realmPasswd环境变量的值在您的shell中设置。
. 从领域中检索OIDC访问令牌: +
$ retrieve_token_url="https://$rhsso_hostname/auth/realms/$rhsso_realm/protocol/openid-connect/token"
$ TKN=$(curl -X POST "$retrieve_token_url"
-H "Content-Type: application/x-www-form-urlencoded"
-d "username=$SSO_SITE_ADMIN_USERNAME"
-d "password=$SSO_SITE_ADMIN_PASSWORD"
-d "grant_type=password"
-d "client_id=admin-cli"
| sed 's/.access_token":"//g' | sed 's/".//g')
- 注意:此OAuth2令牌端点的响应还可以解析以获取_refresh_token_。 然后可以选择使用_refresh_token_在访问令牌过期时刷新访问令牌。
=== 领域公钥 在本节中,您将检索领域的公钥。 稍后,此公钥可以包含在插入后端业务服务的_keycloak适配器_中。 后端服务将能够参与OpenID Connect流程。
. 创建领域时,会自动生成一个密钥对和自签名证书。 + Keycloak当前仅支持RSA签名,因此只有一个活动的密钥对。 . 设置$retrieve_key_url环境变量的值: +
$ retrieve_key_url="https://$rhsso_hostname/auth/admin/realms/$rhsso_realm/keys"
. 检索RSA密钥的值: +
$ RSA_PUB_KEY=$(curl -k -X GET "$retrieve_key_url"
-H "Authorization: Bearer $TKN"
| jq -r '.keys[] | select(.type=="RSA") | .publicKey'
)
$ echo $RSA_PUB_KEY MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAktETcy8xI/rxit6DH9LW1kAB/0XKiV5eujQL9rL+9WD9ZruC2hMFKhme+kyNjNVCf2cqiY0IChmSqTrfm7OcL3k+Rfq91zDgMI19pszoMGyG2Ek2UZYWNBhydBIPBr70njec7Vq8a/bn88evEROetlUHWWcSuwqsiooHD3RNzuDgRB+2ztim8KttusbZxGPGjIjCNlFEBVetfxpHbTBCeN8dAdOiYRjmW6QVxEUH9m0Hcvcw8XwEyVRvd1HpkzMK0BVBnN73d/G743pvyc2huv/Cj+zoBipxNwKJ8rnPGupBVK/17WmyFgi+CDhZww8EwRiSSwrow+Qv1hUP9bnoFwIDAQAB
=== 可选:查看领域RSA证书
. 检索领域RSA证书的值: +
$ RSA_CERT=$(curl -k -X GET "$retrieve_key_url"
-H "Authorization: Bearer $TKN"
| jq -r '.keys[] | select(.type=="RSA") | .certificate'
)
$ echo $RSA_CERT MIICuTCCAaECBgFcJ85oAjANBgkqhkiG9w0BAQsFADAgMR4wHAYDVQQDDBVyaHRfZ3B0ZV8zc2NhbGVfcmVhbG0wHhcNMTcwNTIwMjEzOTE3WhcNMjcwNTIwMjE0MDU3WjAgMR4wHAYDVQQDDBVyaHRfZ3B0ZV8zc2NhbGVfcmVhbG0wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCS0RNzLzEj+vGK3oMf0tbWQAH/RcqJXl66NAv2sv71YP1mu4LaEwUqGZ76TI2M1UJ/ZyqJjQgKGZKoGt+bs5wveT5F+r3XMOAwjX2mzOgwbIbYSTZRlhY0GHJ0Eg8GvvSeN5ztWrxr9ufzx68RE562VQdZZxK7CqyKigcPdE3O4OBEH7bO2Kbwq226xtnEY8aMiMI2UUQFV61/GkdtMEJ43x0B06JhGOZbpBXERQf2bQdy9zDxfATJVG93UemTMwrQFUGc3vd38bvjem/JzaG6/8KP7OgGKnE3Aonyuc8a6kFUr/XtabIWCL4IOFnDDwTBGJJLCujD5C/WFQ/1uegXAgMBAAEwDQYJKoZIhvcNAQELBQADggEBABM81ImbVgN5VoD7b7RCH0jYW9pUzIwjUUWU3P1E+RGMwyyhgCwMK/wDpzty5jno7XyE1oePgZg8OmXY2FGlWi0JzCF8WGsHVEZWiKPkSs9miz5+x5VqKUEM4nrmF3OgEFPH/gJPhx8/GNutSpf0AIHcVDeWL7nayyjMZWSdXm82crd5gZXDSmNgjjeqhTCPFCrMv3nQq9wsL3jDEc7pOAkblsu83GCyD0WmdHqAY/EdT/Jz1b2lJw/Oda6b9Hg93MvnnaJMam7Q7q4K0oRFaYD0ZtYm926YQg5f1iLzoocuouuOeHrMfZQOqb96iaGYeQF+GghpfNXwKMLOhQh3tJM=
. 从证书创建PEM文件: .. 设置一个环境变量,定义以PEM格式的目标x.509证书的路径: +
$ realm_cert=/tmp/$rhsso_realm.pem
.. 创建PEM格式的x.509证书: +
$ echo "-----BEGIN CERTIFICATE-----" > $realm_cert; echo $RSA_CERT >> $realm_cert; echo "-----END CERTIFICATE-----" >> $realm_cert
. 查看SSO领域证书的详细信息: +
$ openssl x509 -in $realm_cert -text -noout
== 通用领域:烟雾测试OAuth2身份验证和RBAC
=== 受保护的业务服务概述
通常,服务需要关于调用其功能的最终用户的身份信息。 一个常见的用例是基于角色的访问控制(RBAC)的需求。 基于最终用户的角色,业务服务确定是否允许访问被调用的资源。
注意:后端业务服务处理的RBAC与 API管理器处理的_策略_和_速率限制_强制执行是不同的。
在本实验的这一部分,您将使用使用Thorntail Java Microprofile技术编写的简单后端服务烟雾测试OAuth2/OIDC安全性。
该简单服务的源代码可以在此处找到。
为了使您的microprofile后端服务实现RBAC,需要进行以下操作:
- 在您的业务服务中编织RBAC规则:为了本实验的目的,此步骤已经为您完成。
特别注意以下代码片段,新代码片段位于
src/main/resources/project-defaults.yml
配置文件中:
swarm: deployment: wf-swarm-oauth.war: web: login-config: auth-method: KEYCLOAK security-constraints: - url-pattern: / methods: [GET] roles: [admin]
*添加_keycloak适配器_*:您的后端服务需要被注入功能,以便它能与红帽SSO服务器通信。 特别是,它需要提取红帽SSO服务器领域的公钥。
使用红帽SSO领域的公钥解压JWT:在运行时,后端业务服务会接收到包含有关最终用户的身份信息的JSON Web Token (JWT)。 这些身份信息包括最终用户的
角色
。 一旦JWT被接收,嵌入的Keycloak适配器会验证JWT的真实性(使用红帽SSO领域的公钥)。 一旦JWT被验证为来自您的红帽SSO服务器,业务服务将使用身份信息来决定最终用户是否具有访问所请求资源的正确凭据。
=== 部署 在本节中,您将定义一个DeploymentConfig,用于通过OIDC协议保护的简单后端业务服务。
. 为您的模拟RESTful业务服务应用程序创建一个新项目: +
$ oc new-project $OCP_PROJECT_PREFIX-bservices
--display-name="$OCP_PROJECT_PREFIX-bservices"
--description="将通过OIDC进行保护的业务服务"
. 如果尚未切换到此新项目,请切换到此新项目: +
$ oc project $OCP_PROJECT_PREFIX-bservices
. 创建一个基于使用Wildfly Swarm实现的简单RESTful服务的新应用程序: +
$ oc new-app
--template=wf-swarm-oauth
--param=JAVA_OPTIONS="-Djavax.net.debug=ssl -Dswarm.keycloak.json.path=/app/rhsso-config/keycloak.json"
- 此命令创建一个保持暂停的pod的部署配置。
pod包括一个基于Java的容器。
容器中JVM的
--XmX
设置为1Gi的80%;约800 MB。
=== keycloak.json
适配器
. 定义与现有的名为realm-management
的仅持有者
客户端特定的keycloak适配器:
+
$ echo " { "realm": "$rhsso_realm", "bearer-only": "true", "auth-server-url": "http://$rhsso_hostname/auth", "ssl-required": "external", "realm-public-key": "$RSA_PUB_KEY", "resource": "realm-management", "use-resource-role-mappings": "true" }" > /tmp/keycloak.json
. 从keycloak.json
文件创建ConfigMap。
+
然后将其作为卷挂载,并使WildFly Swarm指向挂载的keycloak.json
。
.. 在OpenShift的bservices
项目中,从keycloak.json
文件中创建名称为date-service-rhsso
的ConfigMap:
+
$ oc create configmap keycloak-resource-cm --from-file=/tmp/keycloak.json
.. 在Swarm DC中将configmap挂载为卷: +
$ oc set volume dc/wf-swarm-oauth --add --overwrite
--name=keycloak-resource-volume
-m /app/rhsso-config
--type=configmap
--configmap-name=keycloak-resource-cm
. 恢复暂停的DeploymentConfig: +
$ oc rollout resume dc/wf-swarm-oauth
. 查看安全WildFly Swarm服务的日志文件。 应出现类似以下内容的日志语句: +
DEBUG [org.keycloak.adapters.undertow.KeycloakServletExtension] (ServerService Thread Pool -- 11) KeycloakServletException initialization DEBUG [org.keycloak.adapters.undertow.KeycloakServletExtension] (ServerService Thread Pool -- 11) using /WEB-INF/keycloak.json DEBUG [org.keycloak.adapters.authentication.ClientCredentialsProviderUtils] (ServerService Thread Pool -- 11) Using provider 'secret' for authentication of client 'realm-management' DEBUG [org.keycloak.adapters.authentication.ClientCredentialsProviderUtils] (ServerService Thread Pool -- 11) Loaded clientCredentialsProvider secret DEBUG [org.keycloak.adapters.authentication.ClientCredentialsProviderUtils] (ServerService Thread Pool -- 11) Loaded clientCredentialsProvider jwt DEBUG [org.keycloak.adapters.KeycloakDeployment] (ServerService Thread Pool -- 11) resolveUrls DEBUG [org.keycloak.adapters.KeycloakDeploymentBuilder] (ServerService Thread Pool -- 11) Use authServerUrl: https://sso-rhsso-sso0.apps.3295.openshift.opentlc.com/auth, tokenUrl: https://sso-rhsso-sso0.apps.3295.openshift.opentlc.com/auth/realms/realm1/protocol/openid-connect/token, relativeUrls: NEVER DEBUG [org.keycloak.adapters.undertow.KeycloakServletExtension] (ServerService Thread Pool -- 11) Keycloak is using a per-deployment configuration. DEBUG [org.keycloak.adapters.wildfly.WildflyKeycloakServletExtension] (ServerService Thread Pool -- 11) creating WildflyAuthenticationMechanism DEBUG [org.keycloak.adapters.undertow.KeycloakServletExtension] (ServerService Thread Pool -- 11) Setting jsession cookie path to: /
... INFO [org.wildfly.swarm] (main) WFSWARM99999: WildFly Swarm is Ready
=== 测试OIDC保护的业务服务:
. 执行以下操作以获取新的访问令牌(因为原始访问令牌可能已经过期): +
$ TKN=$(curl -k -X POST "$retrieve_token_url"
-H "Content-Type: application/x-www-form-urlencoded"
-d "username=$realmUserId"
-d "password=$realmPasswd"
-d "grant_type=password"
-d "client_id=admin-cli"
| sed 's/.access_token":"//g' | sed 's/".//g')
- 从技术上讲,最佳方法是使用OAuth2的_refresh_token_功能,而不是重新生成新的访问令牌。
使用这种方法,请在请求正文中指定参数
grant_type=refresh_token&refresh_token=$REFRESH_TOKEN
。 $REFRESH_TOKEN的值可以通过从原始请求OAuth2令牌的响应中解析获取。
. 执行以下操作以使用Oauth2访问令牌调用后端RESTful服务: +
$ curl -k -v -X GET
-H "Authorization: Bearer $TKN"
https://oc get route/wf-swarm-oauth --template "{{.spec.host}}"
/time/now
. 返回的响应应包含类似以下的头和主体: +
...
- TLSv1.2 (IN), TLS handshake, Finished (20):
- SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
- ALPN, server did not agree to a protocol
- Server certificate:
- subject: CN=master.3295.openshift.opentlc.com
- start date: Nov 13 20:48:38 2018 GMT
- expire date: Feb 11 20:48:38 2019 GMT
- issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
- SSL certificate verify ok.
GET /time/now HTTP/1.1 Host: wf-swarm-oauth-jb-bservices.apps.3295.openshift.opentlc.com User-Agent: curl/7.61.1 Accept: / Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJIbm5ZV1NMM1pqSTh0T0VHZVlWZHpIbXVVSFpYSDdJbHM1dEJkSVU0VHMwIn0.eyJqdGkiOiIwOWQyZDZhMC1kZmRjLTRjNTctOWZjOC1mMDVjZGU0MjFjMjAiLCJleHAiOjE1NDIyMTQwMzYsIm5iZiI6MCwiaWF0IjoxNTQyMjEzNzM2LCJpc3MiOiJodHRwczovL3Nzby1yaHNzby1zc28wLmFwcHMuMzI5NS5vcGVuc2hpZnQub3BlbnRsYy5jb20vYXV0aC9yZWFsbXMvcmVhbG0xIiwiYXVkIjoiYWRtaW4tY2xpIiwic3ViIjoiNDc2Y2ZlOTAtMTQwMC00ODUwLTg5M2YtNjNlNWM5MjFmMjYxIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYWRtaW4tY2xpIiwiYXV0aF90aW1lIjowLCJzZXNzaW9uX3N0YXRlIjoiNmQ2ODcyZjgtMjQwZC00MWVjLWE4NmQtM2FiOGEyZTVmZWE5IiwiYWNyIjoiMSIsImFsbG93ZWQtb3JpZ2lucyI6W10sInJlc291cmNlX2FjY2VzcyI6e30sIm5hbWUiOiJKZWZmIEJyaWRlIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiamJyaWRlIiwiZ2l2ZW5fbmFtZSI6IkplZmYiLCJmYW1pbHlfbmFtZSI6IkJyaWRlIiwiZW1haWwiOiJqYnJpZGUrMUByZWRoYXQuY29tIn0.PoqUaPncOt9GFpCdHTQE1zuVK3FHTrgkBhmthww9geM-pbV84UTLXr1ggD-v7s9DGYAaVTe7ZUcda0DT5ioADpPuik6qADPf0ZkkWGQiQ6aieBxuTikM0NeeM58Vwhcr5lDphD0VY70SK_aaevUKkZFkmKxUxeUj-8TZob0n5Jip376D8NvDtfoZEhiWngBW58H1J4-sg27qzaUgVqaEoM7zUEvZocgD6j6rUqnThNREJVMi3sUYli6y_LzzqrMwZrWTlxAIYcR6OQ7GK-WTtN_F18_5O28Zaojq1QRHjhotcHPXCTrJaf4XqNEZFGML8yVh5lgzd-HVMt3Lrd_15Q
< HTTP/1.1 200 OK
...
{"value" : "当前时间是2018-11-14T16:44:57.576Z"}
. 查看安全WildFly Swarm服务的日志文件。 日志语句类似于以下内容: +
DEBUG [org.keycloak.adapters.PreAuthActionsHandler] (default task-1) adminRequest http://wf-swarm-oauth-jb-bservices.apps.3295.openshift.opentlc.com/time/now DEBUG [org.keycloak.adapters.wildfly.WildflyRequestAuthenticator] (default task-1) propagate security context to wildfly DEBUG [org.keycloak.adapters.RequestAuthenticator] (default task-1) 用户 '476cfe90-1400-4850-893f-63e5c921f261' 正在调用 'http://wf-swarm-oauth-jb-bservices.apps.3295.openshift.opentlc.com/time/now' 上的客户端 'realm-management' DEBUG [org.keycloak.adapters.RequestAuthenticator] (default task-1) 持有人AUTHENTICATED DEBUG [org.keycloak.adapters.AuthenticatedActionsHandler] (default task-1) AuthenticatedActionsValve.invoke http://wf-swarm-oauth-jb-bservices.apps.3295.openshift.opentlc.com/time/now DEBUG [org.keycloak.adapters.AuthenticatedActionsHandler] (default task-1) 政策强制执行已禁用。 INFO [stdout] (default task-1) userId = 476cfe90-1400-4850-893f-63e5c921f261
== 附录
=== 设置RH-SSO日志为DEBUG
(可选)
有时,您可能希望将RH-SSO服务器的org.keycloak
Java包的日志级别从INFO
提高到DEBUG
。
这样做在尝试解决安全协议和RH-SSO问题时非常有益。
. 打开到您的RH-SSO pod的远程shell会话: +
$ oc rsh -n $rhsso_project
$(oc get pod -n $rhsso_project | egrep "sso-[1-9]" | awk '{print $1}')
. 编辑RH-SSO服务器的主配置文件: .. 在编辑器中打开配置文件: +
$ vi /opt/eap/standalone/configuration/standalone-openshift.xml
.. 搜索org.jboss.as.config
字段:
+
<logger category="org.jboss.as.config">
<level name="DEBUG"/>
</logger>
.. 在此XML块下方添加相似的块,如下所示: +
<logger category="org.keycloak">
<level name="DEBUG"/>
</logger>
.. 保存更改并退出。
. 重新启动同一RH-SSO pod中的keycloak JVM: .. 切换到以下目录: +
cd /opt/eap/bin/
.. 执行以下命令: +
./jboss-cli.sh --connect ':reload'
Red Hat Single Sign-On Multi-Realm Automated Provisioning
ansible-galaxy install gpe_mw_ansible.rh_sso_multi_realm