1.概述

Keycloak支持OpenID Connect (OAuth 2.0的扩展) 和SAML 2.0。 当保护客户和服务时,你需要做的第一件事 决定您要使用的两个中的哪一个。 如果需要,还可以选择使用OpenID Connect保护某些安全,而使用SAML保护其他安全。

为了保护客户端和服务,您还需要为您选择的协议提供适配器或库。 Keycloak自带 选定平台的适配器,但也可以使用通用的OpenID Connect依赖方和SAML服务提供商库。

1.1。什么是客户端适配器?

Keycloak客户端适配器是使使用Keycloak保护应用程序和服务变得非常容易的库。 我们称他们为 适配器而不是库,因为它们提供了与底层平台和框架的紧密集成。 这使得我们的适配器易于使用,而且它们 与库通常所需的样板代码相比,所需的样板代码更少。

1.2。支持的平台

1.2.1。OpenID连接

JavaScript (客户端)
Node.js (服务器端)
C #
蟒蛇
安卓
iOS
Apache HTTP服务器

1.2.2。SAML

Apache HTTP服务器

1.3。支持的协议

1.3.1。OpenID连接

OpenID连接(OIDC) 是一种身份验证协议,它是OAuth 2.0。 虽然OAuth 2.0只是构建授权协议的框架,并且主要是不完整的,但OIDC是一个成熟的身份验证和授权 协议。 OIDC还大量使用Json网络令牌(JWT) 一套标准。 这些标准定义了一个 身份令牌JSON格式和以紧凑和网络友好的方式对数据进行数字签名和加密的方法。

使用OIDC时,实际上有两种类型的用例。 第一个是要求Keycloak服务器进行身份验证的应用程序 他们的用户。 成功登录后,应用程序将收到身份令牌和一个访问令牌。 的身份令牌 包含有关用户的信息,例如用户名,电子邮件和其他个人资料信息。 的访问令牌由数字签名 领域,并包含访问信息 (如用户角色映射),应用程序可以用来确定用户的资源 被允许在应用程序上访问。

第二类用例是想要访问远程服务的客户端的用例。 在这种情况下,客户询问Keycloak 以获得访问令牌它可以用来代表用户在其他远程服务上调用。 Keycloak对用户进行身份验证 然后要求用户同意向请求它的客户端授予访问权限。 然后,客户端接收访问令牌。 这个访问令牌 由王国数字签名。 客户端可以使用此功能对远程服务进行REST调用访问令牌。 休息服务 提取访问令牌,验证令牌的签名,然后根据令牌内的访问信息决定是否处理 请求。

1.3.2。SAML 2.0

SAML 2.0是与OIDC相似的规范,但更古老,更成熟。 它的根源是肥皂和过多的 WS-* 规格,因此它往往比OIDC更冗长。 SAML 2.0主要是一种身份验证协议 通过在身份验证服务器和应用程序之间交换XML文档来工作。 XML签名和加密用于验证请求和响应。

在Keycloak中,SAML提供两种类型的用例: 浏览器应用程序和REST调用。

使用SAML时,实际上有两种类型的用例。 第一个是要求Keycloak服务器进行身份验证的应用程序 他们的用户。 成功登录后,应用程序将收到一个XML文档,其中包含 称为SAML断言的东西,它指定有关用户的各种属性。 此XML文档由 领域,并包含访问信息 (如用户角色映射),应用程序可以用来确定用户的资源 被允许在应用程序上访问。

第二类用例是想要访问远程服务的客户端的用例。 在这种情况下,客户询问Keycloak 要获得SAML断言,它可以用来代表用户在其他远程服务上调用。

1.3.3。OpenID连接与SAML

在OpenID Connect和SAML之间进行选择不仅仅是使用较新的协议 (OIDC) 而不是较旧的更成熟的协议 (SAML)。

在大多数情况下,Keycloak建议使用OIDC。

SAML往往比OIDC更冗长。

除了交换数据的冗长性之外,如果您比较规格,您会发现OIDC旨在与web配合使用,而SAML则经过改装以在web上工作。 例如,OIDC也更适合HTML5/JavaScript应用程序,因为它是 在客户端比SAML更容易实现。 由于令牌采用JSON格式, 它们更容易被JavaScript消费。 你还会发现几个不错的功能 使在web应用程序中实现安全性变得更加容易。 例如,查看iframe技巧规范用于轻松确定用户是否仍在登录。

SAML有它的用途。 当您看到OIDC规范不断发展时,您会看到它们实现了SAML多年来拥有的越来越多的功能。 我们经常看到的是,人们选择SAML而不是OIDC,因为他们认为它更成熟,也因为他们已经有了用它保护的现有应用程序。

2. OpenID连接

本节介绍如何使用Keycloak适配器或通用OpenID Connect使用OpenID Connect保护应用程序和服务 依靠党的图书馆。

2.1。Java适配器

Keycloak为Java应用程序提供了一系列不同的适配器。 选择正确的适配器取决于目标平台。

所有Java适配器共享一组通用配置选项,该选项在Java适配器配置章。

2.1.1。Java适配器配置

Keycloak支持的每个Java适配器都可以通过一个简单的JSON文件进行配置。 这可能是什么样子:

{
  境界:演示,
  资源:客户门户,
  领域-公钥:MIGfMA0GCSqGSIb3D...31LwIDAQAB,
  身份验证-服务器-网址:https:// localhost:8443/auth,
  ssl-必需:外部,
  使用资源角色映射:,
  启用-cors:,
  cors-max-age:1000,
  cors-允许-方法:发布,放置,删除,获取,
  cors-暴露-标题:WWW-Authenticate,My-custom-exposed-Header,
  仅限不记名:,
  启用-基本-身份验证:,
  暴露-令牌:,
  验证-令牌-观众:,
   凭据: {
      秘密:234234-234234
   },

   连接-池-大小:20,
   套接字-超时-millis:5000,
   连接-超时-millis:6000,
   连接-ttl-millis:500,
   禁用信任管理器:,
   允许任意主机名:,
   信任商店:路径/到/信任存储。jks,
   信任商店-密码:盖海姆,
   客户端密钥库:路径/到/client-keystore.jks,
   客户端-密钥库-密码:盖海姆,
   客户端密钥密码:盖海姆,
   令牌-最短生存时间:10,
   jwks请求之间的最小时间:10,
   公钥缓存ttl:86400,
   重定向-重写-规则: {
   ^/wsmaster/api/(.*)$:/api/$1
   }
}

您可以使用${… }用于系统属性更换的外壳。 例如${jboss.server.config.dir}将被替换为/路径/到/Keycloak。 还通过以下方式支持环境变量的替换环境前缀,例如$ {环境。我的环境变量}

可以从管理控制台获得初始配置文件。 这可以通过打开管理控制台来完成,选择客户从菜单中点击 在相应的客户端上。 打开客户端页面后,单击安装选项卡并选择KeycloakOIDC JSON

以下是每个配置选项的描述:

境界

领域的名称。 这是必填。

资源

应用程序的客户端id。 每个应用程序都有一个客户端id,用于标识应用程序。 这是必填。

领域-公钥

领域公钥的PEM格式。 您可以从管理控制台获取此信息。 这是可选而且不建议设置它。 如果未设置,适配器将从Keycloak下载此文件,并 它将始终在需要时重新下载它 (例如 Keycloak旋转它的键)。 但是,如果设置了领域公钥,则适配器 永远不会从Keycloak下载新的密钥,所以当Keycloak旋转它的密钥时,适配器会损坏。

身份验证-服务器-网址

Keycloak服务器的基本URL。 所有其他Keycloak页面和REST服务端点均由此派生。 它通常是这样的形式https:// 主机: 端口/身份验证。 这是必填。

ssl-必需

确保与Keycloak服务器之间的所有通信都是通过HTTPS进行的。 在生产中,这应该设置为全部。 这是可选。 默认值为外部表示外部请求默认需要HTTPS。 有效值是 “全部” 、 “外部” 和 “无”。

机密端口

Keycloak服务器用于通过SSL/TLS进行安全连接的机密端口。 这是可选。 默认值为8443

使用资源角色映射

如果设置为true,则适配器将在令牌内部查找用户的应用程序级别角色映射。 如果为false,它将查看领域级别的用户角色映射。 这是可选。 默认值为

公共客户

如果设置为true,则适配器不会将客户端的凭据发送到Keycloak。 这是可选。 默认值为

启用-cors

这可以支持CORS。 它将处理CORS预检请求。 它还将调查访问令牌以确定有效的来源。 这是可选。 默认值为

cors-max-age

如果启用了CORS,这将设置访问控制-最大年龄头。 这是可选。 如果未设置,则不会在CORS响应中返回此标头。

cors-允许-方法

如果启用了CORS,这将设置访问控制允许方法头。 这应该是一个逗号分隔的字符串。 这是可选。 如果未设置,则不会在CORS响应中返回此标头。

cors-允许-标题

如果启用了CORS,这将设置访问控制允许标题头。 这应该是一个逗号分隔的字符串。 这是可选。 如果未设置,则不会在CORS响应中返回此标头。

cors-暴露-标题

如果启用了CORS,这将设置访问控制-暴露-标题头。 这应该是一个逗号分隔的字符串。 这是可选。 如果未设置,则不会在CORS响应中返回此标头。

仅限不记名

这应该设置为用于服务。 如果启用,适配器将不会尝试对用户进行身份验证,而只会验证承载令牌。 这是可选。 默认值为

自动检测-仅承载

这应该设置为如果您的应用程序同时提供web应用程序和web服务 (例如SOAP或REST)。 它允许您将未经身份验证的web应用程序用户重定向到Keycloak登录页面, 但是发送一个HTTP401状态代码到未经身份验证的SOAP或REST客户端,因为他们不理解重定向到登录页面。 Keycloak根据典型的标头自动检测SOAP或REST客户端X-请求-与,肥皂或者接受。 默认值为

启用-基本-身份验证

这告诉适配器也支持基本身份验证。 如果启用了此选项,则秘密还必须提供。 这是可选。 默认值为

暴露-令牌

如果,经过身份验证的浏览器客户端 (通过JavaScript HTTP调用) 可以通过URL获取签名的访问令牌根/k _ 查询 _ 承载 _ 令牌。 这是可选。 默认值为

凭据

指定应用程序的凭据。 这是一个对象表示法,其中键是凭证类型,值是凭证类型的值。 目前支持密码和jwt。 这是必需仅适用于具有 “机密” 访问类型的客户端。

连接-池-大小

此配置选项定义应汇集到Keycloak服务器的连接数量。 这是可选。 默认值为20

套接字-超时-millis

建立连接后等待数据的套接字超时,单位为毫秒。 两个数据包之间的最长不活动时间。 超时值为零被解释为无限超时。 负值被解释为未定义 (如果适用,系统默认值)。 默认值为-1。 这是可选

连接-超时-millis

与远程主机建立连接的超时时间 (毫秒)。 超时值为零被解释为无限超时。 负值被解释为未定义 (如果适用,系统默认值)。 默认值为-1。 这是可选

连接-ttl-millis

客户端的连接生存时间 (以毫秒为单位)。 小于或等于零的值被解释为无限值。 默认值为-1。 这是可选

禁用信任管理器

如果Keycloak服务器需要HTTPS,并且此配置选项设置为您不必指定信任商店。 此设置应仅在开发过程中使用,并且从不在生产中,因为它将禁用SSL证书的验证。 这是可选。 默认值为

允许任意主机名

如果Keycloak服务器需要HTTPS,并且此配置选项设置为Keycloak服务器的证书通过truststore进行验证, 但是主机名验证没有完成。 此设置应仅在开发过程中使用,并且从不在生产中,因为它将禁用SSL证书的验证。 这种设置在测试环境中可能很有用,这是可选。 默认值为

代理url

如果使用一个HTTP代理的URL。

信任商店

该值是truststore文件的文件路径。 如果您将路径前缀为类路径:,则将从部署的类路径中获取truststore。 用于向Keycloak服务器传出HTTPS通信。 客户端发出HTTPS请求需要一种方法来验证他们正在与之对话的服务器的主机。 这就是trustore所做的。 密钥库包含一个或多个受信任的主机证书或证书颁发机构。 您可以通过提取Keycloak服务器的SSL密钥库的公共证书来创建此信任库。 这是必需除非ssl-必需或者禁用信任管理器

信任商店-密码

信任商店的密码。 这是必需如果信任商店设置,并且信任商店需要密码。

客户端密钥库

这是密钥库文件的文件路径。 当适配器向Keycloak服务器发出HTTPS请求时,此密钥库包含双向SSL的客户端证书。 这是可选

客户端-密钥库-密码

客户端密钥库的密码。 这是必需如果客户端密钥库已设置。

客户端密钥密码

客户端密钥的密码。 这是必需如果客户端密钥库已设置。

始终刷新令牌

如果,适配器将在每个请求中刷新令牌。 警告-启用后,这将导致对您的应用程序的每个请求的Keycloak请求。

启动时的寄存器节点

如果,那么adapter将向Keycloak发送注册请求。 这是默认情况下,仅当应用程序聚集时才有用。 见应用聚类详情

寄存器节点周期

重新注册适配器到Keycloak的期限。 应用程序聚集时很有用。 见应用聚类详情

令牌存储

可能的值是会话饼干。 默认为会话,这意味着适配器在HTTP会话中存储帐户信息。 替代方案饼干意味着将信息存储在cookie中。 见应用聚类详情

令牌-cookie-路径

使用cookie存储时,此选项设置用于存储帐户信息的cookie的路径。 如果是相对路径, 然后假设应用程序在上下文根中运行,并且相对于该上下文根进行解释。 如果它是绝对路径,那么绝对路径用于设置cookie路径。 默认使用相对于上下文根的路径。

主体属性

OpenID Connect ID令牌属性以填充用户主体名称。 如果令牌属性为null,则默认为潜艇。 可能的值是潜艇,首选用户名,电子邮件,名称,昵称,给定名称,家庭名称

关闭-更改-会话-id-登录

在某些平台上成功登录时,默认情况下会更改会话id,以插入安全攻击向量。 如果要关闭此功能,请将其更改为true可选。 默认值为

令牌-最短生存时间

在Keycloak服务器到期之前抢先刷新活动访问令牌的时间 (以秒为单位)。 当访问令牌被发送到另一个REST客户端时,这尤其有用,在该客户端可能会在评估之前过期。 此值不应超过领域的访问令牌寿命。 这是可选。 默认值为0秒,因此适配器将在过期时刷新访问令牌。

jwks请求之间的最小时间

指定两个请求到Keycloak以检索新公钥的最小间隔的时间 (以秒为单位)。 默认情况下是10秒。 当适配器识别未知令牌时,它将始终尝试下载新的公钥孩子。 然而,它不会再尝试了 比每10秒一次 (默认情况下)。 这是为了避免攻击者发送大量带有不良令牌的DoS孩子强制适配器 向Keycloak发送大量请求。

公钥缓存ttl

指定两个请求到Keycloak检索新公钥的最大间隔的时间 (以秒为单位)。 默认情况下为86400秒 (1天)。 当适配器识别未知令牌时,它将始终尝试下载新的公钥孩子。 如果它识别已知的令牌孩子,它将 只需使用之前下载的公钥即可。 但是,在此配置的间隔中至少一次 (默认情况下为1天) 将是新的 公钥总是下载的,即使孩子令牌已经知道了。

忽略-oauth-查询-参数

默认为,如果设置为将关闭处理访问令牌 用于承载令牌处理的查询参数。 用户将无法进行身份验证 如果他们只通过一个访问令牌

重定向-重写-规则

如果需要,请指定重定向URI重写规则。 这是一个对象表示法,其中键是要匹配重定向URI的正则表达式,值是替换字符串。 $字符可用于替换字符串中的反向引用。

验证-令牌-观众

如果设置为,然后在使用承载令牌进行身份验证期间,适配器将验证令牌是否包含此 客户名称 (资源) 作为受众。 该选项对服务特别有用,服务主要是通过身份验证的请求 通过不记名令牌。 这设置为默认情况下,但是为了提高安全性,建议启用此功能。 见观众支持有关观众支持的更多详细信息。

2.1.2。JBoss EAP/WildFly适配器

为了保护部署在JBoss EAP、WildFly或JBoss AS上的WAR应用程序,您必须安装和配置 Keycloak适配器子系统。 然后,您有两种选择来确保战争的安全。

您可以在WAR中提供适配器配置文件,并在web.xml中将auth-method更改为KEYCLOAK。

另外,您根本不必修改WAR,也可以通过配置文件中的Keycloak适配器子系统配置来保护它,例如独立。xml。 本节介绍了这两种方法。

安装适配器

适配器可作为单独的存档使用,具体取决于您使用的服务器版本。

我们只测试和维护最新版本的WildFly版本的适配器。 一旦新版本 WildFly已发布,当前的适配器已被弃用,并且在下一次WildFly发布后将删除对它们的支持。 另一种选择是将您的应用程序从WildFly切换到JBoss EAP,因为JBoss EAP适配器支持更长的时间。

安装在WildFly 9或更高版本上:

$ cd $ WILDFLY_HOME
$ 解压缩keycloak-wildfly-adapter-dist-15.0.2.zip

安装在JBoss EAP 7上:

$ cd $ EAP_HOME
$ 解压缩keycloak-eap7-adapter-dist-15.0.2.zip

安装在JBoss EAP 6上:

$ cd $ EAP_HOME
$ 解压缩keycloak-eap6-adapter-dist-15.0.2.zip

作为7.1在JBoss上安装:

$ cd $ jbos_home
$ 解压缩keycloak-as7-adapter-dist-15.0.2.zip

此ZIP存档包含特定于Keycloak适配器的JBoss模块。 它还包含用于配置适配器子系统的JBoss CLI脚本。

若要配置适配器子系统,如果服务器未运行,请执行:

或者,您可以指定服务器。配置属性,同时从命令行安装适配器使用不同的配置安装适配器,例如:-Dserver.config = standalone-ha.xml
野蝇11或更新
$。/bin/jboss-cli.sh -- file = bin/adapter-elytron-install-offline.cli
10岁或以上的野蝇
$。/bin/jboss-cli.sh -- file = bin/adapter-install-offline.cli
也可以在WildFly 11或更高版本上使用旧版非Elytron适配器,这意味着您可以使用adapter-install-offline.cli 即使在那些版本上。 但是,我们建议使用较新的Elytron适配器。

或者,如果服务器正在运行,则执行:

野蝇11或更新
$。/bin/jboss-cli.sh -c -- file = bin/adapter-elytron-install.cli
10岁或以上的野蝇
$。/bin/jboss-cli.sh -c -- file = bin/adapter-install.cli
JBoss SSO

WildFly内置了对部署到同一WildFly的web应用程序的单点登录的支持 实例。 使用Keycloak时不应启用此功能。

每个战争配置所需

本节介绍如何通过在WAR包中添加配置和编辑文件来直接保护WAR。

你必须做的第一件事是创建一个Keycloak。json适配器配置文件中的网络信息你的战争目录。

此配置文件的格式在Java适配器配置节。

接下来,您必须设置auth-方法Keycloakweb.xml。 您还必须使用标准servlet安全性来指定url上的基于角色的约束。

下面是一个例子:

<网络应用 xmlns=http://java.sun.com/xml/ns/javaee
      xmlns:xsi=http:// www.w3.org/2001/XMLSchema-instance
      xsi: 模式定位=http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ web-app_3_0.xsd
      版本=3.0>

    <模块名称>应用</模块名称>

    <安全约束>
        <网络资源收集>
            <web-资源-名称>管理员</web-资源-名称>
            <url-模式>/管理员/*</url-模式>
        </网络资源收集>
        <授权约束>
            <角色名称>管理员</角色名称>
        </auth-constraint>
        <用户数据约束>
            <运输-保证>机密</运输-保证>
        </用户数据约束>
    </安全约束>
    <安全约束>
        <网络资源收集>
            <web-资源-名称>客户</web-资源-名称>
            <url-模式>/客户/*</url-模式>
        </网络资源收集>
        <授权约束>
            <角色名称>用户</角色名称>
        </auth-constraint>
        <用户数据约束>
            <运输-保证>机密</运输-保证>
        </用户数据约束>
    </安全约束>

    <登录配置>
        <身份验证方法>Keycloak</auth-方法>
        <境界-名称>目前忽略了这一点</领域名称>
    </登录配置>

    <安全-角色>
        <角色名称>管理员</角色名称>
    </安全角色>
    <安全-角色>
        <角色名称>用户</角色名称>
    </安全角色>
</网络应用>
通过适配器子系统保护战争

你不必修改你的战争来保护它。 相反,您可以通过Keycloak适配器子系统从外部保护它。 虽然您不必将KEYCLOAK指定为auth-方法,您仍然必须定义安全约束web.xml。 然而,你不必创建一个网络信息/Keycloak.json文件。 相反,此元数据是在服务器配置中定义的 (即独立。xml) 在Keycloak子系统定义中。

<扩展>
  <扩展 模块=组织。Keycloak-适配器-子系统/>
</扩展>

<个人资料>
  <子系统 xmlns=urn:jboss: 域: keycloak:1.1>
     <安全部署 名称=战争模块名称。战争>
        <境界>演示</领域>
        <身份验证-服务器-网址>http:// localhost:8081/auth</身份验证-服务器-网址>
        <ssl-必需>外部</ssl-必需>
        <资源>客户门户</资源>
        <凭证 名称=秘密>密码</凭证>
     </安全部署>
  </子系统>
</个人资料>

安全部署 名称属性标识您想要保护的战争。 它的值是模块名称中定义web.xml。战争附加。 其余的配置几乎与Keycloak。json中定义的配置选项Java适配器配置

例外的是凭证元素。

为了使您更容易,您可以转到Keycloak管理控制台,然后转到此WAR与之对齐的应用程序的客户端/安装选项卡。 它提供了一个示例XML文件,您可以剪切和粘贴。

如果您有由同一领域保护的多个部署,则可以在单独的元素中共享领域配置。 例如:

<子系统 xmlns=urn:jboss: 域: keycloak:1.1>
    <境界 名称=演示>
        <身份验证-服务器-网址>http:// localhost:8080/auth</身份验证-服务器-网址>
        <ssl-必需>外部</ssl-必需>
    </领域>
    <安全部署 名称=customer-portal.war>
        <境界>演示</领域>
        <资源>客户门户</资源>
        <凭证 名称=秘密>密码</凭证>
    </安全部署>
    <安全部署 名称=product-portal.war>
        <境界>演示</领域>
        <资源>产品门户</资源>
        <凭证 名称=秘密>密码</凭证>
    </安全部署>
    <安全部署 名称=数据库。战争>
        <境界>演示</领域>
        <资源>数据库-服务</资源>
        <仅承载></仅承载>
    </安全部署>
</子系统>
安全域

安全上下文会自动传播到EJB层。

2.1.3。从RPM安装JBoss EAP适配器

从RPM安装EAP 7适配器:

使用Red Hat Enterprise Linux 7,术语通道被术语存储库所取代。 在这些说明中,仅使用术语存储库。

您必须先订阅WildFly 23存储库,然后才能从RPM安装WildFly 7适配器。

先决条件
  1. 确保您的红帽企业Linux系统已使用红帽订阅管理器注册到您的帐户。 有关更多信息,请参见红帽订阅管理文档

  2. 如果您已经订阅了另一个JBoss EAP存储库,则必须首先取消订阅该存储库。

对于Red Hat Enterprise Linux 6,7: 使用Red Hat订阅管理器,使用以下命令订阅WildFly 23存储库: 根据您的红帽企业Linux版本,将 <RHEL_VERSION> 替换为6或7。

$ sudo订阅-管理器存储-启用 = jb-eap-7-for-rhel-<RHEL_VERSION>-服务器-rpms

对于Red Hat Enterprise Linux 8: 使用Red Hat订阅管理器,使用以下命令订阅WildFly 23存储库:

$ sudo订阅-管理器存储-启用 = jb-eap-23-for-rhel-8-x86_64-rpms-启用 = rhel-8-for-x86_64-baseos-rpms-启用 = rhel-8-for-x86_64-appstream-rpms

在Red Hat Enterprise Linux 6,7上使用以下命令为OIDC安装WildFly 7适配器:

$ sudo yum安装eap7-keycloak-adapter-sso7_4

或使用以下用于Red Hat Enterprise Linux 8:

$ sudo dnf安装eap7-keycloak-adapter-sso7_4
RPM安装的默认EAP_HOME路径为/opt/rh/eap7/root/usr/share/wildfly。

运行相应的模块安装脚本。

对于OIDC模块,输入以下命令:

$ $ EAP_HOME/bin/jboss-cli.sh -c-file = $ EAP_HOME/bin/adapter-install.cli

您的安装完成。

从RPM安装EAP 6适配器:

使用Red Hat Enterprise Linux 7,术语通道被术语存储库所取代。 在这些说明中,仅使用术语存储库。

您必须先订阅JBoss EAP 6存储库,然后才能从RPM安装EAP 6适配器。

先决条件
  1. 确保您的红帽企业Linux系统已使用红帽订阅管理器注册到您的帐户。 有关更多信息,请参见红帽订阅管理文档

  2. 如果您已经订阅了另一个JBoss EAP存储库,则必须首先取消订阅该存储库。

使用Red Hat订阅管理器,使用以下命令订阅JBoss EAP 6存储库: 根据您的红帽企业Linux版本,将 <RHEL_VERSION> 替换为6或7。

$ sudo订阅-管理器存储-启用 = jb-eap-6-for-rhel-<RHEL_VERSION>-服务器-rpms

使用以下命令安装OIDC的EAP 6适配器:

$ sudo yum安装keycloak-adapter-sso7_4-eap6
RPM安装的默认EAP_HOME路径为/opt/rh/eap6/root/usr/share/wildfly。

运行相应的模块安装脚本。

对于OIDC模块,输入以下命令:

$ $ EAP_HOME/bin/jboss-cli.sh -c-file = $ EAP_HOME/bin/adapter-install.cli

您的安装完成。

2.1.4。JBoss保险丝6适配器

Keycloak支持保护内部运行的web应用程序JBoss保险丝6

JBoss保险丝6杠杆Jetty 9适配器由于JBoss Fuse 6.3.0 Rollup 12与Jetty 9.2服务器 under the covers and Jetty用于运行各种web应用程序。

Fuse 6唯一受支持的版本是最新版本。 如果您使用较早版本的Fuse 6,则有可能某些功能无法正常工作。 特别是,霍蒂奥集成不适用于早期版本的Fuse 6。

Fuse支持以下项目的安全性:

在Fuse 6中保护您的Web应用程序

您必须首先安装Keycloak Karaf功能。 接下来,您将需要根据要保护的应用程序类型执行步骤。 所有引用的web应用程序都需要将Keycloak Jetty身份验证器注入基础Jetty服务器。 实现此目的的步骤取决于应用程序类型。 细节描述如下。

最好的起点是查看作为目录中Keycloak示例的一部分捆绑的保险丝演示保险丝。 从测试和理解演示中,大多数步骤应该是可以理解的。

安装Keycloak功能

您必须首先安装KeycloakJBoss Fuse环境中的功能。 keycloak功能包括保险丝适配器和所有第三方依赖项。 您可以从Maven存储库或从存档中安装它。

从Maven存储库安装

作为先决条件,您必须在线并有权访问Maven存储库。

对于社区来说,在线就足够了,因为所有工件和第三方依赖项都应该在maven中央存储库中可用。

要使用Maven存储库安装keycloak功能,请完成以下步骤:

  1. 启动JBoss保险丝6.3.0汇总12; 然后在Karaf端子类型中:

    功能: 添加url mvn:org.keycloak/keycloak-osgi-功能/15.0.2/xml/功能
    特点: 安装Keycloak
  2. 您可能还需要安装Jetty 9功能:

    特点: 安装keycloak-jetty9-adapter
  3. 确保已安装功能:

功能: 列表 | grepKeycloak
从ZIP包安装

如果您离线或不想使用Maven获取JAR文件和其他工件,这很有用。

要从ZIP存档中安装保险丝适配器,请完成以下步骤:

  1. 下载Keycloak保险丝适配器ZIP存档。

  2. 将其解压缩到JBoss Fuse的根目录中。 然后将依赖项安装在系统目录。 您可以覆盖所有现有的jar文件。

    将此用于JBoss保险丝6.3.0汇总12:

    cd/熔丝路径/jboss-fuse-6.3.0.redhat-254
    解压缩-q/适配器路径-zip/keycloak-fuse-adapter-15.0.2.zip
  3. 启动Fuse并在fuse/karaf端子中运行以下命令:

    功能: 添加url mvn:org.keycloak/keycloak-osgi-功能/15.0.2/xml/功能
    特点: 安装Keycloak
  4. 安装相应的码头适配器。 由于工件可直接在JBoss保险丝中获得系统目录,您不需要使用Maven存储库。

保护经典战争应用程序

保护您的战争应用程序所需的步骤是:

  1. /WEB-INF/web.xml文件,声明必要的:

    • <security-constraint> 元素中的安全约束

    • <login-config> 元素中的登录配置

    • <security-role> 元素中的安全角色。

      例如:

      <?xml version = "1.0" encoding = "UTF-8"?>
      <网络应用 xmlns=http://java.sun.com/xml/ns/javaee
               xmlns:xsi=http:// www.w3.org/2001/XMLSchema-instance
               xsi: 模式定位=http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ web-app_3_0.xsd
               版本=3.0>
      
          <模块名称>客户门户</模块名称>
      
          <欢迎文件列表>
              <欢迎文件>index.html</欢迎文件>
          </欢迎文件列表>
      
          <安全约束>
              <网络资源收集>
                  <web-资源-名称>客户</web-资源-名称>
                  <url-模式>/客户/*</url-模式>
              </网络资源收集>
              <授权约束>
                  <角色名称>用户</角色名称>
              </auth-constraint>
          </安全约束>
      
          <登录配置>
              <身份验证方法>基本</auth-方法>
              <境界-名称>没关系</领域名称>
          </登录配置>
      
          <安全-角色>
              <角色名称>管理员</角色名称>
          </安全角色>
          <安全-角色>
              <角色名称>用户</角色名称>
          </安全角色>
      </网络应用>
  2. 添加jetty-web.xml带有身份验证器的文件到/WEB-INF/jetty-web.xml文件。

    例如:

    <?xml version = "1.0"?>
    <!DOCTYPE配置公共 “-// Mort Bay咨询 // DTD配置 // EN”
     "http://www.eclipse.org/jetty/ 配置 _ 9_0.dtd">
    <配置 =组织。日蚀。码头。网络应用程序上下文>
        <Get 名称=安全处理程序>
            <设置 名称=认证器>
                <新 =org.keycloak.适配器.jetty.KeycloakJettyAuthenticator>
                </新>
            </Set>
        </Get>
    </Configure>
  3. /网络信息/你的战争的目录,创建一个新文件,keycloak.json 此配置文件的格式在Java适配器配置节。 也可以使此文件在外部可用,如配置外部适配器

  4. 确保您的战争应用程序导入组织。Keycloak。适配器。码头也许还有更多的包元信息/清单.MF文件,在导入-包装头。 使用maven-捆绑-插件在您的项目中正确生成OSGI标头在manifest中。 请注意,软件包的 “*” 分辨率不会导入组织。Keycloak。适配器。码头包,因为它不是由应用程序或蓝图或Spring描述符使用的,而是在jetty-web.xml文件。

    要导入的包列表可能如下:

    org.keycloak.adapters.jetty;version = "15.0.2",
    org.keycloak.适配器; 版本 = "15.0.2",
    org.keycloak.constants;version = "15.0.2",
    org.keycloak.util; 版本 = "15.0.2",
    组织。Keycloak。*; 版本 = "15.0.2",
    *; 分辨率: = 可选
配置外部适配器

如果你不想要Keycloak。json适配器配置文件要捆绑在WAR应用程序中,但要在外部提供并根据命名约定加载,请使用此配置方法。

要启用该功能,请将此部分添加到您的/网络信息/网络.xml文件:

<上下文参数>
    <参数名称>keycloak.config.resolver</参数名称>
    <参数值>组织。keycloak。适配器。osgi。路径基础keycloakconfigresolver</参数值>
</上下文参数>

该组件使用Keycloak。配置或者卡拉夫。等等java属性,用于搜索基本文件夹以定位配置。 然后在其中一个文件夹中搜索一个名为<你的 _ 网络 _ 上下文>-Keycloak.json

因此,例如,如果您的web应用程序具有上下文我的门户,那么您的适配器配置是从$ FUSE_HOME/etc/my-portal-keycloak.json文件。

保护作为OSGI服务部署的Servlet

您可以使用此方法,如果您的OSGI捆绑项目中有一个servlet类,该类没有部署为经典的WAR应用程序。 Fuse使用Pax Web白板扩展器将此类servlet部署为web应用程序。

要使用Keycloak保护您的servlet,请完成以下步骤:

  1. Keycloak提供PaxWebIntegrationService,它允许为您的应用程序注入jetty-web.xml和配置安全约束。 您需要在OSGI-INF/蓝图.xml文件在您的应用程序中。 请注意,您的servlet需要依赖于它。 配置示例:

    <?xml version = "1.0" encoding = "UTF-8"?>
    <蓝图 xmlns=http://www.osgi.org/xmlns/blueprint/ v1.0.0
               xmlns:xsi=http:// www.w3.org/2001/XMLSchema-instance
               xsi: 模式定位=http://www.osgi.org/xmlns/blueprint/ v1.0.0
               http://www.osgi.org/xmlns/blueprint/ v1.0.0/blueprint.xsd>
    
        <!-使用jetty bean只是为了与其他保险丝服务兼容->
        <bean id=servletConstraintMapping =组织。eclipse。码头。安全性。约束映射>
            <属性 名称=约束>
                <bean =org.eclipse.jetty.util.security.Constraint>
                    <属性 名称=名称 =cst1/>
                    <属性 名称=角色>
                        <列表>
                            <值>用户</值>
                        </list>
                    </属性>
                    <属性 名称=验证 =/>
                    <属性 名称=数据结构 =0/>
                </bean>
            </属性>
            <属性 名称=路径规范 =/产品门户/*/>
        </bean>
    
        <bean id=Keycloakpaxweb集成 =组织。Keycloak。适配器。osgi。PaxWebIntegrationService
              init-方法=开始 销毁方法=停止>
            <属性 名称=捷特网络xmllocation =/WEB-INF/jetty-web.xml />
            <属性 名称=捆绑电子文本 参考=蓝图捆绑电子文本 />
            <属性 名称=约束映射>
                <列表>
                    <ref 组件id=servletConstraintMapping />
                </list>
            </属性>
        </bean>
    
        <bean id=产品服务 =组织。Keycloak。示例。产品门户服务器 取决于=Keycloakpaxweb集成>
        </bean>
    
        <服务 参考=产品服务 接口=javax.servlet.Servlet>
            <服务属性>
                <条目 钥匙=别名 =/产品门户 />
                <条目 钥匙=servlet-名称 =产品服务 />
                <条目 钥匙=keycloak.config.file =/Keycloak.json />
            </服务属性>
        </服务>
    
    </蓝图>
    • 你可能需要网络信息项目内部的目录 (即使您的项目不是web应用程序) 并创建/WEB-INF/jetty-web.xml/网络信息/Keycloak.json文件,如经典战争应用节。 请注意,你不需要web.xml文件作为安全约束在蓝图配置文件中声明。

  2. 导入-包装元信息/清单.MF必须至少包含以下进口:

    org.keycloak.adapters.jetty;version = "15.0.2",
    org.keycloak.适配器; 版本 = "15.0.2",
    org.keycloak.constants;version = "15.0.2",
    org.keycloak.util; 版本 = "15.0.2",
    组织。Keycloak。*; 版本 = "15.0.2",
    *; 分辨率: = 可选
保护Apache Camel应用程序

您可以保护使用骆驼码头通过将securityHandler与KeycloakJettyAuthenticator和适当的安全约束注入。 您可以添加OSGI-INF/蓝图.xml使用如下类似的配置将文件提交到您的Camel应用程序。 根据您的环境和需求,角色、安全约束映射和Keycloak适配器配置可能略有不同。

例如:

<?xml version = "1.0" encoding = "UTF-8"?>

<蓝图 xmlns=http://www.osgi.org/xmlns/blueprint/ v1.0.0
           xmlns:xsi=http:// www.w3.org/2001/XMLSchema-instance
           xmlns: 骆驼=http://camel.apache.org/schema/blueprint
           xsi: 模式定位=
       http://www.osgi.org/xmlns/blueprint/ v1.0.0/blueprint.xsd
       http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/ camel-blueprint.xsd>

    <bean id=kcAdapterConfig =org.keycloak.表示.适配器.配置.AdapterConfig>
        <属性 名称=境界 =演示/>
        <属性 名称=资源 =管理-骆驼-端点/>
        <属性 名称=仅承载 =/>
        <属性 名称=authServerUrl =http:// localhost:8080/auth />
        <属性 名称=sslRequired =外部/>
    </bean>

    <bean id=keycloakAuthenticator =org.keycloak.适配器.jetty.KeycloakJettyAuthenticator>
        <属性 名称=适配器配置 参考=kcAdapterConfig/>
    </bean>

    <bean id=约束 =org.eclipse.jetty.util.security.Constraint>
        <属性 名称=名称 =客户/>
        <属性 名称=角色>
            <列表>
                <值>管理员</值>
            </list>
        </属性>
        <属性 名称=验证 =/>
        <属性 名称=数据结构 =0/>
    </bean>

    <bean id=约束映射 =组织。eclipse。码头。安全性。约束映射>
        <属性 名称=约束 参考=约束/>
        <属性 名称=路径规范 =/*/>
    </bean>

    <bean id=安全处理程序 =组织。eclipse。码头。安全。约束安全处理程序>
        <属性 名称=认证器 参考=keycloakAuthenticator />
        <属性 名称=约束映射>
            <列表>
                <ref 组件id=约束映射 />
            </list>
        </属性>
        <属性 名称=authMethod =基本/>
        <属性 名称=真实名称 =没关系/>
    </bean>

    <bean id=会话处理程序 =org.keycloak.适配器.jetty.spi.Wrapingsessionhandler>
        <属性 名称=处理程序 参考=安全处理程序 />
    </bean>

    <bean id=helloProcessor =组织。Keycloak。示例。骆驼处理器 />

    <骆驼上下文 id=蓝图上下文
                  痕迹=
                  xmlns=http://camel.apache.org/schema/blueprint>
        <路线 id=httpBridge>
            <来自 uri=jetty:http:// 0.0.0.0:8383/admin-camel-endpoint?handlers = sessionHandler& amp;匹配前缀 = 真 />
            <进程 参考=helloProcessor />
            <日志 消息=来自骆驼端点的消息包含 ${body}/>
        </路线>
    </骆驼上下文>

</蓝图>
  • 导入-包装元信息/清单.MF需要包含以下导入项:

javax.servlet;version = "[3,4)",
javax.servlet.http;version = "[3,4)",
组织。阿帕奇。骆驼。*,
org.apache.camel;version = "[2.13,3)",
org.eclipse.jetty.security;version = "[9,10)",
org.eclipse.jetty.server.nio;version = "[9,10)",
org.eclipse.jetty.util.security;version = "[9,10)",
组织。Keycloak。*; 版本 = "15.0.2",
组织。osgi。服务。蓝图,
组织。osgi。服务。蓝图。容器,
组织。osgi。服务。事件,
骆驼休息

骆驼RestDSL是骆驼功能,用于以流畅的方式定义您的休息端点。 但是您仍然必须使用特定的实现类,并提供有关如何与Keycloak集成的说明。

配置集成机制的方式取决于您为其配置RestDSL定义的路由的Camel组件。

下面的示例演示了如何使用Jetty组件配置集成,并引用了先前蓝图示例中定义的某些bean。

<bean id=安全处理程序 =组织。eclipse。码头。安全。约束安全处理程序>
    <属性 名称=认证器 参考=keycloakAuthenticator />
    <属性 名称=约束映射>
        <列表>
            <ref 组件id=约束映射 />
        </list>
    </属性>
    <属性 名称=authMethod =基本/>
    <属性 名称=真实名称 =没关系/>
</bean>

<bean id=sessionHandlerRest =org.keycloak.适配器.jetty.spi.Wrapingsessionhandler>
    <属性 名称=处理程序 参考=安全处理程序 />
</bean>


<骆驼上下文 id=蓝图上下文
              痕迹=
              xmlns=http://camel.apache.org/schema/blueprint>

    <rest配置 组件=码头 上下文路径=/restdsl
                       港口=8484>
        <!-与Keycloak安全处理程序的链接发生在这里->
        <端点属性 钥匙=处理程序 =sessionHandlerRest></endpointProperty>
        <端点属性 钥匙=匹配前缀 =></endpointProperty>
    </restConfiguration>

    <休息 路径=/你好 >
        <描述>您好休息服务</描述>
        <get uri=/{id} outType=java.lang.String>
            <描述>只是一个地狱</描述>
            <到 uri=直接: 直接 />
        

    </休息>

    <路线 id=只是直接>
        <来自 uri=直接: 直接/>
        <进程 参考=helloProcessor />
        <日志 消息=RestDSL正确调用 ${body}/>
        <setBody>
            <常量>(__ 这第二句话是从骆驼RestDSL端点 __ 返回的)</常量>
        </setBody>
    </路线>

</骆驼上下文>
在单独的码头引擎上保护Apache CXF端点

要在单独的Jetty引擎上运行由Keycloak保护的CXF端点,请完成以下步骤:

  1. 添加META-INF/spring/beans.xml对您的应用程序,并在其中声明httpj: 发动机-工厂带注射的Jetty SecurityHandlerKeycloakJettyAuthenticator。 CFX jax-ws应用程序的配置可能类似于以下配置:

    <?xml version = "1.0" encoding = "UTF-8"?>
    
    <豆 xmlns=http://www.springframework.org/schema/beans
           xmlns:xsi=http:// www.w3.org/2001/XMLSchema-instance
           xmlns:jaxws=http://cxf.apache.org/jaxws
           xmlns:httpj=http://cxf.apache.org/transports/ http-jetty/configuration
           xsi: 模式定位=
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/ spring-beans.xsd
            http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
            http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/ spring-osgi.xsd
            http://cxf.apache.org/transports/ http-jetty/configuration http://cxf.apache.org/schemas/configuration/ http-jetty.xsd>
    
        <导入 资源=类路径: 元信息/cxf.xml />
    
        <bean id=kcAdapterConfig =org.keycloak.表示.适配器.配置.AdapterConfig>
            <属性 名称=境界 =演示/>
            <属性 名称=资源 =自定义-cxf-端点/>
            <属性 名称=仅承载 =/>
            <属性 名称=authServerUrl =http:// localhost:8080/auth />
            <属性 名称=sslRequired =外部/>
        </bean>
    
        <bean id=keycloakAuthenticator =org.keycloak.适配器.jetty.KeycloakJettyAuthenticator>
            <属性 名称=适配器配置>
                <ref 本地=kcAdapterConfig />
            </属性>
        </bean>
    
        <bean id=约束 =org.eclipse.jetty.util.security.Constraint>
            <属性 名称=名称 =客户/>
            <属性 名称=角色>
                <列表>
                    <值>用户</值>
                </list>
            </属性>
            <属性 名称=验证 =/>
            <属性 名称=数据结构 =0/>
        </bean>
    
        <bean id=约束映射 =组织。eclipse。码头。安全性。约束映射>
            <属性 名称=约束 参考=约束/>
            <属性 名称=路径规范 =/*/>
        </bean>
    
        <bean id=安全处理程序 =组织。eclipse。码头。安全。约束安全处理程序>
            <属性 名称=认证器 参考=keycloakAuthenticator />
            <属性 名称=约束映射>
                <列表>
                    <ref 本地=约束映射 />
                </list>
            </属性>
            <属性 名称=authMethod =基本/>
            <属性 名称=真实名称 =没关系/>
        </bean>
    
        <httpj: 发动机-工厂 公共汽车=cxf id=Kc-cxf-终点>
            <httpj: 引擎 港口=8282>
                <httpj: 处理程序>
                    <ref 本地=安全处理程序 />
                </httpj: 处理程序>
                <httpj: 会话支持></httpj: 会话支持>
            </httpj: 引擎>
        </httpj: 发动机-工厂>
    
        <jaxws: 端点
                        实施者=组织。Keycloak。示例。ws.ProductImpl
                        地址=http:// localhost:8282/ProductServiceCF 取决于=Kc-cxf-终点 />
    
    </beans>

    对于CXF jax-rs应用程序,唯一的区别可能是端点的配置取决于引擎工厂:

    <jaxrs: 服务器 服务类别=组织。Keycloak。示例。rs。客户服务 地址=http:// localhost:8282/rest
        取决于=Kc-cxf-终点>
        <jaxrs: 提供商>
            <bean =com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider />
        </jaxrs: 提供商>
    </jaxrs: 服务器>
  2. 导入-包装元信息/清单.MF必须包含这些进口:

META-INF.cxf;version = "[2.7,3.2)",
META-INF.cxf.osgi; 版本 = "[2.7,3.2)"; 分辨率: = 可选,
org.apache.cxf.bus;version = "[2.7,3.2)",
org.apache.cxf.bus.spring;version = "[2.7,3.2)",
org.apache.cxf.bus.resource;version = "[2.7,3.2)",
org.apache.cxf.transport.http;version = "[2.7,3.2)",
org.apache.cxf.*;version = "[2.7,3.2)",
org.springframework.beans.factory.config,
org.eclipse.jetty.security;version = "[9,10)",
org.eclipse.jetty.util.security;version = "[9,10)",
组织。Keycloak。*; 版本 = "15.0.2"
在默认Jetty引擎上保护Apache CXF端点

一些服务在启动时会自动附带部署的servlet。 一种这样的服务是在http:// localhost:8181/CXF上下文中运行的cxf servlet。 保护这样的端点可能很复杂。 Keycloak当前正在使用的一种方法是ServletReregistrationService,它在启动时取消部署内置的servlet,使您能够在Keycloak保护的上下文中重新部署它。

配置文件OSGI-INF/蓝图.xml在你的应用程序可能类似于下面的。 请注意,它增加了jax-rs客户服务端点,它是特定于您的应用程序的端点,但更重要的是,保护整个/cxf上下文。

<?xml version = "1.0" encoding = "UTF-8"?>
<蓝图 xmlns=http://www.osgi.org/xmlns/blueprint/ v1.0.0
           xmlns:xsi=http:// www.w3.org/2001/XMLSchema-instance
           xmlns:jaxrs=http://cxf.apache.org/blueprint/jaxrs
           xsi: 模式定位=
                http://www.osgi.org/xmlns/blueprint/ v1.0.0/blueprint.xsd
                http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd>

    <!-- JAXRS应用 -->

    <bean id=客户豆 =组织。Keycloak。示例。rs.CxfCustomerService />

    <jaxrs: 服务器 id=cxfJaxrsServer 地址=/客户服务>
        <jaxrs: 提供商>
            <bean =com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider />
        </jaxrs: 提供商>
        <jaxrs: 服务豆>
            <ref 组件id=客户豆 />
        </jaxrs: 服务豆>
    </jaxrs: 服务器>


    <!-通过从paxweb取消注册默认cxf servlet并使用应用的安全约束重新注册来保护整个/cxf上下文->

    <bean id=Cxfconstraint映射 =组织。eclipse。码头。安全性。约束映射>
        <属性 名称=约束>
            <bean =org.eclipse.jetty.util.security.Constraint>
                <属性 名称=名称 =cst1/>
                <属性 名称=角色>
                    <列表>
                        <值>用户</值>
                    </list>
                </属性>
                <属性 名称=验证 =/>
                <属性 名称=数据结构 =0/>
            </bean>
        </属性>
        <属性 名称=路径规范 =/cxf/*/>
    </bean>

    <bean id=Cxfkeycloakpaxweb集成 =组织。Keycloak。适配器。osgi。PaxWebIntegrationService
          init-方法=开始 销毁方法=停止>
        <属性 名称=捆绑电子文本 参考=蓝图捆绑电子文本 />
        <属性 名称=捷特网络xmllocation =/WEB-INF/jetty-web.xml />
        <属性 名称=约束映射>
            <列表>
                <ref 组件id=Cxfconstraint映射 />
            </list>
        </属性>
    </bean>

    <bean id=默认注册 =组织。密钥斗篷。适配器。osgi。服务管理器 取决于=Cxfkeycloakpaxweb集成
          init-方法=开始 销毁方法=停止>
        <属性 名称=捆绑电子文本 参考=蓝图捆绑电子文本 />
        <属性 名称=管理服务参考>
            <参考 接口=组织。osgi。服务。管理服务 过滤器=(服务.pid = org.apache.cxf.osgi) 超时=5000  />
        </属性>
    </bean>

</蓝图>

因此,在默认CXF HTTP目标上运行的所有其他CXF服务也得到了保护。 同样,当应用程序被取消部署时,整个/cxf上下文也变得不安全。 因此,如以下所述,为您的应用程序使用您自己的Jetty引擎独立码头引擎上的安全CXF应用那就给你更多 对每个单独应用程序的安全性进行控制。

  • 网络信息目录可能需要在您的项目内部 (即使您的项目不是web应用程序)。 您可能还需要编辑/WEB-INF/jetty-web.xml/网络信息/Keycloak.json文件的方式与中类似经典战争应用。 请注意,您不需要web.xml文件作为安全约束在蓝图配置文件中声明。

  • 导入-包装元信息/清单.MF必须包含以下导入项:

META-INF.cxf;version = "[2.7,3.2)",
META-INF.cxf.osgi; 版本 = "[2.7,3.2)"; 分辨率: = 可选,
org.apache.cxf.transport.http;version = "[2.7,3.2)",
org.apache.cxf.*;version = "[2.7,3.2)",
com.fasterxml.jackson.jaxrs.json;version = "[2.5,3)",
org.eclipse.jetty.security;version = "[9,10)",
org.eclipse.jetty.util.security;version = "[9,10)",
组织。Keycloak。*; 版本 = "15.0.2",
org.keycloak.adapters.jetty;version = "15.0.2",
*; 分辨率: = 可选
保护保险丝管理服务
使用SSH认证熔断终端

Keycloak主要解决web应用程序身份验证的用例; 但是,如果您的其他web服务和应用程序受到保护 使用Keycloak,使用Keycloak凭据保护非web管理服务 (例如SSH) 是最好的做法。 您可以使用JAAS登录模块执行此操作,该模块允许远程连接到Keycloak,并基于以下内容验证凭据 资源所有者密码凭据

要启用SSH身份验证,请完成以下步骤:

  1. 在Keycloak中创建一个客户端 (例如,ssh-jmx-管理员-客户端),将用于SSH身份验证。 这个客户需要有启用直接访问授权选择到

  2. $ FUSE_HOME/etc/org.apache.karaf.shell.cfg文件,更新或指定此属性:

    sshRealm = Keycloak
  3. 添加$ FUSE_HOME/etc/keycloak-direct-access.json具有类似于以下内容的文件 (基于您的环境和Keycloak客户端设置):

    {
        境界:演示,
        资源:ssh-jmx-管理员-客户端,
        ssl-必需:外部,
        身份验证-服务器-网址:http:// localhost:8080/auth,
        凭据: {
            秘密:密码
        }
    }

    此文件指定客户端应用程序配置,该配置由JAAS DirectAccessGrantsLoginModule从Keycloak用于SSH身份验证的JAAS领域。

  4. 启动保险丝并安装Keycloak贾伊斯王国。 最简单的方法是安装Keycloak-jaas功能,它具有预定义的JAAS领域。 您可以使用自己的功能覆盖功能的预定义领域Keycloak排名较高的JAAS领域。 有关详细信息,请参见JBoss保险丝文档

    在保险丝端子中使用以下命令:

    功能: 添加url mvn:org.keycloak/keycloak-osgi-功能/15.0.2/xml/功能
    特点: 安装keycloak-jaas
  5. 使用SSH作为管理员用户通过在终端中键入以下内容:

    ssh -o PubkeyAuthentication = no -p 8101 admin @ localhost
  6. 用密码登录密码

在以后的某些操作系统上,您可能还需要使用SSH命令的-o选项-o主机键算法 = + ssh-dss因为以后的SSH客户端不允许使用ssh-dss算法,默认情况下。 但是,默认情况下,它当前在JBoss Fuse 6.3.0 Rollup 12中使用。

请注意,用户需要具有领域角色管理员执行所有操作或执行操作子集的另一个角色 (例如,查看器限制用户只能运行只读Karaf命令的角色)。 可用角色配置在$ FUSE_HOME/etc/org.apache.karaf.shell.cfg或者$ FUSE_HOME/etc/system.properties

使用JMX身份验证

如果要使用jconsole或其他外部工具通过RMI远程连接到JMX,则可能需要JMX身份验证。 否则,使用hawt.io/jolokia可能会更好,因为默认情况下,jolokia代理安装在hawt.io中。 有关更多详细信息,请参见Hawtio管理控制台

要使用JMX身份验证,请完成以下步骤:

  1. $ FUSE_HOME/etc/org.apache.karaf.management.cfg文件,将jmxRealm属性更改为:

    jmxRealm = Keycloak
  2. 安装Keycloak-jaas功能和配置$ FUSE_HOME/etc/keycloak-direct-access.json文件,如上面的SSH部分所述。

  3. 在jconsole中,您可以使用一个URL,如:

服务: jmx:rmi:// 本地主机: 44444/jndi/rmi:// 本地主机: 1099/karaf-根

和凭据: admin/password (根据您的环境,基于具有admin权限的用户)。

保护Hawtio管理控制台

要使用Keycloak保护Hawtio管理控制台,请完成以下步骤:

  1. 将这些属性添加到$ FUSE_HOME/etc/system.properties文件:

    hawtio.keycloakEnabled = true
    hawtio.领域 = Keycloak
    hawtio.keycloakClientConfig = 文件: // ${karaf.base}/etc/keycloak-hawtio-client.json
    hawtio.rolePrincipalClasses = org.keycloak.适配器.jaas.RolePrincipal,org.apache.karaf.jaas.boot.principal.RolePrincipal
  2. 在您的领域的Keycloak管理控制台中创建一个客户端。 例如,在Keycloak中演示境界,创建客户端hawtio-客户,指定公众作为访问类型,并指定指向Hawtio的重定向URI: http:// localhost:8181/hawtio/*。 您还必须配置相应的Web源 (在本例中为http:// localhost:8181)。

  3. 创建keycloak-hawtio-client.json文件中的$ FUSE_HOME/etc目录使用类似于下面示例中显示的内容。 更改境界,资源,以及身份验证-服务器-网址属性根据您的Keycloak环境。 的资源属性必须指向上一步中创建的客户端。 此文件由客户端 (Hawtio JavaScript应用程序) 端使用。

    {
      境界:演示,
      资源:hawtio-客户,
      身份验证-服务器-网址:http:// localhost:8080/auth,
      ssl-必需:外部,
      公共客户:
    }
  4. 创建keycloak-hawtio.json文件中的$ FUSE_HOME/etc二分使用类似于下面示例中显示的内容。 更改境界身份验证-服务器-网址属性根据您的Keycloak环境。 此文件由服务器 (JAAS登录模块) 端的适配器使用。

    {
      境界:演示,
      资源:jaas,
      仅限不记名:,
      身份验证-服务器-网址:http:// localhost:8080/auth,
      ssl-必需:外部,
      使用资源角色映射:,
      主体属性:首选用户名
    }
  5. 启动JBoss Fuse 6.3.0汇总12并安装keycloak功能 (如果尚未安装)。 Karaf terminal中的命令类似于这个例子:

    功能: 添加url mvn:org.keycloak/keycloak-osgi-功能/15.0.2/xml/功能
    特点: 安装Keycloak
  6. http:// localhost:8181/hawtio并以用户身份从您的Keycloak领域登录。

    请注意,用户需要具有适当的领域角色才能成功地向Hawtio进行身份验证。 可用角色配置在$ FUSE_HOME/etc/system.properties文件在霍蒂奥。角色

在JBoss EAP 6.4上保护Hawtio

要在JBoss EAP 6.4服务器上运行Hawtio,请完成以下步骤:

  1. 如上一节所述设置Keycloak,保护Hawtio管理控制台。 假设:

    • 你有一个关键的斗篷领域演示和客户hawtio-客户

    • 你的Keycloak正在跑本地主机: 8080

    • 已部署Hawtio的JBoss EAP 6.4服务器将在本地主机: 8181。 此服务器的目录在接下来的步骤中称为$ EAP_HOME

  2. 复制hawtio-wildfly-1.4.0.redhat-630396.war存档到$ EAP_HOME/独立/配置目录。 有关部署Hawtio的更多详细信息,请参见保险丝Hawtio文档

  3. 复制keycloak-hawtio.jsonkeycloak-hawtio-client.json包含上述内容的文件$ EAP_HOME/独立/配置目录。

  4. 将Keycloak适配器子系统安装到JBoss EAP 6.4服务器,如JBoss适配器文档

  5. $ EAP_HOME/独立/配置/独立.xml文件配置系统属性,如下例所示:

    <扩展>
    ...
    </扩展>
    
    <系统属性>
        <属性 名称=hawtio。认证启用 = />
        <属性 名称=哈蒂奥。王国 =霍蒂奥 />
        <属性 名称=霍蒂奥。角色 =管理员,查看器 />
        <属性 名称=hawtio.Roleprincipalclass =组织。Keycloak。适配器。jaas。角色负责人 />
        <属性 名称=hawtio.keycloakEnabled = />
        <属性 名称=hawtio.keycloakClientConfig =${jboss.server.config.dir}/keycloak-hawtio-client.json />
        <属性 名称=hawtio.keycloakServerConfig =${jboss.server.config.dir}/keycloak-hawtio.json />
    </系统属性>
  6. 将Hawtio领域添加到安全域节:

    <安全域 名称=霍蒂奥 缓存类型=默认>
        <身份验证>
            <登录模块 代码=组织。Keycloak。适配器。jaas。BearerTokenLoginModule 旗帜=必需>
                <模块-选项 名称=keycloak-config-file =${hawtio.keycloakServerConfig}/>
            </登录模块>
        </身份验证>
    </安全域>
  7. 添加安全部署霍蒂奥到适配器子系统。 这确保了Hawtio战争能够找到JAAS登录模块类。

    <子系统 xmlns=urn:jboss: 域: keycloak:1.1>
        <安全部署 名称=hawtio-wildfly-1.4.0.redhat-630396.war />
    </子系统>
  8. 使用Hawtio重新启动JBoss EAP 6.4服务器:

    cd $ EAP_HOME/bin
    。/standalone.sh -Djboss.socket.binding.port-offset = 101
  9. 在以下位置访问Hawtiohttp:// localhost:8181/hawtio。 它由Keycloak保护。

2.1.5。JBoss保险丝7适配器

Keycloak支持保护内部运行的web应用程序JBoss保险丝7

JBoss保险丝7利用Undertow适配器,基本上与 EAP 7 / WildFly适配器 由于JBoss Fuse 7.4.0与Undertow HTTP引擎捆绑在一起,Undertow用于运行各种web应用程序。

Fuse 7唯一受支持的版本是最新版本。 如果您使用较早版本的Fuse 7,则有可能某些功能无法正常工作。 特别是,对于低于7.0.1的Fuse 7版本,集成根本不起作用。

Fuse支持以下项目的安全性:

  • 用Pax网络战争扩展器部署在保险丝上的经典战争应用程序

  • 在保险丝上部署的servlet作为带有Pax Web白板扩展器的OSGI服务,以及通过以下方式注册的servlet org.osgi.service.http.HttpService # registerServlet() 这是标准的OSGi企业HTTP服务

  • 阿帕奇骆驼Undertow端点运行骆驼底拖组件

  • 阿帕奇CXF在自己单独的Undertow引擎上运行的端点

  • 阿帕奇CXF在CXF servlet提供的默认引擎上运行的端点

  • SSH和JMX管理员访问

  • Hawtio管理控制台

在Fuse 7中保护您的Web应用程序

您必须首先安装Keycloak Karaf功能。 接下来,您将需要根据要保护的应用程序类型执行步骤。 所有引用的web应用程序都需要将Keycloak Undertow身份验证机制注入基础web服务器。 实现此目的的步骤取决于应用程序类型。 细节描述如下。

最好的起点是查看作为目录中Keycloak示例的一部分捆绑的保险丝演示保险丝。 从测试和理解演示中,大多数步骤应该是可以理解的。

安装Keycloak功能

您必须首先安装Keycloak-pax-http-undertowKeycloak-jaasJBoss Fuse环境中的功能。 的Keycloak-pax-http-undertow功能包括保险丝适配器和所有第三方依赖项。 的Keycloak-jaas包含领域中用于SSH和JMX身份验证的JAAS模块。 您可以从Maven存储库或从存档中安装它。

从Maven存储库安装

作为先决条件,您必须在线并有权访问Maven存储库。

对于社区来说,在线就足够了,因为所有工件和第三方依赖项都应该在maven中央存储库中可用。

要使用Maven存储库安装keycloak功能,请完成以下步骤:

  1. 启动JBoss保险丝7.4.0; 然后在Karaf终端类型中:

    功能: 回购-添加mvn:org.keycloak/keycloak-osgi-功能/15.0.2/xml/功能
    功能: 安装Keycloak-pax-http-undertowKeycloak-jaas
  2. 您可能还需要安装Undertow功能:

    功能: 安装pax-http-undertow
  3. 确保已安装功能:

功能: 列表 | grepKeycloak
从ZIP包安装

如果您离线或不想使用Maven获取JAR文件和其他工件,这很有用。

要从ZIP存档中安装保险丝适配器,请完成以下步骤:

  1. 下载Keycloak保险丝适配器ZIP存档。

  2. 将其解压缩到JBoss Fuse的根目录中。 然后将依赖项安装在系统目录。 您可以覆盖所有现有的jar文件。

    将此用于JBoss保险丝7.4.0:

    cd/熔丝路径/fuse-karaf-7.z
    解压缩-q/适配器路径-zip/keycloak-fuse-adapter-15.0.2.zip
  3. 启动Fuse并在fuse/karaf端子中运行以下命令:

    功能: 回购-添加mvn:org.keycloak/keycloak-osgi-功能/15.0.2/xml/功能
    功能: 安装Keycloak-pax-http-undertowKeycloak-jaas
  4. 安装相应的下拖适配器。 由于工件可直接在JBoss保险丝中获得系统目录,您不需要使用Maven存储库。

保护经典战争应用程序

保护您的战争应用程序所需的步骤是:

  1. /WEB-INF/web.xml文件,声明必要的:

    • <security-constraint> 元素中的安全约束

    • <login-config> 元素中的登录配置。 确保<身份验证方法>Keycloak

    • <security-role> 元素中的安全角色

      例如:

      <?xml version = "1.0" encoding = "UTF-8"?>
      <网络应用 xmlns=http://java.sun.com/xml/ns/javaee
               xmlns:xsi=http:// www.w3.org/2001/XMLSchema-instance
               xsi: 模式定位=http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ web-app_3_0.xsd
               版本=3.0>
      
          <模块名称>客户门户</模块名称>
      
          <欢迎文件列表>
              <欢迎文件>index.html</欢迎文件>
          </欢迎文件列表>
      
          <安全约束>
              <网络资源收集>
                  <web-资源-名称>客户</web-资源-名称>
                  <url-模式>/客户/*</url-模式>
              </网络资源收集>
              <授权约束>
                  <角色名称>用户</角色名称>
              </auth-constraint>
          </安全约束>
      
          <登录配置>
              <身份验证方法>Keycloak</auth-方法>
              <境界-名称>没关系</领域名称>
          </登录配置>
      
          <安全-角色>
              <角色名称>管理员</角色名称>
          </安全角色>
          <安全-角色>
              <角色名称>用户</角色名称>
          </安全角色>
      </网络应用>
  2. /网络信息/你的战争的目录,创建一个新文件,keycloak.json 此配置文件的格式在Java适配器配置节。 也可以使此文件在外部可用,如配置外部适配器

    例如:

    {
        境界:演示,
        资源:客户门户,
        身份验证-服务器-网址:http:// localhost:8080/auth,
        ssl-必需:外部,
        凭据: {
            秘密:密码
        }
    }
  3. 与保险丝6适配器相反,MANIFEST.MF中没有需要的特殊OSGi进口。

配置解析器

Keycloak。json适配器配置文件可以存储在捆绑包中, 这是默认行为,或者在文件系统的目录中。 要指定 配置文件的实际来源,设置keycloak.config.resolver部署参数到所需的配置解析器类。 例如,在经典的WAR应用程序中,设置keycloak.config.resolver中的上下文参数web.xml像这样的文件:

<上下文参数>
    <参数名称>keycloak.config.resolver</参数名称>
    <参数值>组织。keycloak。适配器。osgi。路径基础keycloakconfigresolver</参数值>
</上下文参数>

以下解析器可用于keycloak.config.resolver:

org.keycloak.适配器.osgi.BundleBasedKeycloakConfigResolver

这是默认的解析器。 配置文件在里面 正在保护的OSGi捆绑包。 默认情况下,它加载名为网络信息/Keycloak.json但是这个文件名可以通过配置位置财产。

组织。keycloak。适配器。osgi。路径基础keycloakconfigresolver

此解析器搜索名为<你的 _ 网络 _ 上下文>-Keycloak.json在文件夹内 由Keycloak。配置系统属性。 如果Keycloak。配置是 没有设置,卡拉夫。等等改为使用系统属性。

例如,如果您的web应用程序部署到上下文中我的门户,那么 您的适配器配置将从 ${keycloak.config}/my-portal-keycloak.json文件,或来自${karaf.etc}/my-portal-keycloak.json

org.keycloak.适配器.osgi.HierarchicalPathBasedKeycloakConfigResolver

该解析器类似于路径基础keycloakconfigresolver上面,哪里 对于给定的URI路径,从大多数到最不具体地检查配置位置。

例如,对于/我的/网络应用/上下文URI,搜索以下配置位置存在,直到第一个存在:

  • ${karaf.etc}/my-web-app-context-keycloak.json

  • ${karaf.etc}/my-web-app-keycloak.json

  • ${karaf.etc}/my-keycloak.json

  • ${karaf.etc}/keycloak.json

保护作为OSGI服务部署的Servlet

您可以使用此方法,如果您的OSGI捆绑项目中有一个servlet类,该类没有部署为经典的WAR应用程序。 Fuse使用Pax Web白板扩展器将此类servlet部署为web应用程序。

要使用Keycloak保护您的servlet,请完成以下步骤:

  1. Keycloak提供org.keycloak.适配器.osgi.undertow.PaxWebIntegrationService,它允许为您的应用程序配置身份验证方法和安全约束。 您需要在OSGI-INF/蓝图.xml文件在您的应用程序中。 请注意,您的servlet需要依赖于它。 配置示例:

    <?xml version = "1.0" encoding = "UTF-8"?>
    <蓝图 xmlns=http://www.osgi.org/xmlns/blueprint/ v1.0.0
               xmlns:xsi=http:// www.w3.org/2001/XMLSchema-instance
               xsi: 模式定位=http://www.osgi.org/xmlns/blueprint/ v1.0.0/blueprint.xsd>
    
        <bean id=servletConstraintMapping =组织。Keycloak。适配器。osgi。PaxWebSecurityConstraintMapping>
            <属性 名称=角色>
                <列表>
                    <值>用户</值>
                </list>
            </属性>
            <属性 名称=身份验证 =/>
            <属性 名称=url =/产品门户/*/>
        </bean>
    
        <!-此处理集成并设置login-config和security-constraints参数->
        <bean id=Keycloakpaxweb集成 =org.keycloak.适配器.osgi.undertow.PaxWebIntegrationService
              init-方法=开始 销毁方法=停止>
            <属性 名称=捆绑电子文本 参考=蓝图捆绑电子文本 />
            <属性 名称=约束映射>
                <列表>
                    <ref 组件id=servletConstraintMapping />
                </list>
            </属性>
        </bean>
    
        <bean id=产品服务 =组织。Keycloak。示例。产品门户服务器 取决于=Keycloakpaxweb集成 />
    
        <服务 参考=产品服务 接口=javax.servlet.Servlet>
            <服务属性>
                <条目 钥匙=别名 =/产品门户 />
                <条目 钥匙=servlet-名称 =产品服务 />
                <条目 钥匙=keycloak.config.file =/Keycloak.json />
            </服务属性>
        </服务>
    </蓝图>
    • 你可能需要网络信息项目内部的目录 (即使您的项目不是web应用程序) 并创建/网络信息/Keycloak.json文件,如经典战争应用节。 请注意,你不需要web.xml文件作为安全约束在蓝图配置文件中声明。

  2. 与保险丝6适配器相反,MANIFEST.MF中没有需要的特殊OSGi进口。

保护Apache Camel应用程序

您可以保护使用骆驼-下拖通过通过蓝图注入适当的安全约束并将使用的组件更新为undertow-keycloak。 你必须添加OSGI-INF/蓝图.xml使用如下类似的配置将文件提交到您的Camel应用程序。 角色、安全约束映射和适配器配置可能会略有不同,具体取决于您的环境和需求。

与标准相比undertow组件,undertow-keycloak组件添加了两个新属性:

  • 配置解析器是提供Keycloak适配器的解析器bean 配置。 可用解析器列于配置解析器节。

  • 允许的角色是一个逗号分隔的角色列表。 访问服务的用户必须至少具有一个角色才能允许访问。

例如:

<?xml version = "1.0" encoding = "UTF-8"?>
<蓝图 xmlns=http://www.osgi.org/xmlns/blueprint/ v1.0.0
           xmlns:xsi=http:// www.w3.org/2001/XMLSchema-instance
           xmlns: 骆驼=http://camel.apache.org/schema/blueprint
           xsi: 模式定位=
       http://www.osgi.org/xmlns/blueprint/ v1.0.0/blueprint.xsd
       http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/ camel-blueprint-2.17.1.xsd>

    <bean id=keycloakConfigResolver =org.keycloak.适配器.osgi.BundleBasedKeycloakConfigResolver >
        <属性 名称=捆绑电子文本 参考=蓝图捆绑电子文本 />
    </bean>

    <bean id=helloProcessor =组织。Keycloak。示例。骆驼处理器 />

    <骆驼上下文 id=蓝图上下文
                  痕迹=
                  xmlns=http://camel.apache.org/schema/blueprint>

        <路线 id=httpBridge>
            <来自 uri=undertow-keycloak:http:// 0.0.0.0:8383/admin-camel-endpoint?matchOnUriPrefix = true& amp;configResolver = # keycloakConfigResolver& amp;允许角色 = 管理员 />
            <进程 参考=helloProcessor />
            <日志 消息=来自骆驼端点的消息包含 ${body}/>
        </路线>

    </骆驼上下文>

</蓝图>
  • 导入-包装元信息/清单.MF需要包含以下导入项:

javax.servlet;version = "[3,4)",
javax.servlet.http;version = "[3,4)",
javax.net.ssl,
组织。阿帕奇。骆驼。*,
org.apache.camel;version = "[2.13,3)",
io.undertow.*,
组织。Keycloak。*; 版本 = "15.0.2",
组织。osgi。服务。蓝图,
组织。osgi。服务。蓝图。容器
骆驼休息

骆驼RestDSL是骆驼功能,用于以流畅的方式定义您的休息端点。 但是您仍然必须使用特定的实现类,并提供有关如何与Keycloak集成的说明。

配置集成机制的方式取决于您为其配置RestDSL定义的路由的Camel组件。

下面的示例演示如何使用undertow-keycloak组件,并引用先前蓝图示例中定义的某些bean。

<骆驼上下文 id=蓝图上下文
              痕迹=
              xmlns=http://camel.apache.org/schema/blueprint>

    <!-与Keycloak安全处理程序的链接是通过使用undertow-keycloak组件发生的->
    <rest配置 Apiconpent=undertow-keycloak 上下文路径=/restdsl 港口=8484>
        <端点属性 钥匙=配置解析器 =# keycloakConfigResolver />
        <端点属性 钥匙=允许的角色 =管理员,超级管理员 />
    </restConfiguration>

    <休息 路径=/你好 >
        <描述>您好休息服务</描述>
        <get uri=/{id} outType=java.lang.String>
            <描述>只是一个你好</描述>
            <到 uri=直接: 直接 />
        

    </休息>

    <路线 id=只是直接>
        <来自 uri=直接: 直接/>
        <进程 参考=helloProcessor />
        <日志 消息=RestDSL正确调用 ${body}/>
        <setBody>
            <常量>(__ 这第二句话是从骆驼RestDSL端点 __ 返回的)</常量>
        </setBody>
    </路线>

</骆驼上下文>
在单独的Undertow引擎上保护Apache CXF端点

要在单独的Undertow引擎上运行由Keycloak保护的CXF端点,请完成以下步骤:

  1. 添加OSGI-INF/蓝图.xml到您的应用程序中,并在其中添加适当的配置解析器bean,类似于骆驼配置。 在httpu: 发动机-工厂声明org.keycloak.适配器.osgi.undertow.CxfKeycloakAuthHandler使用该骆驼配置的处理程序。 CFX jax-ws应用程序的配置可能类似于以下配置:

    <?xml version = "1.0" encoding = "UTF-8"?>
    <蓝图 xmlns=http://www.osgi.org/xmlns/blueprint/ v1.0.0
               xmlns:xsi=http:// www.w3.org/2001/XMLSchema-instance
               xmlns:jaxws=http://cxf.apache.org/blueprint/jaxws
               xmlns:cxf=http://cxf.apache.org/blueprint/core
               xmlns:httpu=http://cxf.apache.org/transports/ http-undertow/configuration
               xsi: 模式定位=
          http://cxf.apache.org/transports/ http-undertow/配置http://cxf.apache.org/schemas/configuration/ http-undertow.xsd
          http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd
          http://cxf.apache.org/blueprint/jaxws http://cxf.apache.org/schemas/blueprint/jaxws.xsd>
    
        <bean id=keycloakConfigResolver =org.keycloak.适配器.osgi.BundleBasedKeycloakConfigResolver >
            <属性 名称=捆绑电子文本 参考=蓝图捆绑电子文本 />
        </bean>
    
        <httpu: 发动机-工厂 公共汽车=cxf id=Kc-cxf-终点>
            <httpu: 引擎 港口=8282>
                <httpu: 处理程序>
                    <bean =org.keycloak.适配器.osgi.undertow.CxfKeycloakAuthHandler>
                        <属性 名称=配置解析器 参考=keycloakConfigResolver />
                    </bean>
                </httpu: 处理程序>
            </httpu: 引擎>
        </httpu: 发动机-工厂>
    
        <jaxws: 端点 实施者=组织。Keycloak。示例。ws.ProductImpl
                        地址=http:// localhost:8282/ProductServiceCF 取决于=Kc-cxf-终点/>
    
    </蓝图>

    对于CXF jax-rs应用程序,唯一的区别可能是端点的配置取决于引擎工厂:

    <jaxrs: 服务器 服务类别=组织。Keycloak。示例。rs。客户服务 地址=http:// localhost:8282/rest
        取决于=Kc-cxf-终点>
        <jaxrs: 提供商>
            <bean =com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider />
        </jaxrs: 提供商>
    </jaxrs: 服务器>
  2. 导入-包装元信息/清单.MF必须包含这些进口:

META-INF.cxf;version = "[2.7,3.3)",
META-INF.cxf.osgi; 版本 = "[2.7,3.3)"; 分辨率: = 可选,
org.apache.cxf.bus;version = "[2.7,3.3)",
org.apache.cxf.bus.spring;version = "[2.7,3.3)",
org.apache.cxf.bus.resource;version = "[2.7,3.3)",
org.apache.cxf.transport.http;version = "[2.7,3.3)",
org.apache.cxf.*;version = "[2.7,3.3)",
org.springframework.beans.factory.config,
组织。Keycloak。*; 版本 = "15.0.2"
在默认Undertow引擎上保护Apache CXF端点

一些服务在启动时会自动附带部署的servlet。 一种这样的服务是在http:// localhost:8181/CXF上下文中运行的cxf servlet。 Fuse的Pax Web支持通过配置管理员更改现有上下文。 这可用于通过Keycloak保护端点。

配置文件OSGI-INF/蓝图.xml在你的应用程序可能类似于下面的。 请注意,它增加了jax-rs客户服务endpoint,它是特定于您的应用程序的endpoint。

<?xml version = "1.0" encoding = "UTF-8"?>
<蓝图 xmlns=http://www.osgi.org/xmlns/blueprint/ v1.0.0
           xmlns:xsi=http:// www.w3.org/2001/XMLSchema-instance
           xmlns:jaxrs=http://cxf.apache.org/blueprint/jaxrs
           xsi: 模式定位=
                http://www.osgi.org/xmlns/blueprint/ v1.0.0/blueprint.xsd
                http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd>

    <!-- JAXRS应用 -->
    <bean id=客户豆 =组织。Keycloak。示例。rs.CxfCustomerService />

    <jaxrs: 服务器 id=cxfJaxrsServer 地址=/客户服务>
        <jaxrs: 提供商>
            <bean =com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider />
        </jaxrs: 提供商>
        <jaxrs: 服务豆>
            <ref 组件id=客户豆 />
        </jaxrs: 服务豆>
    </jaxrs: 服务器>
</蓝图>

此外,你必须创建${karaf.etc}/org.ops4j.pax.web.context-任何名称。cfg文件。 它将被视为工厂PID配置,由pax-web-运行时捆绑包。 这样的配置可能包含与标准的某些属性相对应的以下属性web.xml:

捆绑包。符号名称 = 组织。阿帕奇。cxf-rt-transports-http
上下文。id = 默认值

上下文。参数。keycloak.config.resolver = org。keycloak.adapters.osgi.Hierarchicalpathedkeycloakconfigresolver

登录。配置。授权方法 = 密钥斗篷

安全.cxf.url = /cxf/客户服务/*
安全.cxf.角色 = 管理员,用户

有关配置管理文件中可用属性的完整说明,请参阅Fuse文档。 上面的属性具有以下含义:

捆绑包。符号名称上下文。id

标识捆绑包及其内的部署上下文组织。ops4j.pax.web.service.WebContainer

上下文。参数。密钥斗篷。配置。解析器

提供的价值keycloak.config.resolver捆绑包的上下文参数与中相同web.xml经典战争。 可用的解析器描述在配置解析器节。

登录。配置。授权方法

身份验证方法。 一定是Keycloak

安全。任何名称。url安全。任何名称。角色

单个安全约束的属性值,就像它们将在安全约束/网络资源收集/网址模式安全约束/身份验证约束/角色名称web.xml,分别。 角色周围用逗号和空格分隔。 的任何名称标识符可以是任意的,但必须与相同安全约束的各个属性匹配。

某些Fuse版本包含一个错误,该错误要求角色由“,”(逗号和单个空格)。 确保精确地使用此符号来分离角色。

导入-包装元信息/清单.MF必须至少包含以下进口:

javax.ws.rs;version = "[2,3)",
META-INF.cxf;version = "[2.7,3.3)",
META-INF.cxf.osgi; 版本 = "[2.7,3.3)"; 分辨率: = 可选,
org.apache.cxf.transport.http;version = "[2.7,3.3)",
org.apache.cxf.*;version = "[2.7,3.3)",
com.fasterxml.jackson.jaxrs.json;version = "${jackson.version}"
保护保险丝管理服务
使用SSH认证熔断终端

Keycloak主要解决web应用程序身份验证的用例; 但是,如果您的其他web服务和应用程序受到保护 使用Keycloak,使用Keycloak凭据保护非web管理服务 (例如SSH) 是最好的做法。 您可以使用JAAS登录模块执行此操作,该模块允许远程连接到Keycloak,并基于以下内容验证凭据 资源所有者密码凭据

要启用SSH身份验证,请完成以下步骤:

  1. 在Keycloak中创建一个客户端 (例如,ssh-jmx-管理员-客户端),将用于SSH身份验证。 这个客户需要有启用直接访问授权选择到

  2. $ FUSE_HOME/etc/org.apache.karaf.shell.cfg文件,更新或指定此属性:

    sshRealm = Keycloak
  3. 添加$ FUSE_HOME/etc/keycloak-direct-access.json具有类似于以下内容的文件 (基于您的环境和Keycloak客户端设置):

    {
        境界:演示,
        资源:ssh-jmx-管理员-客户端,
        ssl-必需:外部,
        身份验证-服务器-网址:http:// localhost:8080/auth,
        凭据: {
            秘密:密码
        }
    }

    此文件指定客户端应用程序配置,该配置由JAAS DirectAccessGrantsLoginModule从Keycloak用于SSH身份验证的JAAS领域。

  4. 启动保险丝并安装Keycloak贾伊斯王国。 最简单的方法是安装Keycloak-jaas功能,它具有预定义的JAAS领域。 您可以使用自己的功能覆盖功能的预定义领域Keycloak排名较高的JAAS领域。 有关详细信息,请参见JBoss保险丝文档

    在保险丝端子中使用以下命令:

    功能: 添加url mvn:org.keycloak/keycloak-osgi-功能/15.0.2/xml/功能
    特点: 安装keycloak-jaas
  5. 使用SSH作为管理员用户通过在终端中键入以下内容:

    ssh -o PubkeyAuthentication = no -p 8101 admin @ localhost
  6. 用密码登录密码

在以后的某些操作系统上,您可能还需要使用SSH命令的-o选项-o主机键算法 = + ssh-dss因为以后的SSH客户端不允许使用ssh-dss算法,默认情况下。 但是,默认情况下,它当前在JBoss Fuse 7.4.0中使用。

请注意,用户需要具有领域角色管理员执行所有操作或执行操作子集的另一个角色 (例如,查看器限制用户只能运行只读Karaf命令的角色)。 可用角色配置在$ FUSE_HOME/etc/org.apache.karaf.shell.cfg或者$ FUSE_HOME/etc/system.properties

使用JMX身份验证

如果要使用jconsole或其他外部工具通过RMI远程连接到JMX,则可能需要JMX身份验证。 否则,使用hawt.io/jolokia可能会更好,因为默认情况下,jolokia代理安装在hawt.io中。 有关更多详细信息,请参见Hawtio管理控制台

要使用JMX身份验证,请完成以下步骤:

  1. $ FUSE_HOME/etc/org.apache.karaf.management.cfg文件,将jmxRealm属性更改为:

    jmxRealm = Keycloak
  2. 安装Keycloak-jaas功能和配置$ FUSE_HOME/etc/keycloak-direct-access.json文件,如上面的SSH部分所述。

  3. 在jconsole中,您可以使用一个URL,如:

服务: jmx:rmi:// 本地主机: 44444/jndi/rmi:// 本地主机: 1099/karaf-根

和凭据: admin/password (根据您的环境,基于具有admin权限的用户)。

保护Hawtio管理控制台

要使用Keycloak保护Hawtio管理控制台,请完成以下步骤:

  1. 在您的领域的Keycloak管理控制台中创建一个客户端。 例如,在Keycloak中演示境界,创建客户端hawtio-客户,指定公众作为访问类型,并指定指向Hawtio的重定向URI: http:// localhost:8181/hawtio/*。 配置相应的Web源 (在本例中为http:// localhost:8181)。 将客户端范围映射设置为包括视图-轮廓的客户角色账户客户在范围选项卡在hawtio-客户客户详细信息。

  2. 创建keycloak-hawtio-client.json文件中的$ FUSE_HOME/etc目录使用类似于下面示例中显示的内容。 更改境界,资源,以及身份验证-服务器-网址属性根据您的Keycloak环境。 的资源属性必须指向上一步中创建的客户端。 此文件由客户端 (Hawtio JavaScript应用程序) 端使用。

    {
      境界:演示,
      clientId:hawtio-客户,
      url:http:// localhost:8080/auth,
      ssl-必需:外部,
      公共客户:
    }
  3. 创建keycloak-direct-access.json文件中的$ FUSE_HOME/etc目录使用类似于下面示例中显示的内容。 更改境界url属性根据您的Keycloak环境。 此文件由JavaScript客户端使用。

    {
      境界:演示,
      资源:ssh-jmx-管理员-客户端,
      身份验证-服务器-网址:http:// localhost:8080/auth,
      ssl-必需:外部,
      凭据: {
        秘密:密码
      }
    }
  4. 创建keycloak-hawtio.json文件中的$ FUSE_HOME/etc二分使用类似于下面示例中显示的内容。 更改境界身份验证-服务器-网址属性根据您的Keycloak环境。 此文件由服务器 (JAAS登录模块) 端的适配器使用。

    {
      境界:演示,
      资源:jaas,
      仅限不记名:,
      身份验证-服务器-网址:http:// localhost:8080/auth,
      ssl-必需:外部,
      使用资源角色映射:,
      主体属性:首选用户名
    }
  5. 启动JBoss保险丝7.4.0,安装Keycloak功能。 然后输入Karaf终端:

    系统: 属性-p hawtio.keycloakEnabled true
    系统: 财产-p hawtio。领域Keycloak
    系统: 属性-p hawtio.keycloakClientConfig文件: // \ ${karaf.base}/etc/keycloak-hawtio-client.json
    系统: 属性-p hawtio.rolePrincipalClasses org.keycloak.适配器.jaas.RolePrincipal,org.apache.karaf.jaas.boot.principal.RolePrincipal
    重启io.hawt.hawtio-战争
  6. http:// localhost:8181/hawtio并以用户身份从您的Keycloak领域登录。

    请注意,用户需要具有适当的领域角色才能成功地向Hawtio进行身份验证。 可用角色配置在$ FUSE_HOME/etc/system.properties文件在霍蒂奥。角色

2.1.6。弹簧靴适配器

为了能够保护Spring Boot应用程序,您必须将Keycloak Spring Boot adapter JAR添加到您的应用程序中。 然后,您必须通过正常的Spring Boot配置提供一些额外的配置 (应用程序。属性)。 让我们检查一下这些步骤。

适配器安装

Keycloak Spring Boot适配器利用了Spring Boot的自动配置,因此您需要做的就是将Keycloak Spring Boot starter添加到项目中。

要使用Maven添加它,请将以下内容添加到您的依赖项中:

<依赖>
    <groupId>组织。Keycloak
    <人工制品>Keycloak-弹簧-启动-启动器</人工制品>
</依赖>

添加适配器BOM依赖项:

<依赖管理>
  <依赖>
    <依赖>
      <groupId>组织。Keycloak。bom
      <人工制品>Keycloak-适配器-物料清单</人工制品>
      <版本>15.0.2</版本>
      <类型>pom</type>
      <范围>导入</范围>
    </依赖>
  </依赖>
</依赖管理>

当前支持以下嵌入式容器,如果使用Starter,则不需要任何额外的依赖关系:

  • Tomcat

  • Undertow

  • 码头

所需的弹簧启动适配器配置

本节介绍如何配置您的Spring Boot应用程序以使用Keycloak。

而不是Keycloak。json文件,您可以通过正常的Spring Boot配置为Spring Boot Keycloak适配器配置领域。 例如:

Keycloak。领域 = demorealm
keycloak.auth-服务器-url = http:// 127.0.0.1:8080/auth
keycloak.ssl-必需 = 外部
Keycloak。资源 = 演示应用
keycloak.credentials.secret = 11111111-1111-111111111111
keycloak。使用-资源-角色-映射 = 真

您可以通过设置禁用Keycloak弹簧启动适配器 (例如在测试中)Keycloak。启用 = false

要配置策略执行者,与keycloak.json不同,策略执行者配置必须使用而不是仅仅政策执行者

您还需要指定通常会在web.xml。 弹簧启动适配器将设置登录-方法Keycloak并配置安全约束在启动时。 下面是一个示例配置:

Keycloak。安全约束 [0]。身份验证 [0] = 管理员
Keycloak。安全约束 [0]。身份验证 [1] = 用户
keycloak.securityConstraints[0].securityCollections[0].name = 不安全的东西
keycloak.securityConstraints[0].securityCollections[0].patterns[0] =/不安全

Keycloak。安全约束 [1]。身份验证 [0] = 管理员
keycloak.securityConstraints[1].securityCollections[0].name = admin stuff
keycloak.securityConstraints[1].securityCollections[0].patterns[0] = /admin
如果您计划将Spring应用程序部署为WAR,则不应使用Spring Boot适配器,而应将专用适配器用于正在使用的应用程序服务器或servlet容器。 你的Spring Boot还应该包含一个web.xml文件。

2.1.7。Tomcat 7、8和9适配器

为了保护部署在Tomcat 7、8和9上的WAR应用程序,您必须将Keycloak Tomcat 7适配器或Keycloak Tomcat适配器安装到Tomcat安装中。 然后,您必须在部署到Tomcat的每次战争中提供一些额外的配置。 让我们检查一下这些步骤。

适配器安装

适配器不再包含在设备或war发行版中。 每个适配器都是Keycloak下载站点上的单独下载。 它们也可以作为maven工件使用。

您必须将适配器发行版解压缩到Tomcat的lib/目录。 在您的WEB-INF/lib目录中包含适配器的jar将不起作用! Keycloak适配器被实现为阀门,阀门代码必须驻留在Tomcat的主lib/目录中。

在Tomcat 7上安装:

$ cd $ TOMCAT_HOME/lib
$ 解压缩keycloak-tomcat7-adapter-dist.zip

安装在Tomcat 8或9上:

$ cd $ TOMCAT_HOME/lib
$ 解压缩keycloak-tomcat-adapter-dist.zip
每个战争配置所需

本节介绍如何通过在WAR包中添加配置和编辑文件来直接保护WAR。

你必须做的第一件事是创建一个元信息/上下文.xml文件在你的战争包里。 这是一个特定于Tomcat的配置文件,您必须定义一个特定于Keycloak的阀门。

<上下文路径 = "/your-Context-path">
    <阀门类名 = "org.keycloak.适配器.tomcat.KeycloakAuthenticatorValve"/>
</上下文>

接下来,您必须创建一个Keycloak。json中的适配器配置文件网络信息你的战争目录。

此配置文件的格式在Java适配器配置

最后,您必须同时指定登录配置并使用标准servlet安全性在您的url上指定基于角色的约束。 下面是一个例子:

<网络应用 xmlns=http://java.sun.com/xml/ns/javaee
      xmlns:xsi=http:// www.w3.org/2001/XMLSchema-instance
      xsi: 模式定位=http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ web-app_3_0.xsd
      版本=3.0>

        <模块名称>客户门户</模块名称>

    <安全约束>
        <网络资源收集>
            <web-资源-名称>客户</web-资源-名称>
            <url-模式>/*</url-模式>
        </网络资源收集>
        <授权约束>
            <角色名称>用户</角色名称>
        </auth-constraint>
    </安全约束>

    <登录配置>
        <身份验证方法>基本</auth-方法>
        <境界-名称>目前忽略了这一点</领域名称>
    </登录配置>

    <安全-角色>
        <角色名称>管理员</角色名称>
    </安全角色>
    <安全-角色>
        <角色名称>用户</角色名称>
    </安全角色>
</网络应用>

2.1.8。Jetty 9.x适配器

Keycloak有一个单独的适配器,用于Jetty 9.2.x,Jetty 9.3.x和Jetty 9.4.x,您必须将其安装到Jetty安装中。 然后,您必须在部署到Jetty的每次战争中提供一些额外的配置。 让我们检查一下这些步骤。

适配器安装

适配器不再包含在设备或war发行版中。 每个适配器都是Keycloak下载站点上的单独下载。 它们也可以作为maven工件使用。

您必须将9.X码头发行版解压缩到9.X码头基本目录。 在您的WEB-INF/lib目录中包含适配器的jar将不起作用! 在下面的示例中,码头基地被命名为你的基地:

$ cd您的基础
$ 解压缩keycloak-jetty93-adapter-dist-2.5.0.Final.zip

接下来,您必须启用Keycloak您的码头基地模块:

$ java -jar $ JETTY_HOME/start.jar-add-to-startd = keycloak
每个战争配置所需

本节介绍如何通过在WAR包中添加配置和编辑文件来直接保护WAR。

你必须做的第一件事是创建一个WEB-INF/jetty-web.xml文件在你的战争包里。 这是一个特定于码头的配置文件,您必须在其中定义一个特定于Keycloak的身份验证器。

<?xml version = "1.0"?>
<!DOCTYPE配置公共 “-// Mort Bay咨询 // DTD配置 // EN” “http://www.eclipse.org/jetty/ 配置 _ 9_0.dtd”>
<配置类 = "组织.eclipse.jetty.webapp.WebAppContext">
    <获取名称 = "安全处理程序">
        <设置名称 = "认证器">
            <New class = "org.keycloak.适配器.jetty.KeycloakJettyAuthenticator">
            </新>
        </Set>
    </Get>
</Configure>

接下来,您必须创建一个Keycloak。json中的适配器配置文件网络信息你的战争目录。

此配置文件的格式在Java适配器配置节。

Jetty 9.x适配器将无法找到Keycloak。json文件。 您必须在jetty-web.xml如下所述的文件。

您可以在jetty-web.xml。 您只需要弄清楚json设置如何与org.keycloak.表示.适配器.配置.AdapterConfig类。

<?xml version = "1.0"?>
<!DOCTYPE配置公共 “-// Mort Bay咨询 // DTD配置 // EN” “http://www.eclipse.org/jetty/ 配置 _ 9_0.dtd”>
<配置类 = "组织.eclipse.jetty.webapp.WebAppContext">
  <获取名称 = "安全处理程序">
    <设置名称 = "认证器">
        <New class = "org.keycloak.适配器.jetty.KeycloakJettyAuthenticator">
            <Set name = "adapterConfig">
                <New class = "org.keycloak.表示.适配器.配置.AdapterConfig">
                    <Set name = "境界">tomcat</Set>
                    <Set name = "resource"> 客户门户 </Set>
                    <Set name = "authServerUrl">http:// localhost:8081/auth</Set>
                    <Set name = "sslresed"> 外部 </Set>
                    <Set name = "凭据">
                        <地图>
                            <条目>
                                <项目> 秘密 </项目>
                                <项目> 密码 </项目>
                            </条目>
                        </Map>
                    </Set>
                </新>
            </Set>
        </新>
    </Set>
  </Get>
</Configure>

您不必打开战争就可以用keycloak保护它。 而是在webapps目录中创建名称为yourwar.xml的jetty-web.xml文件。 码头应该捡起来。 在这种模式下,您必须直接在xml文件中声明keycloak.json配置。

最后,您必须同时指定登录配置并使用标准servlet安全性在您的url上指定基于角色的约束。 下面是一个例子:

<网络应用 xmlns=http://java.sun.com/xml/ns/javaee
      xmlns:xsi=http:// www.w3.org/2001/XMLSchema-instance
      xsi: 模式定位=http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ web-app_3_0.xsd
      版本=3.0>

        <模块名称>客户门户</模块名称>

    <安全约束>
        <网络资源收集>
            <web-资源-名称>客户</web-资源-名称>
            <url-模式>/*</url-模式>
        </网络资源收集>
        <授权约束>
            <角色名称>用户</角色名称>
        </auth-constraint>
        <用户数据约束>
            <运输-保证>机密</运输-保证>
        </用户数据约束>
    </安全约束>

    <登录配置>
        <身份验证方法>基本</auth-方法>
        <境界-名称>目前忽略了这一点</领域名称>
    </登录配置>

    <安全-角色>
        <角色名称>管理员</角色名称>
    </安全角色>
    <安全-角色>
        <角色名称>用户</角色名称>
    </安全角色>
</网络应用>

2.1.9。弹簧安全适配器

要使用Spring Security和Keycloak保护应用程序,请将此适配器添加为项目的依赖项。 然后,您必须在Spring安全配置文件中提供一些额外的bean,并将Keycloak安全过滤器添加到您的管道中。

与其他Keycloak适配器不同,您不应该在web.xml中配置安全性。 但是,仍然需要keycloak.json。 为了使单点注销正常工作,您必须定义一个会话侦听器。

可以定义会话侦听器:
  • 在web.xml中 (用于纯Spring安全环境):

<监听器>
     <监听器类> 组织。springframework.security.web.session.Https essioneventpublisher </监听器类>
</监听器>
  • 作为Spring bean (在使用Spring安全适配器的Spring Boot环境中)

@ Bean
公共ServletListenerRegistrationBean <httpessioneventpublisher> httpessioneventpublisher () {
    返回新的ServletListenerRegistrationBean <httpessioneventpublisher>(new httpessioneventpublisher ());
}
适配器安装

添加Keycloak弹簧安全适配器作为对Maven POM或Gradle构建的依赖。

<依赖>
    <groupId>组织。Keycloak
    <人工制品>Keycloak-弹簧-安全-适配器</人工制品>
    <版本>15.0.2</版本>
</依赖>
弹簧安全配置

Keycloak Spring安全适配器利用了Spring Security灵活的安全配置语法。

Java配置

Keycloak提供了一个KeycloakWebSecurityConfigurerAdapter作为一个方便的基类,用于创建一个网络安全配置器实例。 实现允许通过覆盖方法进行定制。 虽然不需要使用它,但它大大简化了您的安全上下文配置。

@ KeycloakConfiguration
公众  安全配置 延伸KeycloakWebSecurityConfigurerAdapter
{
    /**
     * 向身份验证管理器注册KeycloakAuthenticationProvider。
     */
    @ 汽车
    公众 虚空配置全球 (身份验证管理生成器身份验证)投掷 异常{
        auth.authenticationProvider(keycloakAuthenticationProvider());
    }

    /**
     * 定义会话身份验证策略。
     */
    @ Bean
    @ 覆盖
    受保护会话认证策略 () {
        返回 新的注册会话认证策略 (新的会话注册impl ());
    }

    @ 覆盖
    受保护 虚空配置 (HttpSecurity http)投掷 异常
    {
        超级。配置 (http);
        http
                。授权任务 ()
                。天线 (/客户 *).hasRole (用户)
                。天线 (/管理员 *).hasRole (管理员)
                。anyRequest().permitAll();
    }
}

您必须提供会话身份验证策略bean,该类型应为注册会话认证策略适用于公共或机密申请,以及零认证会话策略对于仅承载的应用程序。

春季安全会话固定保护战略目前不支持,因为它在通过Keycloak登录后更改了会话标识符。 如果会话标识符发生变化,则通用注销将不起作用,因为Keycloak不知道新的会话标识符。

@ KeycloakConfiguration注释是一个元数据注释,它定义了集成所需的所有注释 春季安全的Keycloak。 如果你有一个复杂的Spring安全设置,你可以简单地看看 的@ KeycloakConfiguration注释并创建自己的自定义元注释或仅使用特定的Spring注释 用于Keycloak适配器。
XML配置

虽然Spring Security的XML名称空间简化了配置,但自定义配置可能有点冗长。

<?xml version = "1.0" encoding = "UTF-8"?>
<豆 xmlns=http://www.springframework.org/schema/beans
       xmlns: 上下文=http://www.springframework.org/schema/context
       xmlns: 安全性=http://www.springframework.org/schema/security
       xmlns:xsi=http:// www.w3.org/2001/XMLSchema-instance
       xsi: 模式定位=
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/ spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/ spring-context.xsd
       http://www.springframework.org/schema/security
       http://www.springframework.org/schema/security/ spring-security.xsd>

    <上下文: 组件扫描 基本包装=组织。Keycloak。适配器。springsecurity />

    <安全性: 身份验证管理器 别名=身份验证管理器>
        <安全性: 身份验证提供者 参考=keycloakAuthenticationProvider />
    </安全性: 身份验证管理器>

    <bean id=自适应部署上下文 =组织。Keycloak。适配器。springsecurity。适配器部署上下文工厂>
        <构造函数-arg =/网络信息/Keycloak.json />
    </bean>

    <bean id=密钥锁认证中心点 =org.keycloak.适配器.springsecurity.身份验证.KeycloakAuthenticationEntryPoint>
        <构造函数-arg 参考=自适应部署上下文 />
    </bean>
    <bean id=keycloakAuthenticationProvider =组织。keycloak。适配器。springsecurity。身份验证。KeycloakAuthenticationProvider />
    <bean id=keycloakPreAuthActionsFilter =组织。密钥斗篷。适配器。springsecurity。过滤器。密钥斗篷预授权过滤器 />
    <bean id=keycloakAuthenticationProcessingFilter =组织。Keycloak。适配器。springsecurity。过滤器。Keycloak认证处理过滤器>
        <构造函数-arg 名称=身份验证管理器 参考=身份验证管理器 />
    </bean>
    <bean id=密钥cloaksecuritycontextrequestfilter
          =组织。密钥斗篷。适配器。springsecurity。过滤器。密钥斗篷安全 />

    <bean id=keycloakLogoutHandler =org.keycloak.适配器.springsecurity.身份验证.KeycloakLogoutHandler>
        <构造函数-arg 参考=自适应部署上下文 />
    </bean>

    <bean id=登录过滤器 =组织。springframework。安全性。web。身份验证。注销过滤器>
        <构造函数-arg 名称=登录成功网址 =/ />
        <构造函数-arg 名称=处理程序>
            <列表>
                <ref =keycloakLogoutHandler />
                <bean =org.springframework.security.web.身份验证.注销.SecurityContextLogoutHandler />
            </list>
        </构造函数-arg>
        <属性 名称=登录请求匹配器>
            <bean =组织。springframework.security.web.util.匹配器.AntPathRequestMatcher>
                <构造函数-arg 名称=图案 =/sso/注销 ** />
                <构造函数-arg 名称=httpMethod =获取 />
            </bean>
        </属性>
    </bean>

    <安全性: http 自动配置= 入口点参考=密钥锁认证中心点>
        <安全性: 自定义过滤器 参考=keycloakPreAuthActionsFilter 以前=注销过滤器 />
        <安全性: 自定义过滤器 参考=keycloakAuthenticationProcessingFilter 以前=表单 _ 登录 _ 过滤器 />
        <安全性: 自定义过滤器 参考=密钥cloaksecuritycontextrequestfilter 之后=表单 _ 登录 _ 过滤器 />
        <安全性: 拦截网址 图案=/客户 ** 访问=角色 _ 用户 />
        <安全性: 拦截网址 图案=/管理员 ** 访问=角色 _ 管理 />
        <安全性: 自定义过滤器 参考=登录过滤器 位置=注销过滤器 />
    </安全性: http>

</beans>
多租户

Keycloak弹簧安全适配器还支持多租户。 而不是注射自适应部署上下文工厂随着通往Keycloak。json您可以注入KeycloakConfigResolver接口。 有关如何实施的更多详细信息KeycloakConfigResolver可以在多租户

命名安全角色

Spring Security在使用基于角色的身份验证时,要求角色名称以角色 _。 例如,管理员角色必须在Keycloak中声明为角色 _ 管理或者类似的,不是简单的管理员

班级组织。keycloak。适配器。springsecurity。身份验证。KeycloakAuthenticationProvider支持可选组织。springframework.security.core.authority.mapping.GrantedAuthoritiesMapper可用于将来自Keycloak的角色映射到Spring Security识别的角色。 例如,使用组织。springframework.security.core.authority.Mapper.SimpleAuthorityMapper要插入角色 _前缀并将角色名称转换为大写。 类是Spring Security核心模块的一部分。

客户端对客户端支持

为了简化客户端之间的通信,Keycloak提供了Spring的扩展RestTemplate为您处理承载令牌身份验证。 要启用此功能,您的安全配置必须添加KeycloakRestTemplate豆。 请注意,它必须作为原型作用域才能正常运行。

对于Java配置:

@ 配置
@ 启用网络安全
@ 组件扫描(basePackageClasses = KeycloakSecurityComponents.class)
公众  安全配置 延伸KeycloakWebSecurityConfigurerAdapter {

    ...

    @ 汽车
    公众KeycloakClientRequestFactory keycloakClientRequestFactory;

    @ Bean
    @ 范围(可配置的beanfactory。SCOPE_PROTOTYPE)
    公众KeycloakRestTemplate keycloakRestTemplate() {
        返回 新的KeycloakRestTemplate(keycloakClientRequestFactory);
    }

    ...
}

对于XML配置:

<bean id=keycloakRestTemplate =组织。Keycloak。适配器。springsecurity。客户端。Keycloak模板 范围=原型>
    <构造函数-arg 名称=工厂 参考=关键cloakclientrequestfactory />
</bean>

然后,您的应用程序代码可以使用KeycloakRestTemplate任何时候它需要打电话给另一个客户。 例如:

@ 服务
公众  远程产品服务 工具产品服务 {

    @ 汽车
    私人KeycloakRestTemplate模板;

    私人 字符串端点;

    @ 覆盖
    公众 列表<字符串> 获取产品 () {
        响应 <字符串[]> 响应 = 模板。获取实体 (端点,字符串[]。类);
        返回 数组。asList (响应.getBody());
    }
}
Spring Boot集成

弹簧靴和弹簧安全适配器可以组合。

如果您使用Keycloak弹簧启动启动器来使用弹簧安全适配器,则只需添加弹簧安全启动器:

<依赖>
  <groupId>组织。springframework。启动
  <人工制品>spring-boot-starter-安全性</人工制品>
</依赖>
使用弹簧启动配置

默认情况下,弹簧安全适配器会查找一个Keycloak。json配置文件。 您可以确保它通过添加此bean查看Spring Boot适配器提供的配置:

@ Bean
公众KeycloakConfigResolver keycloakConfigResolver() {
    返回 新的KeycloakSpringBootConfigResolver();
}
避免双豆注册

Spring Boot尝试急切地向web应用程序上下文注册过滤器bean。 因此,在弹簧启动环境中运行Keycloak弹簧安全适配器时,可能需要添加过滤注册beans到您的安全配置,以防止Keycloak过滤器被注册两次。

弹簧启动2.1也禁用spring.main.allow-bean-definition-overriding默认情况下。 这可能意味着BeanDefinitionOverrideException如果配置类扩展KeycloakWebSecurityConfigurerAdapter注册一个已经被检测到的bean@ 组件扫描。 可以通过覆盖注册以使用特定于引导的@ ConditionalOnMissingBean注释,与Httpessionmanager下面。

@ 配置
@ 启用网络安全
公众  安全配置 延伸KeycloakWebSecurityConfigurerAdapter
{
    ...

    @ Bean
    公众过滤注册bean关键字cloakauthenticationprocessingfilterregistrationbean (
            KeycloakAuthenticationProcessingFilter过滤器) {
        过滤注册bean =新的FilterRegistrationBean (过滤器);
        注册bean.setEnabled ();
        返回注册bean;
    }

    @ Bean
    公众过滤注册bean关键字cloakpreauthactionsfilterregistrationbean (
            KeycloakPreAuthActionsFilter过滤器) {
        过滤注册bean =新的FilterRegistrationBean (过滤器);
        注册bean.setEnabled ();
        返回注册bean;
    }

    @ Bean
    公众过滤注册bean关键字cloakauthenticatedactionsfilterbean (
            KeycloakAuthenticatedActionsFilter过滤器) {
        过滤注册bean =新的FilterRegistrationBean (过滤器);
        注册bean.setEnabled ();
        返回注册bean;
    }

    @ Bean
    公众过滤注册bean关键字cloaksecuritycontextrequestfilterbean (
        KeycloakSecurityContextRequestFilter过滤器) {
        过滤注册bean =新的FilterRegistrationBean (过滤器);
        注册bean.setEnabled ();
        返回注册bean;
    }

    @ Bean
    @ 覆盖
    @ ConditionalOnMissingBean(Https essionmanager.class)
    受保护Https essionmanager () {
        返回 新的Httpessionmanager ();
    }
    ...
}

2.1.10。Java Servlet过滤器适配器

如果要在没有Keycloak适配器的平台上部署Java Servlet应用程序,则选择使用servlet过滤器适配器。 此适配器的工作方式与其他适配器有点不同。 您没有在web.xml中定义安全约束。 相反,您使用Keycloak servlet过滤器适配器定义了一个过滤器映射,以保护要保护的url模式。

反向通道注销的工作原理与标准适配器有点不同。 而不是使HTTP会话无效,而是将会话id标记为已注销。 没有基于会话id使HTTP会话无效的标准方法。
<网络应用 xmlns=http://java.sun.com/xml/ns/javaee
      xmlns:xsi=http:// www.w3.org/2001/XMLSchema-instance
      xsi: 模式定位=http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ web-app_3_0.xsd
      版本=3.0>

        <模块名称>应用</模块名称>

    <过滤器>
        <过滤器名称>Keycloak过滤器</过滤器名称>
        <过滤器类>组织。密钥斗篷。适配器。servlet。密钥斗篷</过滤器类>
    </过滤器>
    <过滤器映射>
        <过滤器名称>Keycloak过滤器</过滤器名称>
        <url-模式>/Keycloak/*</url-模式>
        <url-模式>/受保护/*</url-模式>
    </过滤器映射>
</网络应用>

在上面的代码片段中有两个url模式。 /受保护/*我们想要保护的文件,而/Keycloak/*url模式处理来自Keycloak服务器的回调。

如果您需要排除配置的下面的一些路径url模式您可以使用过滤器init-paramKeycloak。配置。跳过模式要配置 描述路径模式的正则表达式,keycloak过滤器应立即将其委派给过滤器链。 默认情况下,没有配置skipPattern。

模式与requestURI没有上下文路径。 给定上下文路径/我的应用请求/我的应用/索引将与/index.html反对跳跃模式。

<init-参数>
    <参数名称>Keycloak。配置。跳过模式</参数名称>
    <参数值>^/(path1 | path2 | path3).*</参数值>
</init参数>

请注意,您应该在Keycloak管理控制台中使用指向过滤器的URL模式覆盖的安全部分的管理url配置客户端。

管理员URL将对管理员URL进行回调,以执行诸如反向通道注销之类的操作。 所以,这个例子中的管理员URL应该是http[s]:// 主机名/{上下文-根}/keycloak

Keycloak筛选器具有与其他适配器相同的配置参数,但必须将它们定义为filter init params而不是上下文params。

要使用此过滤器,请在您的战争poms中包含此maven工件:

<依赖>
    <groupId>组织。Keycloak
    <人工制品>Keycloak-servlet-过滤器-适配器</人工制品>
    <版本>15.0.2</版本>
</依赖>
在OSGi上使用

servlet过滤器适配器被打包为OSGi捆绑包,因此可以在具有HTTP服务和HTTP白板的通用OSGi环境 (R6及以上) 中使用。

安装

适配器及其依赖关系作为Maven工件分发,因此您需要工作的Internet连接来访问Maven Central,或者将工件缓存在本地Maven repo中。

如果您使用的是Apache Karaf,则可以简单地从Keycloak功能存储库中安装功能:

karaf @ root()> 功能: 回购-添加mvn:org.keycloak/keycloak-osgi-功能/15.0.2/xml/功能
karaf @ root()> 功能: 安装密钥斗篷-servlet-过滤器-适配器

有关其他OSGi运行时,请参阅有关如何安装适配器捆绑包及其依赖项的运行时文档。

如果您的OSGi平台是带有Pax Web的Apache Karaf,则应考虑使用JBoss保险丝6或者JBoss保险丝7改为适配器。
配置

首先,需要将适配器注册为带有OSGi HTTP服务的servlet过滤器。 最常见的方法是编程 (例如通过bundle activator) 和声明式 (使用OSGi注释)。 我们建议使用后者,因为它简化了动态注册和取消注册过滤器的过程:

包装 我的包装;

导入 javax.servlet.Filter;
导入 组织。密钥斗篷。适配器。servlet。密钥斗篷;
导入 org.osgi.service.com组件。注释。组件;
导入 组织。osgi。服务。白板常量;

@ 组件(
    立即 =,
    服务 =过滤器。班级,
    属性 = {
        密钥cloakoidctorter。配置 _ 文件 _ 参数 +=+Keycloak。json,
        白板常量。白板过滤器模式 +=+/*,
        白板常量。白板 _ 上下文 _ 选择 +=+(osgi。白板。上下文。名称 = 我的上下文)
    }
)
公众  KeycloakFilter 延伸Keycloakoidcsfilter {
  //
}

上面的代码片段使用OSGi声明式服务规范将过滤器公开为OSGI服务javax.servlet.Filter类。 一旦该类在OSGi服务注册表中发布,它将被OSGi HTTP服务实现拾取,并用于过滤指定servlet上下文的请求。 这将为与servlet上下文路径 + 过滤器路径匹配的每个请求触发Keycloak适配器。

由于该组件由OSGi配置管理服务控制,因此可以动态配置其属性。 为此,请创建一个我的包装。键盘过滤器。cfgOSGi运行时的标准配置位置下的文件:

keycloak.config.file = /path/至/keycloak.json
osgi.http.白板.过滤器.模式 =/安全/*

或者使用交互式控制台,如果你的运行时允许:

karaf @ root()> 配置: 编辑mypackage.KeycloakFilter
karaf @ root()> 配置: 属性-设置keycloak.config.file '${karaf.etc}/keycloak.json'
karaf @ root()> 配置: 更新

如果您需要更多控制,例如提供自定义KeycloakConfigResolver实施多租户,您可以以编程方式注册过滤器:

公众  活化剂 工具捆绑激活器 {

  私人服务注册;

  公众 虚空开始 (捆绑文本上下文)投掷 异常{
    哈希表道具 =新的 哈希表();
    道具。放 (HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN,/安全/*);
    道具。put (键cloakoidcsfilter.CONFIG_RESOLVER_PARAM,新的MyConfigResolver());

    这个。注册 = 上下文。注册服务 (过滤器。类。getName(),新的Keycloakoidcpreter (),道具);
  }

  公众 虚空停止 (捆绑文本上下文)投掷 异常{
    这个。注册。注销 ();
  }
}

请参考阿帕奇费利克斯超文本传输协议服务有关程序注册的更多信息。

2.1.11。JAAS插件

通常不需要为大多数应用程序使用JAAS,特别是如果它们是基于HTTP的,您应该很可能选择我们的其他适配器之一。 但是,某些应用程序和系统可能仍依赖于纯遗留JAAS解决方案。 Keycloak提供了两个登录模块来帮助在这些情况下。

提供的登录模块有:

组织。密钥斗篷。适配器。jaas。DirectAccessGrantsLoginModule

此登录模块允许使用Keycloak中的用户名/密码进行身份验证。 它在使用资源所有者密码凭据流以验证是否提供了 用户名/密码有效。 它对于非基于web的系统很有用,这些系统需要依赖JAAS并希望使用Keycloak,但不能使用标准浏览器 基于非web性质的流。 此类应用程序的示例可以是消息传递或SSH。

组织。Keycloak。适配器。jaas。BearerTokenLoginModule

此登录模块允许使用通过CallbackHandler作为密码传递给它的Keycloak访问令牌进行身份验证。 例如,当您从基于标准的身份验证流中获得Keycloak访问令牌并且您的web应用程序然后 需要与依赖JAAS的外部非基于web的系统进行对话。 例如消息系统。

两个模块都使用以下配置属性:

keycloak-config-file

的位置Keycloak。json配置文件。 配置文件可以位于文件系统上,也可以位于类路径上。 如果它位于 在类路径上,您需要将位置前缀为类路径:(例如类路径:/路径/keycloak.json)。 这是必填。

角色-校长级

为附加到JAAS主题的角色主体配置替代类。 默认值为组织。Keycloak。适配器。jaas。角色负责人。 注意: 该类需要具有单个构造函数的构造函数字符串争论。

范围

此选项仅适用于直接访问模块。 指定的值将用作OAuth2范围 资源所有者密码凭据授予请求中的参数。

2.1.12。CLI/桌面应用程序

Keycloak支持保护桌面 (例如Swing、JavaFX) 或CLI应用程序通过 Keycloak已安装通过系统浏览器执行身份验证步骤来适配器。

Keycloak已安装适配器支持桌面和一个手册 变体。 桌面变种使用系统浏览器 收集用户凭据。 手动变体 从以下位置读取用户凭据STDIN

它是如何工作的

使用桌面变体Keycloak已安装 适配器打开一个桌面浏览器窗口,用户在其中使用常规的Keycloak 登录页面登录时登录桌面 ()方法在Keycloak已安装对象。

登录页面URL打开时带有重定向参数 这指向一个本地服务器插座在免费的短暂端口上收听 上本地主机由适配器启动。

成功登录后,Keycloak已安装接收授权码 从传入的HTTP请求,并执行授权代码流。 一旦令牌交换的代码完成,服务器插座是关机。

如果用户已经有一个活动的Keycloak会话,则 未显示登录表单,但继续执行令牌交换的代码, 这使得基于网络的SSO体验更加流畅。

客户端最终接收到令牌 (access_token,refresh_token, id_token),然后可以用来调用后端服务。

Keycloak已安装适配器提供更新陈旧令牌的支持。

适配器安装
<依赖>
        <groupId>组织。Keycloak
        <人工制品>Keycloak-已安装-适配器</人工制品>
        <版本>15.0.2</版本>
</依赖>
客户端配置

应用程序需要配置为公众OpenID连接客户端 启用标准流和http:// localhost作为允许有效重定向URI

Keycloak已安装适配器支持PKCE[RFC 7636] 机制,以在 代码到令牌交换OIDC协议。 PKCE可以通过“启用-pkce”: 真设置 在适配器配置中。 强烈建议启用PKCE,以避免代码注入和代码重播攻击。
用法

Keycloak已安装适配器从 元信息/密钥斗篷.json在类路径上。 自定义配置 可以提供一个输入流或者KeycloakDeployment 通过Keycloak已安装构造函数。

在下面的示例中,客户端配置为桌面应用 使用以下内容Keycloak。json:

{
  境界:桌面应用程序授权,
  身份验证-服务器-网址:http:// localhost:8081/auth,
  ssl-必需:外部,
  资源:桌面应用,
  公共客户:,
  使用资源角色映射:,
  启用-pkce:
}

下面的草图演示了使用Keycloak已安装适配器:

// 从classpath读取配置: META-INF/keycloak.json
KeycloakInstalled keycloak =新的KeycloakInstalled();

// 打开桌面浏览器
keycloak.loginDesktop();

AccessToken令牌 = keycloak.getToken();
// 使用token发送后端请求

// 确保令牌至少有效30秒
最小有效性 =30升;
字符串tokenString = keycloak.getTokenString (最小有效性,时间单位。秒);


 // 当您想注销用户时。
keycloak.Logoout ();
Keycloak已安装类支持自定义由 通过登录/注销请求loginResponseWriterlogoutResponseWriter属性。
示例

下面提供了上述配置的示例。

导入 java.util.Locale;
导入 java.util.concurrent.Executors;
导入 java.util.并发.时间单位;

导入 org.keycloak.适配器.已安装.KeycloakInstalled;
导入 组织。Keycloak。代表。附件;

公众  桌面应用程序{

        公众 静态 虚空主要 (字符串[]args)投掷 异常{

                KeycloakInstalled keycloak =新的KeycloakInstalled();
                Keycloak。设置区域 (区域设置。英语);
                keycloak.loginDesktop();

                AccessToken令牌 = keycloak.getToken();
                执行者。newSingleThreadExecutor()。提交 (() -> {

                        系统。输出。打印 (已登录...);
                        系统。输出。打印 (令牌:+ 令牌.Get主题 ());
                        系统。输出。打印 (用户名:+ 令牌.getPreferredUsername());
                        尝试{
                                系统。输出。打印 (附件:+ keycloak.getTokenString());
                        }抓住(异常ex) {
                                例如。printStackTrace();
                        }

                        int时间秒 =20;
                        系统。输出。printf (注销在... % d秒 % n,timeoutSeconds);
                        尝试{
                                时间单位。秒。睡眠 (timeoutSeconds);
                        }抓住(异常e) {
                                e.printStackTrace();
                        }

                        尝试{
                                keycloak.Logoout ();
                        }抓住(异常e) {
                                e.printStackTrace();
                        }

                        系统。输出。打印 (退出...);
                        系统。出口 (0);
                });
        }
}

2.1.13。安全上下文

KeycloakSecurityContext如果您需要直接访问令牌,则可以使用接口。 如果您想检索额外的 令牌中的详细信息 (例如用户配置文件信息),或者您想要调用受Keycloak保护的RESTful服务。

在servlet环境中,它作为HttpServletRequest中的属性在安全调用中可用:

httpServletRequest
    。getAttribute(KeycloakSecurityContext.class.getName());

或者,它在HttpSession中的无担保请求中可用:

httpServletRequest.getSession()
    。getAttribute(KeycloakSecurityContext.class.getName());

2.1.14。错误处理

Keycloak为基于servlet的客户端适配器提供了一些错误处理工具。 当身份验证中遇到错误时,Keycloak将调用Http服务响应。发送错误 ()。 您可以在您的web.xml文件来处理错误,但是你想要。 Keycloak可以引发400、401、403和500错误。

<错误-页面>
    <错误代码>403</错误代码>
    <位置>/错误处理程序</位置>
</错误页面>

Keycloak还设置了一个HttpServletRequest您可以检索的属性。 属性名称为组织。密钥斗篷。适配器。spi。身份验证错误,应该将其铸造为组织。密钥斗篷。适配器。OIDCAuthenticationError

例如:

导入 组织。密钥斗篷。适配器。OIDCAuthenticationError;
导入 组织。密钥斗篷。适配器。OIDCAuthenticationError。原因;
...

OIDCAuthenticationError错误 = (OIDCAuthenticationError) httpServletRequest
    。getAttribute ('组织。密钥斗篷。适配器。spi。身份验证错误');

Reason reason = error.getReason();
系统。out.println(reason.name());

2.1.15。注销

您可以通过多种方式注销web应用程序。 对于Java EE servlet容器,您可以调用HttpServletRequest。注销 ()。 对于其他浏览器应用程序,您可以将浏览器重定向到 http:// auth-server/auth/realms/{realm-name}/protocol/openid-connect/logoout?redirect_uri = encodedRedirectUri,如果您与浏览器进行了SSO会话,则会将您注销。

当使用HttpServletRequest。注销 ()选项适配器对传递刷新令牌的Keycloak服务器执行后通道POST调用。 如果该方法是从不受保护的页面 (未检查有效令牌的页面) 执行的,则刷新令牌可能不可用,在这种情况下, 适配器跳过呼叫。 为此,使用被保护的页面执行HttpServletRequest。注销 ()建议使用,以便当前令牌始终 考虑到这一点,如果需要,将与Keycloak服务器进行交互。

如果要避免在注销过程中退出外部身份提供程序,则可以提供参数初始化 _idp,值为 所讨论的身份提供者的身份 (别名)。 当作为外部身份提供程序发起的单个注销的一部分调用注销端点时,这很有用。

2.1.16。参数转发

Keycloak初始授权端点请求具有对各种参数的支持。 大多数参数描述在 OIDC规范。 一些参数由适配器自动添加,基于 在适配器配置上。 但是,也可以在每次调用的基础上添加一些参数。 当您打开安全应用程序URI时, 特定参数将被转发到Keycloak授权端点。

例如,如果您请求脱机令牌,则可以使用范围参数如下:

http:// myappserver/mysecuredapp?范围 = 离线访问

和参数范围 = 离线访问将自动转发到Keycloak授权端点。

支持的参数为:

  • 范围-使用以空格分隔的范围列表。 空格分隔的列表通常引用客户端范围 在特定客户端上定义。 请注意,范围openid将始终由适配器添加到范围列表中。 例如,如果你 输入范围选项地址电话,那么对Keycloak的请求将包含scope参数scope = openid地址电话

  • 提示-Keycloak支持以下设置:

    • 登录-SSO将被忽略,并且即使用户已经通过身份验证,也将始终显示Keycloak登录页面

    • 同意-仅适用于以下客户需要同意。 如果使用,则始终显示同意页面, 即使用户先前同意了此客户端。

    • -永远不会显示登录页面; 相反,用户将被重定向到应用程序,如果用户出现错误 尚未认证。 此设置允许您在应用程序端创建过滤器/拦截器,并显示自定义错误页面 给用户。 请参阅规范中的更多详细信息。

  • max_age-仅在用户已通过身份验证时使用。 指定认证持续的最大允许时间,测量 从用户进行身份验证时起。 如果用户的身份验证时间超过maxAge,SSO被忽略,他必须重新认证。

  • login_hint-用于预先填写登录表单上的用户名/电子邮件字段。

  • kc_idp_hint-用于告诉Keycloak跳过显示登录页面,并自动重定向到指定的身份提供程序。 更多信息身份提供者文档

大多数参数都在OIDC规范。 唯一的例外是参数kc_idp_hint,它特定于Keycloak,并包含要自动使用的身份提供程序的名称。 有关更多信息,请参见身份经纪中的部分服务器管理指南

如果您使用附加的参数打开URL,如果您已经通过身份验证,适配器将不会将您重定向到Keycloak 在应用程序中。 例如,打开http:// myappserver/mysecuredapp?prompt = login不会自动将您重定向到 如果您已经对应用程序进行了身份验证,则可以使用Keycloak登录页面我的秘密。 这种行为将来可能会改变。

2.1.17。客户端身份验证

当机密OIDC客户端需要发送反向通道请求 (例如,为令牌交换代码或刷新令牌) 时,它需要对Keycloak服务器进行身份验证。 默认情况下,有三种方法可以对客户端进行身份验证: 客户端ID和客户端秘密,使用签名的JWT进行客户端身份验证或使用客户端秘密对签名的JWT进行客户端身份验证。

客户端ID和客户端密钥

这是OAuth2规范中描述的传统方法。 客户端有一个秘密,适配器 (应用程序) 和Keycloak服务器都需要知道这个秘密。 您可以在Keycloak管理控制台中生成特定客户端的秘密,然后将此秘密粘贴到Keycloak。json应用程序端的文件:

凭据: {
    秘密:19666a4f-32dd-4049-b082-684c74115f28
}
带有签名JWT的客户端身份验证

这是基于RFC7523规格。 它是这样工作的:

  • 客户端必须具有私钥和证书。 对于Keycloak,这是通过传统的密钥库文件,它可以在客户端应用程序的类路径上使用,也可以在文件系统的某个地方使用。

  • 一旦客户端应用程序启动,它允许在JWKS假设http://myhost.com/myapp是客户端应用程序的基本URL,则使用诸如http://myhost.com/myapp/ k_jwks之类的URL进行格式化。 这个URL可以被Keycloak使用 (见下文)。

  • 在身份验证期间,客户端生成JWT令牌并用其私钥对其进行签名,并将其发送给Keycloak 中的特定反向通道请求 (例如,代码到令牌的请求)客户端 _ 断言参数。

  • Keycloak必须具有客户端的公钥或证书,以便它可以在JWT上验证签名。 在Keycloak中,您需要为客户端配置客户端凭据。 首先你需要选择签署JWT作为在选项卡中验证客户端的方法凭据在管理控制台中。 然后您可以在选项卡中选择钥匙:

    • 配置Keycloak可以下载客户端公钥的JWKS URL。 这可以是诸如http://myhost.com/myapp/ k_jwks之类的URL (请参见上面的详细信息)。 此选项是最灵活的,因为客户端可以随时旋转其键,然后Keycloak总是在需要时下载新键,而无需更改配置。 更准确地说,当Keycloak看到由未知签名的令牌时,它会下载新密钥孩子(密钥ID)。

    • 以PEM格式,JWK格式或从密钥库上传客户端的公钥或证书。 使用此选项,公钥是硬编码的,并且在客户端生成新密钥对时必须更改。 如果您没有自己的可用空间,您甚至可以从Keycloak管理控制台生成自己的密钥库。 有关如何设置Keycloak管理控制台的更多详细信息,请参见服务器管理指南

要在适配器端进行设置,您需要在您的Keycloak。json文件:

凭据: {
  jwt: {
    客户端-密钥库-文件:类路径: keystore-client.jks,
    客户端-密钥库-类型:JKS,
    客户端-密钥库-密码:storepass,
    客户端密钥密码:键盘,
    客户端密钥别名:客户密钥,
    令牌-过期:10
  }
}

使用此配置,密钥库文件keystore-client.jks在你的战争中必须在类路径上可用。 如果不使用前缀类路径: 您可以指向客户端应用程序正在运行的文件系统上的任何文件。

为了获得灵感,您可以看一下将示例分发到主要演示示例中的示例产品门户申请。

使用客户端秘密对已签名的JWT进行客户端身份验证

这与带有签名JWT的客户端身份验证相同,除了使用客户端机密而不是私钥和证书。

客户端有一个秘密,适配器 (应用程序) 和Keycloak服务器都需要知道这个秘密。 你需要选择与客户秘密签署JWT作为在选项卡中验证客户端的方法凭据在管理控制台中,然后将此秘密粘贴到Keycloak。json应用程序端的文件:

凭据: {
  秘密-jwt: {
    秘密:19666a4f-32dd-4049-b082-684c74115f28,
    算法:HS512
  }
}

“算法” 字段指定使用客户端秘密签名的JWT的算法。 它必须是以下值之一: HS256,HS384和hs512。 详情请参阅JSON网络算法 (JWA)

此 “算法” 字段是可选的,因此如果 “算法” 字段不存在于Keycloak。json文件。

添加您自己的客户端身份验证方法

您也可以添加自己的客户端身份验证方法。 您将需要同时实现客户端和服务器端提供程序。 有关更多详细信息,请参见身份验证SPI中的部分服务器开发指南

2.1.18。多租户

在我们的上下文中,多租户意味着可以使用多个Keycloak领域来保护单个目标应用程序 (WAR)。 可以定位领域 在相同的Keycloak实例上或在不同的实例上。

在实践中,这意味着应用程序需要有多个Keycloak。json适配器配置文件。

您可以使用多个WAR实例,将不同的适配器配置文件部署到不同的上下文路径。 然而,这可能不方便 您可能还想根据上下文路径以外的其他内容选择领域。

Keycloak可以使用自定义配置解析器,因此您可以选择用于每个请求的适配器配置。

要首先实现这一点,您需要创建一个实现组织。keycloak。适配器。KeycloakConfigResolver。 例如:

包装 示例;

导入 组织。keycloak。适配器。KeycloakConfigResolver;
导入 组织。Keycloak。适配器。Keycloak部署;
导入 组织。Keycloak。适配器。Keycloak部署生成器;

公众  路径基础keycloakconfigresolver 工具KeycloakConfigResolver {

    @ 覆盖
    公众KeycloakDeployment解析 (OIDCHttpFacade。请求请求) {
        如果(路径。开始与 (替代方案)) {
            KeycloakDeployment deployment = cache.get (领域);
            如果(null= = 部署) {
                输入流is = getClass()。getResourceAsStream (/tenant1-keycloak.json);
                返回KeycloakDeploymentBuilder.build (是);
            }
        }其他{
            输入流is = getClass()。getResourceAsStream (/default-keycloak.json);
            返回KeycloakDeploymentBuilder.build (是);
        }
    }

}

您还需要配置哪些KeycloakConfigResolver要与keycloak.config.resolver上下文参数在您的web.xml:

<网络应用>
    ...
    <上下文参数>
        <参数名称>keycloak.config.resolver</参数名称>
        <参数值>示例。基于路径的keycloakconfigresolver</参数值>
    </上下文参数>
</网络应用>

2.1.19。应用聚类

本章涉及支持部署到JBoss EAP、WildFly和JBoss AS的集群应用程序。

根据您的应用程序是否有以下几个选项可用:

  • 无状态或有状态

  • 可分发 (复制的http会话) 或不可分发

  • 依赖于负载均衡器提供的粘性会话

  • 托管在与Keycloak相同的域上

处理群集并不像常规应用程序那样简单。 主要是由于浏览器和服务器端应用程序 将请求发送到Keycloak,因此它不像在负载平衡器上启用粘性会话那么简单。

无状态令牌存储

默认情况下,由Keycloak保护的web应用程序使用HTTP会话来存储安全上下文。 这意味着你要么必须 启用粘性会话或复制HTTP会话。

作为在HTTP会话中存储安全上下文的替代方法,可以将适配器配置为将其存储在cookie中。 如果你愿意,这很有用 使您的应用程序无状态,或者如果您不想在HTTP会话中存储安全上下文。

要使用cookie存储来保存安全上下文,请编辑您的应用程序网络信息/Keycloak.json并添加:

令牌存储:饼干
的默认值令牌存储会话,它将安全上下文存储在HTTP会话中。

使用cookie存储的一个限制是,每个HTTP请求都会在cookie中传递整个安全上下文。 这可能会影响性能。

另一个小限制是对单点退出的支持有限。 如果您从 应用程序本身作为适配器将删除KEYCLOAK_ADAPTER_STATE cookie。 但是,从其他应用程序初始化的后通道注销不是 由Keycloak传播到使用cookie存储的应用程序。 因此,建议对访问令牌超时使用一个短值 (例如1分钟)。

某些负载平衡器不允许对粘性会话cookie名称或内容进行任何配置,例如Amazon ALB。 对于这些,建议设置shouldAttachRoute选项
相对URI优化

在Keycloak和应用程序托管在同一域中 (通过反向代理或负载平衡器) 的部署方案中,它可以是 方便在客户端配置中使用相对URI选项。

使用相对URI,URI被解析为相对于用于访问Keycloak的URL。

例如,如果您的应用程序的URL是https://acme.org/myappKeycloak的网址是https://acme.org/auth,那么您可以使用 重定向-uri/我的应用而不是https://acme.org/myapp

管理URL配置

可以在Keycloak管理控制台中配置特定客户端的管理员URL。 Keycloak服务器使用它向应用程序发送后端请求以执行各种任务,例如注销用户或推送撤销策略。

例如,反向通道注销的工作方式是:

  1. 用户从一个应用程序发送注销请求

  2. 应用程序向Keycloak发送注销请求

  3. Keycloak服务器使用户会话无效

  4. 然后,Keycloak服务器向具有与会话关联的管理url的应用程序发送反向通道请求

  5. 当应用程序收到注销请求时,它将使相应的HTTP会话无效

如果管理URL包含${application.session.host}它将被替换为与HTTP会话关联的节点的URL。

应用程序节点的注册

上一节介绍了Keycloak如何向与特定HTTP会话关联的节点发送注销请求。 但是,在某些情况下,admin可能希望将admin任务传播到所有已注册的群集节点,而不仅仅是其中一个。 例如,将新的 “非之前” 策略推送到应用程序或从应用程序中注销所有用户。

在这种情况下,Keycloak需要了解所有应用程序群集节点,因此它可以将事件发送给所有节点。 为此,我们支持自动发现机制:

  1. 当新的应用程序节点加入集群时,它会向Keycloak服务器发送注册请求

  2. 可以在配置的周期性间隔内将请求重新发送到Keycloak

  3. 如果Keycloak服务器在指定的超时时间内未收到重新注册请求,则它会自动取消注册特定节点

  4. 节点在发送取消注册请求时,也会在Keycloak中取消注册,这通常是在节点关闭或应用程序取消部署期间。 当未调用undeployment侦听器时,这可能无法正常工作,这导致需要自动取消注册

默认情况下,发送启动注册和定期重新注册是禁用的,因为它仅适用于某些群集应用程序。

要启用功能,请编辑网络信息/Keycloak.json文件为您的应用程序,并添加:

启动时的寄存器节点:,
寄存器节点周期:600,

这意味着适配器将在启动时发送注册请求,并每10分钟重新注册一次。

在Keycloak管理控制台中,您可以指定最大节点重新注册超时时间 (应大于寄存器节点周期来自 适配器配置)。 您还可以通过Adminstration控制台手动添加和删除中的群集节点,如果您不想依赖 在自动注册功能上,或者如果您想在不使用自动取消注册功能的情况下删除陈旧的应用程序节点。

在每个请求中刷新令牌

默认情况下,应用程序适配器仅在过期时刷新访问令牌。 但是,您也可以将适配器配置为在每个 请求。 这可能会影响性能,因为您的应用程序将向Keycloak服务器发送更多请求。

要启用功能,请编辑网络信息/Keycloak.json文件为您的应用程序,并添加:

始终刷新令牌:
这可能会对性能产生重大影响。 仅当您不能依赖反向通道消息传播注销时启用此功能,而不是在 政策。 要考虑的另一件事是,默认情况下,访问令牌的有效期很短,因此即使未传播注销,令牌也将在 注销的分钟。

2.2。JavaScript适配器

Keycloak带有一个客户端JavaScript库,可用于保护HTML5/JavaScript应用程序。 JavaScript适配器内置了对Cordova应用程序的支持。

可以直接从Keycloak服务器中检索该库,位于/auth/js/keycloak.js并且还作为ZIP存档分发。

最佳做法是直接从Keycloak服务器加载JavaScript适配器,因为升级服务器时会自动更新它。 如果将适配器复制到web应用程序,请确保仅在升级服务器后才升级适配器。

关于使用客户端应用程序需要注意的一件重要事情是,客户端必须是公共客户端,因为没有安全的方法来存储客户端 客户端应用程序中的凭据。 这使得确保为客户端配置的重定向uri是正确的和尽可能具体的非常重要。

要使用JavaScript适配器,您必须首先在Keycloak管理控制台中为您的应用程序创建一个客户端。 确保公众 选择为访问类型

您还需要配置有效的重定向uri网络起源。 尽可能具体,否则可能会导致安全漏洞。

创建客户端后,单击安装选项卡选择KeycloakOIDC JSON对于格式选项然后点击下载。 下载的 Keycloak。json文件应托管在您的web服务器上与您的HTML页面相同的位置。

或者,您可以跳过配置文件并手动配置适配器。

下面的示例演示如何初始化JavaScript适配器:

<html>
<头>
    <脚本 src=Keycloak></脚本>
    <脚本>
        函数 initKeycloak() {
            varKeycloak =新的Keycloak ();
            keycloak.init()。然后 (函数(已认证) {
                警报 (已认证? '已认证':'未认证');
            })。抓住(函数() {
                警报 ('初始化失败');
            });
        }
    </脚本>
</head>
<身体 onload=initKeycloak()>
    <!-- 你的页面内容到这里 -->
</body>
</html>

如果Keycloak。json文件在不同的位置,你可以指定它:

varKeycloak =新的Keycloak ('http:// localhost:8080/myapp/keycloak.json');

或者,您可以使用所需的配置传入JavaScript对象:

varKeycloak =新的Keycloak ({
    url:'http:// keycloak-server/auth',
    境界:'我的领域',
    clientId:'我的app'
});

默认情况下,要进行身份验证,您需要调用登录功能。 但是,有两个选项可以使适配器自动进行身份验证。 你 可以通过登录-必需或者检查-sso到init函数。登录-必需如果用户登录到Keycloak,将对客户端进行身份验证 如果没有,或者显示登录页面。检查-sso只有在用户已经登录的情况下,才会对客户端进行身份验证,如果用户没有登录,浏览器将 重定向回应用程序并保持未经身份验证。

您可以配置一个沉默 检查-sso选项。 启用此功能后,您的浏览器将不会完全重定向到Keycloak服务器并返回到您的应用程序,但是此操作将在隐藏的iframe中执行,因此,您的应用程序资源只需要在应用程序初始化时由浏览器加载和解析一次,而不是在从Keycloak重定向回您的应用程序后再次加载和解析。 这在SPAs (单页应用程序) 的情况下特别有用。

要启用沉默 检查-sso,您必须提供一个silentCheckSsoRedirectUriinit方法中的属性。 此URI需要是应用程序中的有效端点 (当然,它必须配置为Keycloak管理控制台中客户端的有效重定向):

Keycloak。init({
    onLoad:'检查-sso',
    silentCheckSsoRedirectUri: 窗口。位置。原点 +'/silent-check-sso.html'
})

成功检查您的身份验证状态并从Keycloak服务器检索令牌后,将在iframe中加载静默检查-sso重定向uri处的页面。 除了将接收到的令牌发送到主应用程序之外,它没有其他任务,应该只看起来像这样:

<html>
<正文>
    <脚本>
        父。邮件 (位置。href,位置。来源)
    </脚本>
</body>
</html>

请记住,指定位置的此页面必须由应用程序本身提供,并且不是JavaScript适配器的一部分!

沉默 检查-sso功能在某些现代浏览器中受到限制。 请看带跟踪保护部分的现代浏览器

启用登录-必需设置onLoad登录-必需并传递给init方法:

Keycloak。init({
    onLoad:'登录-必需'
})

用户通过身份验证后,应用程序可以通过将承载令牌包含在 授权头。 例如:

var 加载数据=函数() {
    文档。getElementById ('用户名')。innerText = keycloak。主题;

    varurl ='http:// localhost:8080/restful-service';

    var要求 =新的XMLHttpRequest();
    请求。打开 ('获取',网址,);
    请求。setRequestHeader ('接受','应用程序/json');
    请求。setRequestHeader ('授权','持票人'+ Keycloak。令牌);

    要求。onreadystatechange=函数() {
        如果(要求。就绪状态 = =4) {
            如果(要求。状态 = =200) {
                警报 ('成功');
            }其他 如果(要求。状态 = =403) {
                警报 ('禁止');
            }
        }
    }

    请求发送 ();
};

要记住的一件事是,默认情况下访问令牌的有效期很短,因此您可能需要在发送 请求。 你可以通过更新令牌方法。 的更新令牌方法返回一个承诺,仅当 令牌已成功刷新,如果没有,则向用户显示错误。例如:

密钥斗篷。更新令牌 (30)。然后 (函数() {
    loadData();
})。抓住(函数() {
    警报 ('无法刷新令牌');
});

2.2.1。会话状态iframe

默认情况下,JavaScript适配器创建一个隐藏的iframe,用于检测是否发生了单注销。 这不需要任何网络流量,而是通过查看特殊的状态cookie来检索状态。 可以通过设置来禁用此功能checkLoginIframe: false在传递给init方法。

你不应该依赖直接看这个cookie。 它的格式可以更改,并且还与Keycloak服务器的URL相关联,而不是 你的申请。

会话状态iframe功能在某些现代浏览器中受到限制。 请看带跟踪保护部分的现代浏览器

2.2.2。隐式和混合流

默认情况下,JavaScript适配器使用授权代码流。

通过此流程,Keycloak服务器将授权码而不是身份验证令牌返回给应用程序。 JavaScript适配器交换 的代码对于浏览器重定向回应用程序后的访问令牌和刷新令牌。

Keycloak还支持隐式访问令牌所在的流程 在使用Keycloak成功验证后立即发送。 这可能具有比标准流更好的性能,因为没有额外的 请求将代码交换为令牌,但当访问令牌到期时会产生影响。

但是,在URL片段中发送访问令牌可能是安全漏洞。 例如,令牌可以通过web服务器日志和或 浏览器历史记录。

要启用隐式流,您需要启用隐式流启用Keycloak管理控制台中客户端的标志。 您还需要传递参数流量有价值隐式init方法:

Keycloak。init({
    流量:'隐式'
})

需要注意的一点是,只提供了访问令牌,没有刷新令牌。 这意味着一旦访问令牌过期,应用程序 必须再次重定向到密钥斗篷以获取新的访问令牌。

Keycloak还支持混合动力流。

这要求客户端同时拥有启用标准流隐式流启用在管理控制台中启用了标志。 然后,Keycloak服务器将代码和令牌发送到您的应用程序。 访问令牌可以立即使用,而代码可以交换访问和刷新令牌。 与隐式流类似,混合流对性能有好处,因为访问令牌立即可用。 但是,令牌仍然在URL中发送,并且前面提到的安全漏洞可能仍然适用。

混合流中的一个优点是使刷新令牌可用于应用程序。

对于混合流,您需要传递参数流量有价值混合动力init方法:

Keycloak。init({
    流量:'混合动力'
})

2.2.3。与科尔多瓦的混合应用

Keycloak支持与开发的混合移动应用阿帕奇科尔多瓦。 JavaScript适配器有两种模式:科尔多瓦科尔多瓦-本地人:

默认为cordova,如果未配置任何适配器类型并且存在window.cordova,适配器将自动选择。 登录时,它会打开一个无应用浏览器这使用户可以与Keycloak进行交互,然后通过重定向到http:// 本地主机。 因此,您必须在管理控制台的客户端配置部分将此URL列为有效的重定向uri。

虽然此模式易于设置,但它也有一些缺点:

  • InApp浏览器是嵌入在应用程序中的浏览器,不是手机的默认浏览器。 因此,它将具有不同的设置,并且存储的凭据将不可用。

  • InApp浏览器也可能会更慢,尤其是在呈现更复杂的主题时。

  • 在使用此模式之前,需要考虑安全问题,例如应用程序可以访问用户的凭据,因为它可以完全控制浏览器呈现登录页面,因此不允许在您不信任的应用程序中使用它。

使用此示例应用程序来帮助您入门:https://github.com/keycloak/keycloak/tree/master/examples/cordova

替代模式科尔多瓦-本地人采取不同的方法。 它使用系统的浏览器打开登录页面。 用户通过身份验证后,浏览器会使用特殊的URL重定向回应用程序。 从那里,Keycloak适配器可以通过从URL中读取代码或令牌来完成登录。

您可以通过传递适配器类型来激活本机模式科尔多瓦-本地人init方法:

Keycloak。init({
    适配器:'科尔多瓦-本地人'
})

此适配器需要两个额外的插件:

链接到应用程序的技术细节在每个平台上都不同,需要特殊设置。 请参阅的Android和iOS部分deeplinks插件文档有关进一步的说明。

打开应用程序有不同种类的链接: 自定义方案 (即我的应用程序: // 登录或者安卓-应用: // com.example.myapp/https/example.com/login) 和通用链接 (iOS))/深度链接 (安卓)。 虽然前者更容易设置并且倾向于更可靠地工作,但后者提供了额外的安全性,因为它们是唯一的,并且只有域的所有者才能注册它们。 自定义网址在iOS上不推荐使用。 我们建议您使用通用链接,并结合带有自定义url链接的后备站点,以获得最佳可靠性。

此外,我们建议采取以下步骤来提高与Keycloak适配器的兼容性:

  • iOS上的通用链接似乎更可靠地与响应模式设置为查询

  • 要防止Android在重定向上打开您的应用程序的新实例,请将以下代码片段添加到config.xml:

<偏好 名称=安卓启动模式 =单件 />

有一个示例应用程序,显示如何使用本机模式:https://github.com/keycloak/keycloak/tree/master/examples/ 科尔多瓦-本地人

2.2.4。自定义适配器

有时有必要在默认情况下不支持的环境 (例如电容器) 中运行JavaScript客户端。 为了使在这类未知环境中使用JavasScript客户端成为可能,可以传递自定义适配器。 例如,第三方库可以提供这样的适配器,以使运行JavaScript客户端没有问题成为可能:

导入Keycloak从'Keycloak-js';
导入KeycloakCapacitorAdapter来自'Keycloak-电容器-适配器';

常量Keycloak =新的Keycloak ();

Keycloak。init({
    适配器: KeycloakCapacitorAdapter,
});

这个特定的包不存在,但它给出了一个很好的例子,说明如何将这样的适配器传递到客户端。

也可以制作自己的适配器,为此,您必须实现钥匙衣盒适配器接口。 例如,以下TypeScript代码可确保正确实现所有方法:

从 'keycloak-js' 导入Keycloak,{KeycloakAdapter};

// 实现 “keycloakadapter” 接口,以确保存在所有必需的方法。
常量MyCustomAdapter: KeycloakAdapter = {
    登录 (选项) {
        // 在这里编写自己的实现。
    }

    // 其他方法去这里...
};

常量Keycloak = 新Keycloak ();

Keycloak。init({
    适配器: 我的定制适配器,
});

当然,您也可以通过省略类型信息而在没有TypeScript的情况下执行此操作,但是确保正确实现接口将完全由您自己决定。

2.2.5。早期浏览器

JavaScript适配器依赖于Base64 (window.btoa和window.atob) 、HTML5历史API和可选的Promise API。 如果您需要支持没有这些可用的浏览器 (例如IE9),则需要添加polyfilpers。

示例polyfill库:

2.2.6。具有跟踪保护功能的现代浏览器

在某些浏览器的最新版本中,应用了各种cookie策略以防止第三方跟踪用户, 就像Chrome中的SameSite或完全阻塞的第三方cookie。 预计这些政策将变得更加平衡 随着时间的推移,其他浏览器更加严格和采用,最终导致第三方上下文中的cookie 完全不受浏览器支持和阻止。 受此影响的适配器功能可能会在 未来。

Javascript适配器依赖第三方cookie来获取会话状态iframe,沉默 检查-sso部分也适用于 常规 (非静默)检查-sso。 这些功能功能有限,或者根据如何完全禁用 浏览器对cookies有限制。 适配器尝试检测此设置并做出相应反应。

使用 “默认情况下为SameSite = Lax” 策略的浏览器

如果在Keycloak端以及应用程序上配置了SSL / TLS连接,则支持所有功能 侧。 见配置SSL / TLS。 受影响的是例如Chrome 版本84。

带有阻止的第三方cookie的浏览器

会话状态iframe不支持,如果JS适配器检测到此类浏览器行为,则会自动禁用。 这意味着适配器不能使用会话cookie进行单点注销检测,而必须纯粹依赖令牌。 这个 意味着当用户在另一个窗口中注销时,使用JavaScript适配器的应用程序将不会注销,直到它 尝试刷新访问令牌。 因此,建议将访问令牌寿命设置为相对较短的时间,因此 检测到注销的时间要早一点。 请看会话和令牌超时

沉默 检查-sso不支持并回退到常规 (非静音)检查-sso默认情况下。 这种行为可以 通过设置进行更改沉默检查sofallback: 假在传递给init方法。 在这种情况下,检查-sso 如果检测到限制性浏览器行为,将完全禁用。

常规检查-sso也受到影响。 由于不支持会话状态iframe,因此将额外重定向到Keycloak 必须在初始化适配器以检查用户的登录状态时进行。 这不同于标准行为,当 iframe用于判断用户是否登录,只有在注销时才执行重定向。

受影响的浏览器例如Safari从版本13.1开始。

2.2.7。JavaScript适配器参考

构造函数
新的Keycloak ();
新的Keycloak ('http:// localhost/keycloak.json');
新的Keycloak ({url:'http:// localhost/auth',境界:'我的领域',clientId:'我的app'});
属性
已认证

如果用户通过身份验证,否则。

令牌

可以在授权对服务的请求中的标头。

标记解析

作为JavaScript对象的解析令牌。

主题

用户id。

idToken

base64编码的ID令牌。

idTokenParsed

解析后的id令牌作为JavaScript对象。

realmAccess

与令牌关联的领域角色。

资源访问

与令牌关联的资源角色。

刷新令牌

base64编码的刷新令牌,可用于检索新令牌。

刷新解析

解析为JavaScript对象的刷新令牌。

timeSkew

浏览器时间和Keycloak服务器之间的估计时间差 (以秒为单位)。 这个值只是一个估计,但是准确的 在确定令牌是否过期时就足够了。

响应

init中传递的响应模式 (默认值为片段)。

流量

流动在init中传递。

适配器

允许您覆盖重定向和其他与浏览器相关的功能将由库处理的方式。 可用选项:

  • “默认”-库使用浏览器api进行重定向 (这是默认)

  • “cordova”-库将尝试使用InAppBrowser cordova插件加载keycloak登录/注册页面 (当库在cordova生态系统中工作时会自动使用)

  • “cordova-native”-库尝试使用手机的系统浏览器使用BrowserTabs cordova插件打开登录和注册页面。 这需要额外的设置才能重定向回应用程序 (请参阅与科尔多瓦的混合应用)。

  • 自定义-允许您实现自定义适配器 (仅适用于高级用例)

响应类型

响应类型发送给带有登录请求的Keycloak。 这是根据初始化期间使用的流值确定的,但是可以通过设置该值来覆盖。

方法
init (选项)

调用以初始化适配器。

选项是一个对象,其中:

  • useNonce-添加加密随机数,以验证身份验证响应是否与请求匹配 (默认为)。

  • onLoad-指定在加载时要执行的操作。 支持的值是登录-必需或者检查-sso

  • silentCheckSsoRedirectUri-如果onLoad设置为 'check-sso',则设置静默身份验证检查的重定向uri。

  • silentCheckSsoFallback-使下降到常规检查-sso沉默 检查-sso浏览器不支持 (默认为)。

  • 令牌-设置令牌的初始值。

  • refreshToken-设置刷新令牌的初始值。

  • idToken-为id令牌设置初始值 (仅与token或refreshToken一起)。

  • timeSkew-为本地时间和Keycloak服务器之间的skew设置初始值 (以秒为单位) (仅与token或refreshToken一起使用)。

  • checkLoginIframe-设置为启用/禁用监视登录状态 (默认为)。

  • checkLoginIframeInterval-设置检查登录状态的间隔 (默认为5秒)。

  • 响应模式-在登录请求时设置发送到Keycloak服务器的OpenID连接响应模式。 有效值为查询或者片段。 默认值为片段,这意味着成功身份验证后将Keycloak重定向到URL片段中添加了OpenID Connect参数的JavaScript应用程序。 这通常更安全,建议超过查询

  • 流-设置OpenID连接流。 有效值为标准,隐式或者混合动力

  • enableLogging-启用将消息从Keycloak记录到控制台 (默认为)。

  • pkceMethod-证明密钥代码交换的方法 (PKCE) 使用。 配置此值启用PKCE机制。 可用选项:

    • “S256” -- 基于SHA256的PKCE方法

  • messageReceiveTimeout-为等待来自Keycloak服务器的消息响应设置以毫秒为单位的超时。 例如,在第三方cookie检查期间等待消息时使用此方法。 默认值为10000。

返回初始化完成时解析的承诺。

登录 (选项)

重定向到登录表单上 (选项是带有redirectUri和/或提示字段的可选对象)。

选项是一个对象,其中:

  • redirectUri-指定登录后要重定向到的uri。

  • 提示-此参数允许稍微自定义Keycloak服务器端的登录流程。 例如,在值的情况下强制显示登录屏幕登录。 见参数转发部分 的详细信息和所有可能的值提示参数。

  • maxAge-仅在用户已经通过身份验证的情况下使用。 指定自用户身份验证发生以来的最长时间。 如果用户的身份验证时间超过maxAge,SSO将被忽略,他将需要再次进行身份验证。

  • loginHint-用于预先填写登录表单上的用户名/电子邮件字段。

  • scope-用于将scope参数转发到Keycloak登录端点。 使用以空格分隔的范围列表。 那些典型的 参考客户端范围在特定客户端上定义。 请注意,范围openid将是 始终由适配器添加到范围列表中。 例如,如果您输入范围选项地址电话,则请求 到Keycloak将包含scope参数scope = openid地址电话

  • idpHint-用于告诉Keycloak跳过显示登录页面,并自动重定向到指定的身份 提供者。 更多信息身份提供者文档

  • 动作-如果值为注册然后用户重定向到注册页面,否则重定向到登录页面。

  • 区域设置-根据以下内容设置 “ui_locales” 查询参数OIDC 1.0规范的3.1.2.1节

  • cordovaOptions-指定传递给Cordova在应用程序浏览器 (如果适用) 的参数。 选项隐藏位置不受这些论点的影响。 所有可用选项定义在https://cordova.apache.org/docs/en/latest/reference/ 科尔多瓦-插件-inappbrowser/。 使用示例:{缩放: “否”,硬件备份: “是”};

创建oginurl (选项)

返回登录表单上的URL (选项是带有redirectUri和/或提示字段的可选对象)。

Options是一个对象,它支持与函数相同的选项登录

注销 (选项)

重定向到注销。

选项是一个对象,其中:

  • redirectUri-指定注销后要重定向到的uri。

createLogoutUrl (选项)

返回注销用户的URL。

选项是一个对象,其中:

  • redirectUri-指定注销后要重定向到的uri。

注册 (选项)

重定向到注册表格。 使用选项操作 = 'register '登录的快捷方式

选项与登录方法相同,但 “操作” 设置为 “注册”

创建注册url (选项)

返回注册页面的url。 带有选项action = 'register '的createLoginUrl的快捷方式

选项与createLoginUrl方法相同,但 “操作” 设置为 “注册表”

会计管理 ()

重定向到帐户管理控制台。

创建帐户 (选项)

将URL返回到帐户管理控制台。

选项是一个对象,其中:

  • redirectUri-指定重定向回应用程序时要重定向到的uri。

hasRealmRole (角色)

如果令牌具有给定的领域角色,则返回true。

hasResourceRole (角色,资源)

如果令牌具有资源的给定角色 (资源是可选的,如果未指定使用clientId),则返回true。

加载用户配置文件 ()

加载用户配置文件。

返回用配置文件解析的承诺。

例如:

Keycloak。加载用户配置文件 ()
    。然后 (函数(简介) {
        警报 (JSON.stringify (配置文件,null,  ))
    })。抓住(函数() {
        警报 ('加载用户配置文件失败');
    });
Istokenexpended (最小有效性)

如果令牌在过期前的剩余时间少于最小有效性秒,则返回true (最小有效性是可选的,如果未指定0,则使用)。

更新令牌 (最小有效性)

如果令牌在最小有效秒内过期 (最小有效是可选的,如果未指定5则使用),则会刷新令牌。 如果会话状态iframe已启用,则还会检查会话状态。

返回一个用布尔值解析的promise,该布尔值指示令牌是否已刷新。

例如:

密钥斗篷。更新令牌 (5)
    。然后 (函数(刷新) {
        如果(刷新) {
            警报 ('Token被成功刷新');
        }其他{
            警报 ('令牌仍然有效');
        }
    })。抓住(函数() {
        警报 ('无法刷新令牌,或者会话已过期');
    });
clearToken()

清除身份验证状态,包括令牌。 如果应用程序检测到会话已过期,例如更新令牌失败,这可能很有用。

调用此会导致onauthlogoout回调侦听器被调用。

回调事件

适配器支持为某些事件设置回调侦听器。

例如:

Keycloak。一次成功=函数() {警报 ('已认证'); }

可用的事件有:

  • onReady (已认证)-初始化适配器时调用

  • onAuthSuccess-在用户成功验证时调用

  • Onauterror-如果身份验证期间出现错误,请调用。

  • Onauthrefreshuccess-在令牌刷新时调用

  • onAuthRefreshError-如果尝试刷新令牌时出现错误,则调用

  • Onauthlogoout-如果用户已注销,则调用 (仅在会话状态iframe已启用或处于Cordova模式时才调用)。

  • onTokenExpired-访问令牌过期时调用 如果刷新令牌可用,则可以使用updateToken刷新令牌,或者在不刷新令牌的情况下 (即,使用隐式流),您可以重定向到登录屏幕以获取新的访问令牌。

2.3。节点。js适配器

Keycloak提供了一个构建在连接为了保护服务器端JavaScript应用程序-目标是足够灵活地与框架集成,如快递。js

该库可以直接从Keycloak组织来源可在 GitHub

要使用Node.js适配器,首先您必须在Keycloak管理控制台中为您的应用程序创建一个客户端。 适配器支持公共、机密和仅承载访问类型。 选择哪一个取决于用例场景。

创建客户端后,单击安装选项卡,选择KeycloakOIDC JSON对于格式选项,然后单击下载。 下载的Keycloak。json文件应位于项目的根文件夹中。

2.3.1。安装

假设你已经安装了节点.js,为您的应用程序创建一个文件夹:

mkdir myapp & & cd myapp

使用npm初始化命令创建一个包。json为你的申请。 现在在依赖项列表中添加Keycloak connect适配器:

    “依赖关系”: {
        “Keycloak-连接”: “15.0.2”
    }

2.3.2。用法

实例化一个Keycloak类

Keycloak类提供了配置的中心点 并与您的应用程序集成。 最简单的创作 不涉及任何争论。

    var会话 = 要求 ('快速会议');
    varKeycloak = 需要 ('Keycloak-连接');

    var记忆商店 =新的session.MemoryStore();
    varKeycloak =新的Keycloak ({商店: memoryStore });

默认情况下,这将定位一个名为Keycloak。json旁边 用于初始化特定于keycloak的应用程序的主要可执行文件 设置 (公钥,领域名称,各种url)。 的Keycloak。json文件 是从Keycloak管理控制台获得的。

使用此方法实例化会导致所有合理的默认值 被使用。 作为替代方案,也可以提供配置 对象,而不是Keycloak。json文件:

    令kcConfig = {
        clientId:'我的客户端',
        仅承载:,
        服务器:'http:// localhost:8080/auth',
        境界:'我的领域',
        真实公钥:'米比扬布...'
    };

    让keycloak =新的Keycloak ({商店: memoryStore},kcConfig);

应用程序还可以通过使用以下方式将用户重定向到其首选的身份提供者:

    让keycloak =新的Keycloak ({商店: memoryStore,idpHint: myIdP},kcConfig);
配置web会话存储

如果您想使用web会话来管理 服务器端状态进行身份验证,需要初始化 Keycloak (&hellip; )至少有一个商店参数,传入实际 会话存储快速会议正在使用。

    var会话 = 要求 ('快速会议');
    var记忆商店 =新的session.MemoryStore();

    varKeycloak =新的Keycloak ({商店: memoryStore });
传递自定义范围值

默认情况下,范围值openid作为查询参数传递给Keycloak的登录URL,但是您可以添加一个额外的自定义值:

    varKeycloak =新的Keycloak ({范围:'离线访问'});

2.3.3。安装中间件

实例化后,将中间件安装到您的支持连接的应用程序中:

    varapp = express();

    app.use( keycloak.middleware() );

2.3.4。代理配置

如果应用程序在终止SSL连接的代理后面运行 必须根据代理背后的表达导。 使用不正确的代理配置会导致无效的重定向uri 正在生成。

配置示例:

    varapp = express();

    app.set ('信任代理',);

    app.use( keycloak.middleware() );

2.3.5。检查身份验证

要在访问资源之前检查用户是否经过身份验证, 简单地使用Keycloak。检查 ()。 它只会在用户已经登录的情况下进行身份验证。 如果用户未登录,则浏览器将被重定向回原始请求的URL并保持未经身份验证:

    app.get ('/检查-sso',keycloak.checkSso(),checkSsoHandler );

2.3.6。保护资源

简单身份验证

要强制要求用户在访问资源之前必须经过身份验证, 只需使用无参数版本的Keycloak。保护 ():

    app.get ('/抱怨',keycloak.protect(),contristhandler);
基于角色的授权

要保护具有当前应用程序角色的资源,请执行以下操作:

    app.get ('/特殊',Keycloak。保护 ('特殊'),特殊处理程序);

来保护具有应用程序角色的资源不同应用程序:

    app.get ('/特别',Keycloak。保护 ('其他-应用程序: 特殊'),特殊处理程序);

要保护具有领域角色的资源,请执行以下操作:

    app.get ('/管理员',Keycloak。保护 ('领域: 管理'),管理员);
基于资源的授权

基于资源的授权允许您保护资源及其特定方法/操作,** 基于Keycloak中定义的一组策略,从而将应用程序的授权外部化。 这是通过暴露一个Keycloak。执行者可以用来保护资源的方法。*

    app.get ('/Api/me',Keycloak。执行者 ('用户: 个人资料'),userProfileHandler);

Keycloak-执行者方法在两种模式下运行,具体取决于响应 _ 模式配置选项。

    app.get ('/Api/me',Keycloak。执行者 ('用户: 个人资料',{响应 _ 模式:'令牌'}),userProfileHandler);

如果响应 _ 模式设置为令牌,权限是代表发送给您的应用程序的承载令牌所代表的主题从服务器获得的。 在这种情况下,一个新的访问令牌由Keycloak发出,具有服务器授予的权限。 如果服务器未使用具有预期权限的令牌进行响应,则该请求将被拒绝。 使用此模式时,您应该能够从请求中获取令牌,如下所示:

    app.get ('/Api/me',Keycloak。执行者 ('用户: 个人资料',{响应 _ 模式:'令牌'}),函数(要求,资源) {
        var令牌 = req.kauth.grant.Access_token.Content;
        varpermissions = 令牌。授权? 令牌。授权。权限:未定义;

        // 显示用户配置文件
    });

当您的应用程序正在使用会话,并且您想从服务器缓存以前的决策,以及自动处理刷新令牌时,更喜欢这种模式。 此模式对于充当客户端和资源服务器的应用程序特别有用。

如果响应 _ 模式设置为权限(默认模式),服务器仅返回授予的权限列表,而不发出新的访问令牌。 除了不发出新令牌外,此方法还公开了服务器通过请求如下:

    app.get ('/Api/me',Keycloak。执行者 ('用户: 个人资料',{响应 _ 模式:'权限'}),函数(要求,资源) {
        varpermissions = req.permissions;

        // 显示用户配置文件
    });

不管响应 _ 模式在使用中,Keycloak。执行者方法将首先尝试检查发送到您的应用程序的承载令牌中的权限。 如果承载令牌已经携带了预期的权限,则不需要 与服务器交互以获得决策。 当您的客户端能够在访问受保护的资源之前以预期的权限从服务器获取访问令牌时,这一点特别有用,因此他们可以使用Keycloak授权服务提供的一些功能,例如增量授权,并避免在以下情况下向服务器发出额外请求Keycloak。执行者正在强制访问资源。

默认情况下,策略执行者将使用客户id定义给应用程序 (例如,通过Keycloak。json) 到 在Keycloak中引用支持Keycloak授权服务的客户端。 在这种情况下,客户端不能被公开给予 它实际上是一个资源服务器。

如果您的应用程序同时充当公共客户端 (前端) 和资源服务器 (后端),则可以使用以下配置来引用不同的 客户端在Keycloak与您想要执行的策略:

      Keycloak。执行者 ('用户: 个人资料',{资源 _ 服务器 _ 标识:'我的-apiserver'})

建议在Keycloak中使用不同的客户端来表示您的前端和后端。

如果您正在保护的应用程序已启用Keycloak授权服务,并且您已定义客户端凭据 在Keycloak。json,您可以将其他声明推送到服务器,并将其提供给您的策略以做出决策。 为此,您可以定义一个索赔配置选项,该选项期望函数返回一个JSON,你想推的声明:

      app.get ('/受保护/资源',Keycloak。执行者 (['资源: 视图','资源: 写'],{
          索赔:函数(请求) {
            返回{
              http.uri: [/受保护/资源],
              用户。代理:// 从请求中获取用户代理
            }
          }
        }),函数(要求,资源) {
          // 授予访问权限

有关如何配置Keycloak以保护您的应用程序资源的更多详细信息,请查看授权服务指南

高级授权

要基于URL本身的部分来保护资源,假设存在角色 对于每个部分:

    函数 保护部分(令牌,请求) {
      返回token.hasRole( request.params.section );
    }

    app.get ('/: 章节/: 页面',keycloak.protect( protectBySection),sectionHandler );

高级登录配置:

默认情况下,除非您的客户端仅承载,否则所有未经授权的请求都将重定向到Keycloak登录页面。 但是,机密或公共客户端可以同时托管可浏览端点和API端点。 防止未经身份验证的重定向 API请求并返回HTTP 401,您可以覆盖redirectToLogin函数。

例如,此覆盖检查URL是否包含/api/并禁用登录重定向:

    Keycloak。原型。重定向素=函数(要求) {
    varapiReqMatcher =/\/api\//;
    返回!apiReqMatcher.test(req.originalUrl | | req.url);
    };

2.3.7。附加网址

显式用户触发注销

默认情况下,中间件捕获对/注销通过以下方式发送用户 以Keycloak为中心的注销工作流 这可以通过指定注销 配置参数到中间件 ()呼叫:

    应用程序。使用 (keycloak。中间件 ({注销:'/注销'} ));

当调用用户触发的注销时,一个查询参数重定向 _ 网址可以通过:

https://example.com/logoff?redirect_url = https % 3A % 2F % 2Fexample.com % 3A3000% 2 ffloged % 2Fout

然后,此参数将用作OIDC注销端点的重定向url,用户将被重定向到 https://example.com/logged/out

Keycloak管理回调

此外,中间件支持从Keycloak控制台进行回调,以注销单个 会话或所有会话。 默认情况下,这些类型的管理员回调是相对的 到的根URL/但是可以通过提供一个管理员参数 到中间件 ()呼叫:

    应用程序。使用 (keycloak。中间件 ({管理员:'/回调'} );

2.4。mod_auth_openidc Apache HTTPD模块

mod_auth_openidc是一个用于OpenID连接的Apache HTTP插件。 如果您的语言/环境支持使用Apache HTTPD 作为代理,那么您可以使用mod_auth_openidc用OpenID Connect保护您的web应用程序。 此模块的配置 超出了本文档的范围。 请看mod_auth_openidc有关配置的更多详细信息,GitHub repo

要配置mod_auth_openidc你需要

  • client_id。

  • 客户秘密。

  • redirect_uri到您的应用程序。

  • Keycloak openid-配置网址

  • mod_auth_openidc特定的Apache HTTPD模块配置。

一个示例配置如下所示。

加载模块auth_openidc_module模块/mod_auth_openidc.so

服务器名称 $ {hospip}

<虚拟主机 *:80>

    服务器管理员网站管理员 @ 本地主机
    文档根/var/www/html

    # 这是mod_auth_openidc要求的
    Oidccryptomassphrase a-随机秘密使用的apache-oidc-and-balancer

    Oidcprovidermetaadataurl ${KC_ADDR}/auth/realms/${KC_REALM}/。知名/openid-配置

    OIDCClientID ${CLIENT_ID}
    OIDCClientSecret $ {客户端 _ 秘密}
    OIDCRedirectURI http:// ${HOSTIP}/${CLIENT_APP_NAME}/redirect_uri

    # 将prefered_username声明映射到REMOTE_USER环境变量
    Oidcremoteuser声明首选 _ 用户名

    <位置/$ {客户端 _ 应用 _ 名称}/>
        AuthType openid-连接
        要求有效-用户
    </位置>
</虚拟主机>

有关如何配置mod_auth_openidc的更多信息,请参见mod_auth_openidc 项目页面。

2.5。其他OpenID连接库

Keycloak可以通过提供的适配器来保护,这些适配器通常更易于使用,并提供与Keycloak的更好集成。 但是,如果适配器不适用于您的编程语言,框架或平台,则可以选择使用通用的OpenID Connect依赖方 (RP) 库。 本章描述特定于Keycloak的详细信息,不包含特定的协议详细信息。 有关更多信息,请参见OpenID连接规范OAuth2规范

2.5.1。端点

要理解的最重要的端点是知名配置端点。 它在Keycloak中列出了与OpenID Connect实现相关的端点和其他配置选项。 端点是:

/realms/{realm-name}/。知名/openid-configuration

要获取完整的URL,请添加Keycloak的基本URL并替换{领域名称}用你领域的名字。 例如:

http:// localhost:8080/auth/realms/master/.知名/openid-configuration

一些RP库从该端点检索所有必需的端点,但对于其他人,您可能需要单独列出端点。

授权端点
/领域/{领域名称}/协议/openid-connect/auth

授权端点执行最终用户的身份验证。 这是通过将用户代理重定向到此端点来完成的。

有关更多详细信息,请参见授权端点OpenID Connect规范中的部分。

令牌端点
/领域/{领域名称}/协议/openid-连接/令牌

令牌端点用于获取令牌。 可以通过交换授权码或根据使用的流程直接提供凭据来获得令牌。 令牌端点还用于在到期时获取新的访问令牌。

有关更多详细信息,请参见令牌端点OpenID Connect规范中的部分。

用户信息端点
/领域/{领域名称}/协议/openid-connect/userinfo

userinfo端点返回关于经过身份验证的用户的标准声明,并受到承载令牌的保护。

有关更多详细信息,请参见用户信息端点OpenID Connect规范中的部分。

注销端点
/领域/{领域名称}/协议/openid-连接/注销

注销端点注销经过身份验证的用户。

可以将用户代理重定向到端点,在这种情况下,活动用户会话将注销。 之后,用户代理将重定向回应用程序。

端点也可以由应用程序直接调用。 要直接调用此端点,需要包括刷新令牌以及对客户端进行身份验证所需的凭据。

证书端点
/领域/{领域名称}/协议/openid-connect/证书

证书端点返回由领域启用的公钥,编码为JSON Web密钥 (JWK)。 根据领域设置,可以启用一个或多个用于验证令牌的密钥。 有关更多信息,请参见服务器管理指南JSON Web密钥规范

内省终点
/领域/{领域名称}/协议/openid-connect/token/introspect

自省端点用于检索令牌的活动状态。 换句话说,您可以使用它来验证访问或刷新令牌。 它只能由机密客户端调用。

有关如何在此端点上调用的更多详细信息,请参见OAuth 2.0令牌内省规范

动态客户端注册端点
/领域/{领域名称}/客户端-注册/openid-连接

动态客户端注册端点用于动态注册客户端。

有关更多详细信息,请参见客户注册章节OpenID Connect动态客户端注册规范

令牌撤销端点
/realms/{realm-name}/protocol/openid-connect/revoke

令牌撤销端点用于撤销令牌。 此端点支持刷新令牌和访问令牌。

有关如何在此端点上调用的更多详细信息,请参见OAuth 2.0令牌撤销规范

设备授权端点
/领域/{领域名称}/协议/openid-connect/auth/设备

设备授权端点用于获取设备代码和用户代码。 它只能由机密客户端调用。

有关如何在此端点上调用的更多详细信息,请参见OAuth 2.0设备授权授权规范

反向通道身份验证端点
/领域/{领域名称}/协议/openid-connect/ext/ciba/auth

反向通道身份验证端点用于获取标识客户端发出的身份验证请求的auth_req_id。 它只能由机密客户端调用。

有关如何在此端点上调用的更多详细信息,请参见OpenID Connect客户端启动的反向通道身份验证流规范

2.5.2。验证访问令牌

如果您需要手动验证由Keycloak发布的访问令牌,则可以调用内省终点。 这种方法的缺点是您必须对Keycloak服务器进行网络调用。 这可能会很慢,可能会过载 服务器,如果您有太多的验证请求同时进行。 密钥斗篷发行的访问令牌是JSON网络令牌 (JWT)使用数字签名和编码JSON网络签名 (JWS)。 因为它们是以这种方式编码的,所以这允许您使用发行领域的公钥在本地验证访问令牌。 你可以硬编码 验证代码中的领域公钥,或者使用证书端点密钥ID (KID) 嵌入到 JWS。 根据您使用的语言编写代码,有许多第三方库可以帮助您进行JWS验证。

2.5.3。流动

授权代码

授权代码流将用户代理重定向到Keycloak。 一旦用户成功使用Keycloak进行身份验证, 创建授权码,并将用户代理重定向回应用程序。 然后,应用程序将授权码及其 从Keycloak获取访问令牌、刷新令牌和ID令牌的凭据。

该流针对web应用程序,但也建议用于本地应用程序,包括移动应用程序,在这些应用程序中可以嵌入 用户代理。

有关更多详细信息,请参阅授权代码流在OpenID Connect规范中。

隐式

隐式流重定向的工作原理类似于授权码流,但是访问令牌和ID令牌不是返回授权码 返回。 这减少了为访问令牌交换授权码的额外调用的需要。 但是,它不包括刷新 令牌。 这导致需要允许访问令牌具有长期限,这是有问题的,因为很难使这些无效。 或者 初始访问令牌过期后,需要新的重定向以获取新的访问令牌。 如果应用程序只想 对用户进行身份验证并处理注销本身。

还有一个混合流,其中返回访问令牌和授权码。

需要注意的一点是,隐式流和混合流都存在潜在的安全风险,因为访问令牌可能通过web服务器日志和 浏览器历史记录。 通过对访问令牌使用短过期,这在某种程度上有所缓解。

有关更多详细信息,请参阅隐式流在OpenID Connect规范中。

资源所有者密码凭据

资源所有者密码凭据 (在Keycloak中称为直接授予) 允许将用户凭据交换为令牌。 不推荐 使用这个流程,除非你绝对需要。 这可能有用的示例是遗留应用程序和命令行接口。

使用此流程有许多限制,包括:

  • 用户凭据公开给应用程序

  • 应用程序需要登录页面

  • 应用程序需要了解身份验证方案

  • 更改身份验证流程需要更改应用程序

  • 不支持身份经纪或社交登录

  • 不支持流 (用户自我注册,所需的操作等)

为了允许客户端使用资源所有者密码凭据,授予客户端必须具有启用直接访问授权选项已启用。

此流不包含在OpenID Connect中,而是OAuth 2.0规范的一部分。

有关更多详细信息,请参阅资源所有者密码证书授予OAuth 2.0规范中的章节。

使用卷曲的示例

下面的示例演示如何为领域中的用户获取访问令牌大师使用用户名用户和密码密码。 该示例使用 机密客户我的客户端:

卷曲 \
  -d "客户端 _ id = 我的客户端" \
  -d "client_secret = 40cc097b-2a57-4c17-b36a-8fdf3fc2d578" \
  -d "用户名 = 用户" \
  -d "密码 = 密码" \
  -d "grant_type = 密码" \
  “http:// localhost:8080/auth/realms/master/protocol/openid-connect/token”
客户端凭据

当客户端 (应用程序和服务) 想要代表自己而不是代表用户获得访问权限时,将使用客户端凭据。 这可以 例如,对于通常将更改应用于系统的后台服务,而不是特定用户,这很有用。

Keycloak支持客户端使用秘密或公钥/私钥进行身份验证。

此流不包含在OpenID Connect中,而是OAuth 2.0规范的一部分。

有关更多详细信息,请参阅客户凭证授予OAuth 2.0规范中的章节。

设备授权授权

设备授权授权由运行在连接互联网的设备上的客户端使用,这些设备的输入能力有限或缺乏合适的浏览器。 应用程序请求Keycloak设备代码和用户代码。 Keycloak创建设备代码和用户代码。 Keycloak向应用程序返回包括设备代码和用户代码的响应。 然后应用程序向用户提供用户代码和验证URI。 用户访问要通过使用其他浏览器进行身份验证的验证URI。 应用程序反复轮询Keycloak,直到Keycloak完成用户授权。 如果用户身份验证完成,应用程序将获取设备代码。 然后,应用程序使用设备代码及其凭据从Keycloak获取访问令牌,刷新令牌和ID令牌。

有关更多详细信息,请参阅OAuth 2.0设备授权授权规范

客户端发起的反向通道身份验证授权

客户端启动的反向通道身份验证授权由希望通过直接与OpenID提供程序通信而无需通过用户浏览器 (如OAuth 2.0的授权码授权) 来启动身份验证流程的客户端使用。

客户端请求Keycloak标识客户端发出的身份验证请求的auth_req_id。 Keycloak创建auth_req_id。

收到此auth_req_id后,此客户端需要反复轮询Keycloak以从Keycloak获取访问令牌,刷新令牌和ID令牌,以返回auth_req_id,直到用户通过身份验证为止。

如果客户端使用模式,它不需要重复轮询令牌端点,但是它可以等待Keycloak向指定的客户端通知端点发送的通知。 可以在Keycloak管理控制台中配置客户端通知端点。 CIBA规范中描述了客户通知端点的合同细节。

也请参考其他地方的Keycloak文档,如本指南的反向通道身份验证端点客户端发起的反向通道身份验证授予部分服务器管理指南。 有关FAPI CIBA合规性的详细信息,请参阅本指南的FAPI部分

2.5.4。重定向uri

使用基于重定向的流时,为客户端使用有效的重定向uri非常重要。 重定向uri应该尽可能具体。 这个 尤其适用于客户端 (公共客户端) 应用程序。 如果不这样做,可能会导致:

  • 打开重定向-这可以允许攻击者创建看起来像是来自您的域的欺骗链接

  • 未经授权的条目-当用户已经通过Keycloak进行身份验证时,攻击者可以使用未正确配置重定向uri的公共客户端,以在用户不知情的情况下通过重定向用户获得访问权限

在web应用程序的生产中始终使用https对于所有重定向uri。 不允许重定向到http。

还有一些特殊的重定向uri:

http:// 本地主机

此重定向URI对本机应用程序很有用,并允许本机应用程序在随机端口上创建web服务器,该端口可用于获取 授权码。 这个重定向uri允许任何端口。

urn:ietf:wg:oauth:2.0:oob

如果无法在客户端中启动web服务器 (或浏览器不可用),则可以使用特殊urn:ietf:wg:oauth:2.0:oob重定向uri。 使用此重定向uri时,Keycloak会在标题和页面上的框中显示一个带有代码的页面。 应用程序可以检测到浏览器标题已更改,或者用户可以手动将代码复制/粘贴到应用程序中。 有了这个重定向uri,用户也可以使用不同的设备来获取粘贴回应用程序的代码。

2.6。财务级API (FAPI) 支持

Keycloak使管理员更容易确保其客户端符合以下规范:

这种合规性意味着Keycloak服务器将验证需求 对于授权服务器,在规范中提到。 Keycloak适配器没有对FAPI的任何特定支持,因此在客户端 (应用程序) 上需要验证 可能仍然需要手动或通过其他一些第三方解决方案来完成。

2.6.1。FAPI客户端配置文件

为了确保您的客户端符合FAPI,您可以在您的领域中配置客户端策略,如服务器管理指南 并将它们链接到FAPI支持的全局客户端配置文件,这些配置文件在每个领域中自动可用。 您可以使用fapi-1-baseline或者fapi-1-advanced基于哪个FAPI的配置文件 你需要你的客户符合的个人资料。

如果你想使用推送的授权请求 (PAR),建议您的客户端使用 两者fapi-1-baseline简介和fapi-1-advanced对于PAR请求。 具体地说,fapi-1-baseline配置文件包含pkce-执行者执行者,这确保了 该客户端使用带有安全S256算法的PKCE。 FAPI高级客户端不需要这样做,除非它们使用PAR请求。

如果你想使用CIBA以符合FAPI的方式,确保您的客户端同时使用fapi-1-advancedfapi-ciba客户配置文件。 有必要使用fapi-1-advanced配置文件,或包含请求的执行程序的其他客户端配置文件,作为fapi-ciba个人资料仅包含CIBA特定的执行者。 在强制执行FAPI CIBA规范的要求时,需要更多的要求,例如强制执行机密客户端或证书绑定访问令牌。

2.6.2。巴西开放式银行金融级API安全配置文件

Keycloak符合巴西开放式银行金融级API安全配置文件1.0实施者草案1。 这个在某些要求上比FAPI 1高级规范,因此可能需要配置客户端策略 以更严格的方式来执行一些要求。 尤其是:

  • 如果您的客户端不使用PAR,请确保它使用加密的OIDC请求对象。 这可以通过使用带有安全请求对象执行器配置为需要加密启用。

  • 确保对于JWS,客户端使用PS256算法。 对于JWE,客户端应该使用RSA-OAEPA256GCM。 这可能需要在所有客户端设置在这些算法适用的地方。

2.6.3。TLS注意事项

在交换机密信息时,所有交互均应使用TLS (HTTPS) 进行加密。 此外,FAPI规范中有一些要求 使用的密码套件和TLS协议版本。 为了满足这些要求,您可以考虑配置允许的密码。 此配置可以在 KEYCLOAK_HOME/独立/配置/独立-*.xmlElytron子系统中的文件。 例如,此元素可以添加在tls服务器-ssl-上下文

<服务器-ssl-上下文 名称=kcSSLContext 想要-客户-身份验证= 协议=TLSv1.2 \
关键经理=kcKeyManager 信任经理=kcTrustManager \
密码套件过滤器=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 协议=TLSv1.2 />

对以下内容的引用kcKeyManagerkcTrustManager指对应的Keystore和Truststore。 有关更多详细信息,请参见Wildfly Elytron子系统的文档,以及 Keycloak文档的其他部分,如网络设置部分或者X.509认证部分

3. SAML

本节介绍如何使用Keycloak客户端适配器或通用的SAML保护应用程序和服务 SAML提供程序库

3.1。Java适配器

Keycloak为Java应用程序提供了一系列不同的适配器。 选择正确的适配器取决于目标平台。

3.1.1。通用适配器配置

Keycloak支持的每个SAML客户端适配器都可以由一个简单的XML文本文件配置。 这可能是什么样子:

<Keycloak-saml-适配器 xmlns=骨灰盒: Keycloak: saml: 适配器
                       xmlns:xsi=http:// www.w3.org/2001/XMLSchema-instance
                       xsi: 模式定位=urn:keycloak:saml: 适配器schema/ keycloak_saml_adapter_1_10.xsd>
    <SP 实体id=http:// localhost:8081/sales-post-sig/
        sslPolicy=外部
        名称idpolicyformat=urn:oasis: 名称: tc:SAML:1.1:nameid-格式: 未指定
        注销页=/注销。jsp
        强制认证=
        被动=
        关闭更改会话登录=
        自动检测beareronly=>
        <钥匙>
            <键 签名= >
                <密钥库 资源=/网络信息/密钥库.jks 密码=123号店面>
                    <私钥 别名=http:// localhost:8080/sales-post-sig/ 密码=测试123/>
                    <证书 别名=http:// localhost:8080/sales-post-sig//>
                </密钥库>
            </键>
        </键>
        <原则名称映射 政策=从 _ 名称 _ id/>
        <角色标识符>
            <属性 名称=角色/>
        </角色标识符>
        <角色映射提供程序 id=基于属性的角色映射器>
            <属性 名称=属性.资源.位置 =/WEB-INF/role-mappings.properties/>
        </角色映射提供程序>
        <国内流离失所者 实体id=国内流离失所者
             需要签名=>
        <单人签名服务 请求绑定=邮政
                             绑定url=http:// localhost:8081/auth/realms/demo/protocol/saml
                    />

            <单输出服务
                    请求绑定=邮政
                    响应绑定=邮政
                    postBindingUrl=http:// localhost:8081/auth/realms/demo/protocol/saml
                    重定向绑定url=http:// localhost:8081/auth/realms/demo/protocol/saml
                    />
            <钥匙>
                <键 签名=>
                    <密钥库 资源=/网络信息/密钥库.jks 密码=123号店面>
                        <证书 别名=演示/>
                    </密钥库>
                </键>
            </键>
        </IDP>
     </SP>
</Keycloak-saml-适配器>

这些配置开关中的一些可能是适配器特定的,而一些在所有适配器上是通用的。 对于Java适配器,您可以使用${&hellip; }作为系统属性替换的外壳。 例如${jboss.server.config.dir}

SP元素

下面是SP元素属性的解释:

<SP 实体id=sp
    sslPolicy=ssl
    名称idpolicyformat=格式
    强制认证=
    被动=
    保持断言=
    自动检测beareronly=>
...
</SP>
实体id

这是此客户端的标识符。 IdP需要此值来确定与之通信的客户是谁。 这个设置是必需

sslPolicy

这是适配器将实施的SSL策略。 有效值为:全部,外部,以及。 对于全部,所有请求都必须通过HTTPS进入。 对于外部,只有非私有ip地址必须通过HTTPS通过电线。 对于,不需要通过HTTPS进行请求。 这个设置是可选。 默认值为外部

名称idpolicyformat

SAML客户端可以请求特定的NameID主题格式。 如果需要特定格式,请填写此值。 它必须是一个标准的SAML格式标识符:urn:oasis: 名称: tc:SAML:2.0:nameid-格式: 瞬态。 这个设置是可选。 默认情况下,不请求特殊格式。

强制认证

SAML客户端可以请求重新验证用户,即使他们已经在IdP上登录。 将此设置为启用。 这个设置是可选。 默认值为

被动

SAML客户端可以请求永远不要要求用户进行身份验证,即使他们没有在IdP上登录。 将此设置为如果你想要这个。 不要与强制认证因为他们是相反的。 这个设置是可选。 默认值为

关闭更改会话登录

在某些平台上成功登录时,默认情况下会更改会话ID,以插入安全攻击向量。 将此更改为禁用此功能。 建议您不要将其关闭。 默认值为

自动检测beareronly

这应该设置为如果您的应用程序同时提供web应用程序和web服务 (例如SOAP或REST)。 它允许您将未经身份验证的web应用程序用户重定向到Keycloak登录页面, 但是发送一个HTTP401状态代码到未经身份验证的SOAP或REST客户端,因为他们不理解重定向到登录页面。 Keycloak根据典型的标头自动检测SOAP或REST客户端X-请求-与,肥皂或者接受。 默认值为

注销页

这将设置注销后要显示的页面。 如果页面是完整的URL,例如http://web.example.com/logout.html, 用户使用HTTP注销到该页面后被重定向302状态代码。 如果指定了没有方案部分的链接, 例如/注销。jsp,注销后显示页面,不管它是否位于保护区内 到安全约束web.xml中的声明,并且该页面相对于部署上下文根解析。

保持断言

此属性应设置为使适配器将断言的DOM表示形式存储在其 内部的原始形式SamlPrincipal与请求相关联。 断言文档可以使用 方法获取断言文档在校长内部。 这在重新播放签名断言时特别有用。 返回的文档是解析Keycloak服务器接收到的SAML响应生成的文档。 这个设置是可选它的默认值是(文档未保存在主体内部)。

服务提供商密钥和关键元素

如果IdP要求客户端应用程序 (或SP) 对其所有请求进行签名和/或如果IdP将加密断言,则必须定义用于执行此操作的密钥。 对于客户端签名的文档,您必须定义用于签名文档的私钥和公钥或证书。 对于加密,您只需要定义用于解密它的私钥。

有两种方式来描述你的钥匙。 它们可以存储在Java密钥库中,或者您可以直接在其中复制/粘贴密钥keycloak-saml.xmlPEM格式。

        <钥匙>
            <键 签名= >
               ...
            </键>
        </键>

钥匙元素有两个可选属性签名加密。 当设置为true时,这些将告诉适配器密钥将用于什么用途。 如果两个属性都设置为true,则该密钥将用于签名文档和解密加密的断言。 您必须将这些属性中的至少一个设置为true。

密钥库元素

钥匙元素您可以从Java密钥库加载密钥和证书。 这是在 a密钥库元素。

        <钥匙>
            <键 签名= >
                <密钥库 资源=/网络信息/密钥库.jks 密码=123号店面>
                    <私钥 别名=我的私人 密码=测试123/>
                    <证书 别名=菌体/>
                </密钥库>
            </键>
        </键>

以下是使用密钥库元素。

文件

密钥存储区的文件路径。 此选项为可选。 必须设置文件或资源属性。

资源

到密钥库的战争资源路径。 这是在对ServletContext.getResourceAsStream() 的方法调用中使用的路径。 此选项为可选。 必须设置文件或资源属性。

密码

密钥库的密码。 此选项为必需

如果要定义SP将用于对文档进行签名的密钥,则还必须指定对私钥的引用 和Java密钥库内的证书。 的私人钥匙证书上面示例中的元素定义了一个别名指向密钥或证书 在密钥库内。 密钥库需要额外的密码才能访问私钥。 在私人钥匙元素您必须在密码属性。

关键PEMS

钥匙元素您直接使用子元素声明密钥和证书 私人钥匙pem,PublicKeyPem,以及证书pem。 这些元素中包含的值必须符合PEM密钥格式。 如果您正在使用openssl或类似的命令行工具。

<钥匙>
   <键 签名=>
      <PrivateKeyPem>
         2341251234AB31234 = = 231BB998311222423522334
      </PrivateKeyPem>
      <证书pem>
         211111341251234AB31234 = = 231BB998311222423522334
      </CertificatePem>
   </键>
</键>
SP PrincipalNameMapping元素

此元素是可选的。 创建从以下方法获取的Java主体对象时HttpServletRequest.getUserPrincipal(),您可以定义由Principal.getName()方法。

<SP ...>
  <原则名称映射 政策=从 _ 名称 _ id/>
</SP>

<SP ...>
  <原则名称映射 政策=FROM_ATTRIBUTE 属性=电子邮件 />
</SP>

政策属性定义用于填充此值的策略。 此属性的可能值为:

从 _ 名称 _ id

此策略仅使用SAML主题值。 这是默认设置

FROM_ATTRIBUTE

这将从从服务器接收的SAML断言中声明的属性之一中提取值。 您需要指定要在属性XML属性。

RoleIdentifiers元素

角色标识符元素定义应该使用从用户接收到的断言中的SAML属性 作为用户的Java EE安全上下文中的角色标识符。

<角色标识符>
     <属性 名称=角色/>
     <属性 名称=成员/>
     <属性 名称=成员/>
</角色标识符>

默认情况下角色属性值转换为Java EE角色。 一些国内流离失所者使用成员或者成员属性断言。 您可以定义一个或多个属性元素来指定哪些SAML属性必须转换为角色。

角色映射提供程序元素

角色映射提供程序是一个可选元素,它允许指定的id和配置 组织。Keycloak。适配器。saml。角色映射提供程序SAML适配器要使用的SPI实现。

当Keycloak用作IDP时,可以使用内置的角色映射器来映射任何角色,然后再将它们添加到 SAML断言。 但是,SAML适配器可用于将SAML请求发送到第三方idp,在这种情况下,它可能是 必须将从断言中提取的角色映射到SP所需的不同角色集。 的 角色映射提供程序SPI允许配置可插拔角色映射器,可用于执行必要的 映射。

提供程序的配置如下所示:

...
<角色标识符>
    ...
</角色标识符>
<角色映射提供程序 id=基于属性的角色映射器>
    <属性 名称=属性.资源.位置 =/WEB-INF/role-mappings.properties/>
</角色映射提供程序>
<国内流离失所者>
    ...
</IDP>

id属性标识要使用哪个已安装的提供程序。 的财产子元素可以多次使用 为提供程序指定配置属性。

基于属性的角色映射提供程序

Keycloak包括一个角色映射提供程序执行角色映射的实现使用属性文件。 这个 提供者由id标识基于属性的角色映射器并由org.keycloak.适配器.saml.PropertiesBasedRoleMapper 类。

此提供程序依赖于两个配置属性,可用于指定属性文件 那将被使用。 首先,它检查是否属性.文件.位置已指定属性,使用配置的 值来定位属性文件系统中的文件。 如果未找到配置的文件,则提供程序会抛出 运行时间异常。 下面的代码片段显示了提供程序使用属性.文件.配置 加载选项角色。属性文件来自/选择/映射器/文件系统中的目录:

    <角色映射提供程序 id=基于属性的角色映射器>
        <属性 名称=属性.文件.位置 =/opt/映射器/角色。属性/>
    </角色映射提供程序>

如果属性.文件.位置配置尚未设置,提供程序检查属性.资源.位置 属性,使用配置的值加载属性文件来自战争资源。 如果此配置属性为 同样不存在,提供程序尝试从/WEB-INF/role-mappings.properties默认情况下。 加载文件失败 从资源将导致提供者抛出一个运行时间异常。 下面的代码片段显示了一个提供程序的示例 使用属性.资源.位置加载角色。属性来自应用程序的文件/网络信息/conf/目录:

    <角色映射提供程序 id=基于属性的角色映射器>
        <属性 名称=属性.资源.位置 =/WEB-INF/conf/角色。属性/>
    </角色映射提供程序>

属性文件可以同时包含角色和主体作为键,以及由逗号分隔的零个或多个角色的列表 作为价值观。 当被调用时,实现会遍历从断言和检查中提取的角色集, 对于每个角色,如果存在映射 如果角色映射到空角色,则将其丢弃。 如果它映射到一组更多的矿石 不同的角色,则在结果集中设置这些角色。 如果找不到角色的映射,则按原来的方式包含 在结果集中。

处理完角色后,实现将检查从断言中提取的主体是否包含条目 属性文件。 如果存在主体的映射,则将列为值的任何角色添加到结果集中。 这个 允许将额外的角色分配给委托人。

例如,假设提供程序已配置了以下属性文件:

roleA = 劳力士,罗利
roleB =

kc_user = 角色

如果校长kc_user是从带有角色的断言中提取的罗莱,roleBroleC,最终的一组角色 分配给校长的将是roleC,劳力士,罗利罗莱兹因为罗莱正在映射到两者中劳力士罗利,roleB被映射到一个空角色-因此被丢弃,roleC按原来的方式使用,最后是一个额外的角色 被添加到kc_user校长 (罗莱兹)。

注意: 要在角色名称中使用空格进行映射,请使用unicode替换空格。 例如,传入的 “角色a” 将显示为:

角色 = 劳力士,罗利
添加您自己的角色映射提供程序

要添加自定义角色映射提供程序,只需实现组织。Keycloak。适配器。saml。角色映射提供程序SPI。 有关更多详细信息,请参见SAML角色映射SPI中的部分服务器开发指南

国内流离失所者要素

IDP元素中的所有内容都描述了SP正在与之通信的身份提供程序 (身份验证服务器) 的设置。

<国内流离失所者 实体id=国内流离失所者
     需要签名=
     签名算法=Rsa _ sha1
     签名认证方法=Http://www.w3.org/2001/10/xml-exc-c14n #>
...
</IDP>

以下是您可以在国内流离失所者元素声明。

实体id

这是IDP的发行者ID。 这个设置是必需

需要签名

如果设置为,客户端适配器将对发送到IDP的每个文档进行签名。 此外,客户希望IDP将签署发送给它的任何文件。 此开关为所有请求和响应类型设置默认值,但是稍后您将看到您对此有一些细粒度的控制。 这个设置是可选并将默认为

签名算法

这是IDP期望签名文档使用的签名算法。 允许的值为:Rsa _ sha1,Rsa _ sha256,Rsa _ sha512,以及Dsa _ sha1。 这个设置是可选 默认为Rsa _ sha256

签名认证方法

这是IDP期望签名文档使用的签名规范化方法。 这个设置是可选。 默认值为Http://www.w3.org/2001/10/xml-exc-c14n #对大多数国内流离失所者来说应该是好的。

元数据库

用于检索IDP元数据的URL,目前仅用于定期获取签名和加密密钥,这些密钥允许在IDP上循环这些密钥,而无需在SP侧进行手动更改。

IDP允许时钟倾斜子元素

允许时钟倾斜可选子元素定义IDP和SP之间允许的时钟偏斜。 默认值为0。

<允许时钟倾斜 单位=毫秒>3500</允许时钟倾斜>
单位

可以定义附加到该元素值的时间单位。 允许的值是微秒、毫秒、分钟、纳秒和秒。 这是可选。 默认值为

IDP单一签名服务子元素

单一签名服务子元素定义IDP的登录SAML端点。 客户端适配器将发送请求 到要登录时通过此元素中的设置格式化的IDP。

<单人签名服务 签名请求=
                     验证响应性质=
                     请求绑定=邮政
                     绑定url=url/>

以下是您可以在此元素上定义的配置属性:

签名请求

客户端应该签署authn请求吗? 这个设置是可选。 默认为IDP需要签名元素值为。

验证响应性质

客户是否应该期望IDP签署从auhtn请求发回的断言响应文档? 此设置可选。 默认为IDP需要签名元素值为。

请求绑定

这是用于与IDP通信的SAML绑定类型。 这个设置是可选。 默认值为邮政,但您可以将其设置为重定向也是。

响应绑定

SAML允许客户端请求它希望使用authn响应的绑定类型。 这个的值可以是邮政或者重定向。 这个设置是可选。 默认情况下,客户端不会为响应请求特定的绑定类型。

断言消费者服务url

IDP登录服务应向其发送响应的断言消费者服务 (ACS) 的URL。 这个设置是可选。 默认情况下,它是未设置的,依赖于IdP中的配置。 设置时,它必须以/saml,例如http://sp.domain.com/my/endpoint/for/saml。 值 此属性的发送断言消费者服务urlSAML的属性授权请求消息。 此属性通常伴随着响应绑定属性。

绑定url

这是客户端将向其发送请求的IDP登录服务的URL。 这个设置是必需

IDP单线服务子元素

单输出服务子元素定义IDP的注销SAML端点。 客户端适配器将发送请求 要注销时,通过此元素中的设置格式化的IDP。

<单输出服务 验证请求签名=
                     验证响应性质=
                     签名请求=
                     信号响应=
                     请求绑定=重定向
                     响应绑定=邮政
                     postBindingUrl=posturl
                     重定向绑定url=重定向>
签名请求

客户应该对它向国内流离失所者提出的注销请求进行签名吗? 这个设置是可选。 默认为IDP需要签名元素值为。

信号响应

客户端是否应该签署它发送给IDP请求的注销响应? 这个设置是可选。 默认为IDP需要签名元素值为。

验证请求签名

客户是否应该期望来自IDP的签名注销请求文档? 这个设置是可选。 默认为IDP需要签名元素值为。

验证响应性质

客户是否应该期望来自IDP的签名注销响应文档? 这个设置是可选。 默认为IDP需要签名元素值为。

请求绑定

这是用于将SAML请求传达给IDP的SAML绑定类型。 这个设置是可选。 默认值为邮政,但您也可以将其设置为重定向。

响应绑定

这是用于将SAML响应传达给IDP的SAML绑定类型。 这个的值可以是邮政或者重定向。 这个设置是可选。 默认值为邮政,但您可以将其设置为重定向也是。

postBindingUrl

这是使用POST绑定时IDP注销服务的URL。 这个设置是必需如果使用邮政绑定。

重定向绑定url

这是使用重定向绑定时IDP注销服务的URL。 这个设置是必需如果使用重定向绑定。

IDP密钥子元素

IDP的密钥子元素仅用于定义证书或公钥,以用于验证IDP签名的文档。 它的定义方式与SP的密钥元素。 但同样,您只需定义一个证书或公钥引用。 请注意,如果IDP和SP都是通过以下方式实现的 Keycloak服务器和适配器分别不需要指定用于签名验证的密钥,请参见下文。

可以配置SP以获取用于IDP签名验证的公钥 如果SP和IDP都是 由Keycloak实现。 这是通过删除密钥中签名验证密钥的所有声明来完成的 子元素。 如果密钥子元素将保持为空,则可以省略 完全。 然后,SP从SAML描述符中自动获取密钥, 其位置是从在 IDP单一签名服务子元素。 通常用于SAML描述符检索的HTTP客户端的设置 不需要其他配置,但是可以在 IDP HttpClient子元素

也可以指定多个密钥用于签名验证。 这是通过声明多个关键元素来完成的 在具有签名属性设置为。 这对于例如在旋转IDP签名键的情况下很有用: 有 通常是签署新的SAML协议消息和断言的过渡期 使用新密钥,但仍应接受以前密钥签名的密钥。

无法将Keycloak配置为同时获取密钥 自动进行签名验证,并定义其他静态签名 验证密钥。

       <国内流离失所者 实体id=国内流离失所者>
            ...
            <钥匙>
                <键 签名=>
                    <密钥库 资源=/网络信息/密钥库.jks 密码=123号店面>
                        <证书 别名=演示/>
                    </密钥库>
                </键>
            </键>
        </IDP>
IDP HttpClient子元素

HttpClient可选子元素定义使用的HTTP客户端的属性 用于自动获取包含用于IDP签名的公共密钥的证书 在以下情况下通过IDP的SAML描述符进行验证 已启用

<HttpClient 连接游泳池大小=10
            禁用信任管理器=
            allowAnyHostname=
            客户密钥库=类路径: 密钥库。jks
            客户密钥存储密码=pwd
            信任商店=类路径: 信任商店。jks
            信任存储密码=pwd
            代理=http:// 代理/
            套盘超时=5000
            连接超时=6000
            连接ttl=500 />
连接游泳池大小

此配置选项定义应汇集到Keycloak服务器的连接数量。 这是可选。 默认值为10

禁用信任管理器

如果Keycloak服务器需要HTTPS,并且此配置选项设置为您不必指定信任商店。 此设置应仅在开发过程中使用,并且从不在生产中,因为它将禁用SSL证书的验证。 这是可选。 默认值为

allowAnyHostname

如果Keycloak服务器需要HTTPS,并且此配置选项设置为 Keycloak服务器的证书通过truststore进行验证, 但是主机名验证没有完成。 此设置应仅在开发过程中使用,并且从不在生产中 因为它将部分禁用SSL证书的验证。 这种设置在测试环境中可能很有用。 这是可选。 默认值为

信任商店

该值是truststore文件的文件路径。 如果您将路径前缀为类路径:,则将从部署的类路径中获取truststore。 用于向Keycloak服务器传出HTTPS通信。 客户端发出HTTPS请求需要一种方法来验证他们正在与之对话的服务器的主机。 这就是trustore所做的。 密钥库包含一个或多个受信任的主机证书或证书颁发机构。 您可以通过提取Keycloak服务器的SSL密钥库的公共证书来创建此信任库。 这是必需除非禁用信任管理器

信任存储密码

信任商店的密码。 这是必需如果信任商店设置,并且信任商店需要密码。

客户密钥库

这是密钥库文件的文件路径。 当适配器向Keycloak服务器发出HTTPS请求时,此密钥库包含双向SSL的客户端证书。 这是可选

客户密钥存储密码

客户端密钥库和客户端密钥的密码。 这是必需如果客户密钥库已设置。

代理

用于HTTP连接的HTTP代理的URL。 这是可选

套盘超时

建立连接后等待数据的套接字超时,单位为毫秒。 两个数据包之间的最长不活动时间。 超时值为零被解释为无限超时。 负值被解释为未定义 (如果适用,系统默认值)。 默认值为-1。 这是可选

连接超时

与远程主机建立连接的超时时间 (毫秒)。 超时值为零被解释为无限超时。 负值被解释为未定义 (如果适用,系统默认值)。 默认值为-1。 这是可选

连接ttl

客户端的连接生存时间 (以毫秒为单位)。 小于或等于零的值被解释为无限值。 默认值为-1。 这是可选

3.1.2。JBoss EAP/WildFly适配器

为了保护部署在JBoss EAP或WildFly上的WAR应用程序,您必须安装和配置Keycloak SAML适配器子系统。

然后你提供一个keycloak配置,/WEB-INF/keycloak-saml.xml文件在您的战争中,并将auth-方法更改为KEYCLOAK-SAML在web.xml中。 本节介绍了这两种方法。

适配器安装

每个适配器都是Keycloak下载站点上的单独下载。

我们只测试和维护最新版本的WildFly版本的适配器。 一旦新版本 WildFly已发布,当前的适配器已被弃用,并且在下一次WildFly发布后将删除对它们的支持。 另一种选择是将您的应用程序从WildFly切换到JBoss EAP,因为JBoss EAP适配器支持更长的时间。

安装在WildFly 9或更高版本或JBoss EAP 7上:

$ cd $ WILDFLY_HOME
$ 解压缩keycloak-saml-wildfly-adapter-dist.zip

安装在JBoss EAP 6.x:

$ cd $ jbos_home
$ 解压缩keycloak-saml-eap6-adapter-dist.zip

这些zip文件在您的WildFly或JBoss EAP发行版中创建新的JBoss模块特定于WildFly/JBoss EAP SAML适配器。

添加模块后,必须在应用程序服务器的服务器配置中启用Keycloak SAML子系统:域。xml或者独立。xml

有一个CLI脚本可以帮助您修改服务器配置。 启动服务器,从服务器的bin目录运行脚本:

野蝇11或更新
$ cd $ jbos_home
$。/bin/jboss-cli.sh -c -- file = bin/adapter-elytron-install-saml.cli
10岁及以上的野蝇
$ cd $ jbos_home
$ /bin/boss-cli.sh -c -- file = bin/adapter-install-saml.cli
也可以在WildFly 11或更高版本上使用旧版非Elytron适配器,这意味着您可以使用adapter-install-saml.cli 即使在那些版本上。 但是,我们建议使用较新的Elytron适配器。

该脚本将添加扩展,子系统和可选的安全域,如下所述。

<服务器 xmlns=urn:jboss: 域: 1.4>

    <扩展>
        <扩展 模块=组织。Keycloak-saml-适配器-子系统/>
          ...
    </扩展>

    <个人资料>
        <子系统 xmlns=urn:jboss: 域: keycloak-saml:1.1/>
         ...
    </个人资料>

Keycloak当您需要创建安全上下文时,安全域应与ejb和其他组件一起使用 在要传播到您正在调用的ejb (其他EE组件) 的安全web层中。 否则,此配置是可选的。

<服务器 xmlns=urn:jboss: 域: 1.4>
 <子系统 xmlns=urn:jboss: 域: 安全性: 1.2>
    <安全域>
...
      <安全域 名称=Keycloak>
         <身份验证>
           <登录模块 代码=org.keycloak.适配器.jboss.KeycloakLoginModule
                         旗帜=必需/>
          </身份验证>
      </安全域>
    </安全域>

安全上下文会自动传播到EJB层。

JBoss SSO

WildFly内置了对部署到同一WildFly的web应用程序的单点登录的支持 实例。 使用Keycloak时不应启用此功能。

为JSESSIONID cookie设置相同的值

浏览器计划为SameSiteCookie的属性Lax。 此设置意味着 只有当请求起源于同一域时,cookie才会被发送到应用程序。 这种行为会影响 SAML POST绑定可能变得不起作用。 为了保留SAML适配器的全部功能,我们建议 设置SameSite值至对于JSESSIONID由您的容器创建的cookie。 不这样做可能会导致 重置容器的会话与每个请求到Keycloak。

为了避免设置SameSite属性为,考虑切换到重定向绑定 如果可以接受,或者使用不需要此解决方法的OIDC协议。

要设置SameSite值至对于JSESSIONIDcookie在Wildfly/EAP中,添加文件undertow-handlers.conf 以下内容对网络信息您的应用程序的目录。

samesite-cookie (模式 = 无,cookie-模式 = JSESSIONID)

此配置的支持在19.1.0版的Wildfly中可用。

3.1.3。从RPM安装JBoss EAP适配器

从RPM安装EAP 7适配器:

使用Red Hat Enterprise Linux 7,术语通道被术语存储库所取代。 在这些说明中,仅使用术语存储库。

您必须先订阅JBoss EAP 7存储库,然后才能从RPM安装EAP 7适配器。

先决条件
  1. 确保您的红帽企业Linux系统已使用红帽订阅管理器注册到您的帐户。 有关更多信息,请参见红帽订阅管理文档

  2. 如果您已经订阅了另一个JBoss EAP存储库,则必须首先取消订阅该存储库。

对于Red Hat Enterprise Linux 6,7: 使用Red Hat订阅管理器,使用以下命令订阅WildFly 23存储库: 根据您的红帽企业Linux版本,将 <RHEL_VERSION> 替换为6或7。

$ sudo订阅-管理器存储-启用 = jb-eap-7-for-rhel-<RHEL_VERSION>-服务器-rpms

对于Red Hat Enterprise Linux 8: 使用Red Hat订阅管理器,使用以下命令订阅WildFly 23存储库:

$ sudo订阅-管理器存储-启用 = jb-eap-23-for-rhel-8-x86_64-rpms-启用 = rhel-8-for-x86_64-baseos-rpms-启用 = rhel-8-for-x86_64-appstream-rpms

使用以下命令安装SAML的EAP 7适配器:

$ sudo yum安装eap7-keycloak-saml-adapter-sso7_4

或使用以下用于Red Hat Enterprise Linux 8:

$ sudo dnf安装eap7-keycloak-adapter-sso7_4
RPM安装的默认EAP_HOME路径为/opt/rh/eap7/root/usr/share/wildfly。

运行相应的模块安装脚本。

对于SAML模块,输入以下命令:

$ $ EAP_HOME/bin/jboss-cli.sh -c-file = $ EAP_HOME/bin/adapter-install-saml.cli

您的安装完成。

从RPM安装EAP 6适配器:

使用Red Hat Enterprise Linux 7,术语通道被术语存储库所取代。 在这些说明中,仅使用术语存储库。

您必须先订阅JBoss EAP 6存储库,然后才能从RPM安装EAP 6适配器。

先决条件
  1. 确保您的红帽企业Linux系统已使用红帽订阅管理器注册到您的帐户。 有关更多信息,请参见红帽订阅管理文档

  2. 如果您已经订阅了另一个JBoss EAP存储库,则必须首先取消订阅该存储库。

使用Red Hat订阅管理器,使用以下命令订阅JBoss EAP 6存储库: 根据您的红帽企业Linux版本,将 <RHEL_VERSION> 替换为6或7。

$ sudo订阅-管理器存储-启用 = jb-eap-6-for-rhel-<RHEL_VERSION>-服务器-rpms

使用以下命令安装SAML的EAP 6适配器:

$ sudo yum安装keycloak-saml-adapter-sso7_4-eap6
RPM安装的默认EAP_HOME路径为/opt/rh/eap6/root/usr/share/wildfly。

运行相应的模块安装脚本。

对于SAML模块,输入以下命令:

$ $ EAP_HOME/bin/jboss-cli.sh -c-file = $ EAP_HOME/bin/adapter-install-saml.cli

您的安装完成。

每个战争配置

本节介绍如何通过在WAR包中添加配置和编辑文件来直接保护WAR。

你必须做的第一件事是创建一个keycloak-saml.xml中的适配器配置文件网络信息你的战争目录。 此配置文件的格式在通用适配器配置节。

接下来,您必须设置auth-方法Keycloak-SAMLweb.xml。 您还必须使用标准servlet安全性来指定url上的基于角色的约束。 这里有一个例子web.xml文件:

<网络应用 xmlns=http://java.sun.com/xml/ns/javaee
      xmlns:xsi=http:// www.w3.org/2001/XMLSchema-instance
      xsi: 模式定位=http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ web-app_3_0.xsd
      版本=3.0>

        <模块名称>客户门户</模块名称>

    <安全约束>
        <网络资源收集>
            <web-资源-名称>管理员</web-资源-名称>
            <url-模式>/管理员/*</url-模式>
        </网络资源收集>
        <授权约束>
            <角色名称>管理员</角色名称>
        </auth-constraint>
        <用户数据约束>
            <运输-保证>机密</运输-保证>
        </用户数据约束>
    </安全约束>
    <安全约束>
        <网络资源收集>
            <web-资源-名称>客户</web-资源-名称>
            <url-模式>/客户/*</url-模式>
        </网络资源收集>
        <授权约束>
            <角色名称>用户</角色名称>
        </auth-constraint>
        <用户数据约束>
            <运输-保证>机密</运输-保证>
        </用户数据约束>
    </安全约束>

    <登录配置>
        <身份验证方法>Keycloak-SAML</auth-方法>
        <境界-名称>目前忽略了这一点</领域名称>
    </登录配置>

    <安全-角色>
        <角色名称>管理员</角色名称>
    </安全角色>
    <安全-角色>
        <角色名称>用户</角色名称>
    </安全角色>
</网络应用>

auth-方法设置。

通过Keycloak SAML子系统保护战争

你不必打开一场战争就可以用Keycloak来保护它。 或者,您可以通过Keycloak SAML适配器子系统从外部保护它。 虽然您不必将KEYCLOAK-SAML指定为auth-方法,您仍然必须定义安全约束web.xml。 然而,你不必创建一个WEB-INF/keycloak-saml.xml文件。 此元数据是在服务器的XML中定义的域。xml或者独立。xml子系统配置部分。

<扩展>
  <扩展 模块=组织。Keycloak-saml-适配器-子系统/>
</扩展>

<个人资料>
  <子系统 xmlns=urn:jboss: 域: keycloak-saml:1.1>
    <安全部署 名称=战争模块名称。战争>
      <SP 实体id=应用程序URL>
        ...
      </SP>
    </安全部署>
  </子系统>
</个人资料>

安全部署 名称属性标识您想要保护的战争。 它的值是模块名称中定义web.xml。战争附加。 其余配置使用与keycloak-saml.xml中定义的配置通用适配器配置

配置示例:

<子系统 xmlns=urn:jboss: 域: keycloak-saml:1.1>
  <安全部署 名称=saml-post-encryption.war>
    <SP 实体id=http:// localhost:8080/sales-post-enc/
        sslPolicy=外部
        名称idpolicyformat=urn:oasis: 名称: tc:SAML:1.1:nameid-格式: 未指定
        注销页=/注销。jsp
        强制认证=>
      <钥匙>
        <键 签名= 加密=>
          <密钥库 资源=/网络信息/密钥库.jks 密码=123号店面>
            <私钥 别名=http:// localhost:8080/sales-post-enc/ 密码=测试123/>
            <证书 别名=http:// localhost:8080/sales-post-enc//>
          </密钥库>
        </键>
      </键>
      <原则名称映射 政策=从 _ 名称 _ id/>
      <角色标识符>
        <属性 名称=角色/>
      </角色标识符>
      <国内流离失所者 实体id=国内流离失所者>
        <单人签名服务 签名请求=
            验证响应性质=
            请求绑定=邮政
            绑定url=http:// localhost:8080/auth/realms/saml-demo/protocol/saml/>

        <单输出服务
            验证请求签名=
            验证响应性质=
            签名请求=
            信号响应=
            请求绑定=邮政
            响应绑定=邮政
            postBindingUrl=http:// localhost:8080/auth/realms/saml-demo/protocol/saml
            重定向绑定url=http:// localhost:8080/auth/realms/saml-demo/protocol/saml/>
        <钥匙>
          <键 签名= >
            <密钥库 资源=/网络信息/密钥库.jks 密码=123号店面>
              <证书 别名=saml-演示/>
            </密钥库>
          </键>
        </键>
      </IDP>
    </SP>
   </安全部署>
</子系统>

3.1.4。Tomcat SAML适配器

为了保护部署在Tomcat 7、8和9上的WAR应用程序,您必须将Keycloak Tomcat 7 SAML适配器或Keycloak Tomcat SAML适配器安装到Tomcat安装中。 然后,您必须在部署到Tomcat的每次战争中提供一些额外的配置。 让我们检查一下这些步骤。

适配器安装

适配器不再包含在设备或war发行版中。 每个适配器都是Keycloak下载站点上的单独下载。 它们也可以作为maven工件使用。

您必须将适配器发行版解压缩到Tomcat的lib/目录。 在您的WEB-INF/lib目录中包含适配器的jar将不起作用! Keycloak SAML适配器实现为 阀门和阀门代码必须位于Tomcat的主lib/目录中。

在Tomcat 7上安装:

$ cd $ TOMCAT_HOME/lib
$ 解压缩keycloak-saml-tomcat7-adapter-dist.zip

安装在Tomcat 8或9上:

$ cd $ TOMCAT_HOME/lib
$ 解压缩keycloak-saml-tomcat-adapter-dist.zip
每个战争配置

本节介绍如何通过在WAR包中添加配置和编辑文件来直接保护WAR。

你必须做的第一件事是创建一个元信息/上下文.xml文件在你的战争包里。 这是一个特定于Tomcat的配置文件,您必须定义一个特定于Keycloak的阀门。

<上下文 路径=/您的上下文路径>
    <阀门 类名=组织。Keycloak。适配器。saml。tomcat。SamlAuthenticatorValve/>
</上下文>

接下来,您必须创建一个keycloak-saml.xml中的适配器配置文件网络信息你的战争目录。 此配置文件的格式在通用适配器配置节。

最后,您必须同时指定登录配置并使用标准servlet安全性在您的url上指定基于角色的约束。 下面是一个例子:

<网络应用 xmlns=http://java.sun.com/xml/ns/javaee
      xmlns:xsi=http:// www.w3.org/2001/XMLSchema-instance
      xsi: 模式定位=http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ web-app_3_0.xsd
      版本=3.0>

        <模块名称>客户门户</模块名称>

    <安全约束>
        <网络资源收集>
            <web-资源-名称>客户</web-资源-名称>
            <url-模式>/*</url-模式>
        </网络资源收集>
        <授权约束>
            <角色名称>用户</角色名称>
        </auth-constraint>
    </安全约束>

    <登录配置>
        <身份验证方法>基本</auth-方法>
        <境界-名称>目前忽略了这一点</领域名称>
    </登录配置>

    <安全-角色>
        <角色名称>管理员</角色名称>
    </安全角色>
    <安全-角色>
        <角色名称>用户</角色名称>
    </安全角色>
</网络应用>

如果keycloak-saml.xml没有显式设置断言消费者服务url,SAML适配器将隐式监听该位置的SAML断言/我的上下文路径/saml。 这必须匹配主SAML处理网址在IDP领域/客户端设置中,例如http://sp.domain.com/我的上下文路径/saml。 如果没有,Tomcat可能会无限重定向到IDP登录服务,因为它在用户登录后不会收到SAML断言。

为JSESSIONID cookie设置相同的值

浏览器计划为SameSiteCookie的属性Lax。 此设置意味着 只有当请求起源于同一域时,cookie才会被发送到应用程序。 这种行为会影响 SAML POST绑定可能变得不起作用。 为了保留SAML适配器的全部功能,我们建议 设置SameSite值至对于JSESSIONID由您的容器创建的cookie。 不这样做可能会导致 重置容器的会话与每个请求到Keycloak。

为了避免设置SameSite属性为,考虑切换到重定向绑定 如果可以接受,或者使用不需要此解决方法的OIDC协议。

要设置SameSite值至对于JSESSIONIDTomcat中的cookie将以下配置添加到 'context.xml' 你的申请。 注意,这将设置SameSite值至对于Tomcat容器创建的所有cookie。

<烹饪处理器 sameSiteCookies= />
无法设置SameSite仅属性为cookie的子集,因此创建的所有cookie 对于您的应用程序,此属性将设置为

Tomcat版本9.0.29和8.5.49提供了对此功能的支持。

3.1.5。Jetty SAML适配器

为了保护部署在Jetty上的WAR应用程序,您必须将Keycloak Jetty 9.x SAML适配器安装到Jetty安装中。 然后,您必须在部署到Jetty的每次战争中提供一些额外的配置。 让我们检查一下这些步骤。

Jetty 9适配器安装

Keycloak有一个单独的SAML适配器,用于Jetty 9.x。 然后,您必须在部署到Jetty的每次战争中提供一些额外的配置。 让我们检查一下这些步骤。

适配器不再包含在设备或war发行版中。 每个适配器都是Keycloak下载站点上的单独下载。 它们也可以作为maven工件使用。

您必须将Jetty 9.x发行版解压缩到Jetty 9.x的根目录中。 在您的WEB-INF/lib目录中包含适配器的jar将不起作用!

$ cd $ 捷特 _ 家
$ 解压缩keycloak-saml-jetty92-adapter-dist.zip

接下来,您必须为jetty.base启用keycloak模块。

$ cd您的基础
$ java -jar $ JETTY_HOME/start.jar-add-to-startd = keycloak
每个战争配置的码头9

本节介绍如何通过在WAR包中添加配置和编辑文件来直接保护WAR。

你必须做的第一件事是创建一个WEB-INF/jetty-web.xml文件在你的战争包里。 这是一个特定于码头的配置文件,您必须在其中定义一个特定于Keycloak的身份验证器。

<?xml version = "1.0"?>
<!DOCTYPE配置公共 “-// Mort Bay咨询 // DTD配置 // EN” “http://www.eclipse.org/jetty/ 配置 _ 9_0.dtd”>
<配置 =组织。日蚀。码头。网络应用程序上下文>
    <Get 名称=安全处理程序>
        <设置 名称=认证器>
            <新 =org.keycloak.适配器.saml.jetty.KeycloakSamlAuthenticator>
            </新>
        </Set>
    </Get>
</Configure>

接下来,您必须创建一个keycloak-saml.xml中的适配器配置文件网络信息你的战争目录。 此配置文件的格式在通用适配器配置节。

最后,您必须同时指定登录配置并使用标准servlet安全性在您的url上指定基于角色的约束。 下面是一个例子:

<网络应用 xmlns=http://java.sun.com/xml/ns/javaee
      xmlns:xsi=http:// www.w3.org/2001/XMLSchema-instance
      xsi: 模式定位=http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ web-app_3_0.xsd
      版本=3.0>

        <模块名称>客户门户</模块名称>

    <安全约束>
        <网络资源收集>
            <web-资源-名称>客户</web-资源-名称>
            <url-模式>/*</url-模式>
        </网络资源收集>
        <授权约束>
            <角色名称>用户</角色名称>
        </auth-constraint>
        <用户数据约束>
            <运输-保证>机密</运输-保证>
        </用户数据约束>
    </安全约束>

    <登录配置>
        <身份验证方法>基本</auth-方法>
        <境界-名称>目前忽略了这一点</领域名称>
    </登录配置>

    <安全-角色>
        <角色名称>管理员</角色名称>
    </安全角色>
    <安全-角色>
        <角色名称>用户</角色名称>
    </安全角色>
</网络应用>

3.1.6。Java Servlet过滤器适配器

如果要将SAML与没有该servlet平台适配器的Java servlet应用程序一起使用,则可以 选择使用Keycloak拥有的servlet过滤器适配器。 该适配器的工作方式与其他适配器略有不同。 您仍然必须指定一个/WEB-INF/keycloak-saml.xml中定义的文件 的通用适配器配置部分,但是 您没有在web.xml。 相反,您使用Keycloak servlet过滤器适配器定义了一个过滤器映射,以保护要保护的url模式。

反向通道注销的工作原理与标准适配器有点不同。 而不是使http会话无效,而是将会话ID标记为已注销。 无法根据会话ID任意使http会话无效。
当您有一个使用SAML过滤器的群集应用程序时,反向通道注销当前不起作用。
<网络应用 xmlns=http://java.sun.com/xml/ns/javaee
      xmlns:xsi=http:// www.w3.org/2001/XMLSchema-instance
      xsi: 模式定位=http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ web-app_3_0.xsd
      版本=3.0>

        <模块名称>客户门户</模块名称>

    <过滤器>
        <过滤器名称>Keycloak过滤器</过滤器名称>
        <过滤器类>org.keycloak.适配器.saml.servlet.SamlFilter</过滤器类>
    </过滤器>
    <过滤器映射>
        <过滤器名称>Keycloak过滤器</过滤器名称>
        <url-模式>/*</url-模式>
    </过滤器映射>
</网络应用>

Keycloak过滤器具有与其他适配器相同的配置参数,但您必须 将它们定义为过滤器init参数,而不是上下文参数。

如果您有各种不同的安全和不安全的url模式,则可以定义多个过滤器映射。

你必须有一个过滤器映射,覆盖/saml。 此映射涵盖所有服务器回调。

向国内流离失所者注册SPs时,您必须注册http[s]:// 主机名/{上下文根}/saml作为您的Assert消费者服务URL和单一注销服务URL。

要使用此过滤器,请在您的战争poms中包含此maven工件:

<依赖>
   <groupId>组织。Keycloak
   <人工制品>Keycloak-saml-servlet-过滤器-适配器</人工制品>
   <版本>15.0.2</版本>
</依赖>

为了使用多租户keycloak.config.resolver参数应作为过滤器参数传递。

    <过滤器>
        <过滤器名称>Keycloak过滤器</过滤器名称>
        <过滤器类>org.keycloak.适配器.saml.servlet.SamlFilter</过滤器类>
        <init-参数>
            <参数名称>keycloak.config.resolver</参数名称>
            <参数值>示例。samlmultiptenantresolver</参数值>
        </init参数>
    </过滤器>

3.1.7。向身份提供商注册

对于每个基于servlet的适配器,您为assert consumer service URL和单一注销服务注册的端点 必须是您的servlet应用程序的基本URL/saml附加到它上面,也就是说,https://example.com/contextPath/saml

3.1.8。注销

您可以通过多种方式从web应用程序注销。 对于Java EE servlet容器,您可以调用HttpServletRequest。注销 ()。 对于任何其他浏览器应用程序,您可以指向 具有安全约束并传入查询参数GLO的web应用程序的任何url上的浏览器,即http:// 我的app?GLO = true。 如果您与浏览器有SSO会话,这将注销。

集群环境中的注销

在内部,SAML适配器存储SAML会话索引、主体名称 (已知时) 和HTTP会话ID之间的映射。 可以跨集群在JBoss应用服务器系列 (WildFly 10/11,EAP 6/7) 中维护此映射,以实现可分发 应用程序。 作为前提条件,HTTP会话需要跨集群分布 (即应用程序标记为 <可分发/>应用程序中的标签web.xml)。

要启用该功能,请将以下部分添加到您的/网络信息/网络.xml文件:

对于EAP 7,WildFly 10/11:

<上下文参数>
    <参数名称>keycloak。会话idmapperupdater。类</参数名称>
    <参数值>org.keycloak.适配器.saml.wildfly.infinispan.InfinispanSessionCacheIdMapperUpdater</参数值>
</上下文参数>

对于EAP 6:

<上下文参数>
    <参数名称>keycloak。会话idmapperupdater。类</参数名称>
    <参数值>org.keycloak.适配器.saml.jbossweb.infinispan.InfinispanSessionCacheIdMapperUpdater</参数值>
</上下文参数>

如果部署的会话缓存被命名为部署-缓存,用于SAML映射的缓存将被命名为 作为部署-缓存。ssoCache。 缓存的名称可以被上下文参数覆盖 Keycloak。会话idmapperupdater。infinispan。cacheName。 包含缓存的缓存容器将与 包含部署会话缓存的缓存,但可以被上下文参数覆盖 keycloak.sessionIdMapperUpdater.infinispan.containerName

默认情况下,SAML映射缓存的配置将从会话缓存派生。 配置可以 与其他缓存一样,在服务器的缓存配置部分中手动覆盖。

当前,为了提供可靠的服务,建议对SAML会话缓存使用复制缓存。 使用分布式缓存可能会导致SAML注销请求将登陆到没有访问权限的节点的结果 到SAML会话索引到HTTP会话映射,这将导致注销失败。

跨DC场景中的注销

交叉DC场景仅适用于WildFly 10及更高版本,以及EAP 7及更高版本。

需要特殊处理来处理跨越多个数据中心的会话。 想象以下场景:

  1. 登录请求在数据中心1的集群内处理。

  2. 管理员为特定SAML会话发出注销请求,该请求登录数据中心2。

数据中心2必须注销数据中心1中存在的所有会话 (以及所有其他数据中心 共享HTTP会话)。

为了涵盖这种情况,SAML会话缓存描述以上需要复制 不仅在单个集群内,而且在所有数据中心内,例如 通过独立的Infinispan/JDG服务器:

  1. 必须将缓存添加到独立的Infinispan/JDG服务器中。

  2. 必须将上一个项目的缓存添加为相应SAML会话缓存的远程存储。

一旦在部署过程中发现远程存储存在于SAML会话缓存中,就会监视其更改 并且相应地更新本地SAML会话缓存。

3.1.9。获取断言属性

成功登录SAML后,您的应用程序代码可能希望获取随SAML断言传递的属性值。 HttpServletRequest.getUserPrincipal()返回a校长您可以将其类型转换到Keycloak特定类的对象 被称为组织。Keycloak。适配器。saml。SamlPrincipal。 此对象允许您查看原始断言,并且还具有方便功能来查找属性值。

包装 组织。Keycloak。适配器。saml;

公众  SamlPrincipal 工具 可序列化,校长{
    /**
     * 获得完整的saml断言
     *
     * @ 返回
     */
    公众断言类型getAssertion() {
       ...
    }

    /**
     * 获取在断言中发送的SAML主题
     *
     * @ 返回
     */
    公众 字符串获取主题 () {
        ...
    }

    /**
     * 主题名称id格式
     *
     * @ 返回
     */
    公众 字符串getNameIDFormat() {
        ...
    }

    @ 覆盖
    公众 字符串getName() {
        ...
    }

    /**
     * 通过属性名称获取属性值的便利功能
     *
     * @ 参数名称
     * @ 返回
     */
    公众 列表<字符串> 获取属性 (字符串名称) {
        ...

    }

    /**
     * 通过属性友好名称获取属性值的便利功能
     *
     * @ param friendlyName
     * @ 返回
     */
    公众 列表<字符串> 获取friendlyattributes (字符串friendlyName) {
        ...
    }

    /**
     * 方便函数,通过属性名称获取属性的第一个值
     *
     * @ 参数名称
     * @ 返回
     */
    公众 字符串getAttribute (字符串名称) {
        ...
    }

    /**
     * 方便函数,通过属性名称获取属性的第一个值
     *
     *
     * @ param friendlyName
     * @ 返回
     */
    公众 字符串getFriendlyAttribute (字符串friendlyName) {
        ...
    }

    /**
     * 获取所有断言属性名称的集合
     *
     * @ 返回
     */
    公众 设置<字符串> 获取属性名称 () {
        ...
    }

    /**
     * 获取所有断言友好属性名称的集合
     *
     * @ 返回
     */
    公众 设置<字符串> 获取友好名称 () {
        ...
    }
}

3.1.10。错误处理

Keycloak为基于servlet的客户端适配器提供了一些错误处理工具。 当身份验证中遇到错误时,客户端适配器将调用Http服务响应。发送错误 ()。 您可以设置一个错误-页面在你的web.xml文件来处理错误,但是你想要。 客户端适配器可以抛出400、401、403和500错误。

<错误-页面>
    <错误代码>403</错误代码>
    <位置>/错误处理程序</位置>
</错误页面>

客户端适配器还设置了一个HttpServletRequest您可以检索的属性。 属性名称为组织。密钥斗篷。适配器。spi。身份验证错误。 将此对象类型转换为:组织。密钥斗篷。适配器。saml。SamlAuthenticationError。 这门课可以告诉你到底发生了什么。 如果未设置此属性,则适配器不对错误代码负责。

公众  SamlAuthenticationError 工具身份验证错误 {
    公众 静态 枚举原因 {
        提取 _ 失败,
        无效签名,
        错误 _ 状态
    }

    公众原因getReason() {
        返回原因;
    }
    公众状态响应类型获取状态 () {
        返回状态;
    }
}

3.1.11。故障排除

解决问题的最佳方法是在客户端适配器和Keycloak服务器中打开SAML的调试。 使用您的日志记录框架,将日志级别设置为调试对于组织。Keycloak。saml包。 打开此功能可让您查看发送到服务器和从服务器发送的SAML请求和响应文档。

3.1.12。多租户

SAML提供了与OIDC相同的功能多租户,这意味着可以使用多个Keycloak领域来保护单个目标应用程序 (WAR)。 这些领域可以位于相同的Keycloak实例上,也可以位于不同的实例上。

要做到这一点,应用程序必须有多个keycloak-saml.xml适配器配置文件。

虽然您可以使用不同的适配器配置文件将多个WAR实例部署到不同的上下文路径,但这可能会带来不便,并且您可能还希望基于上下文路径以外的其他内容选择领域。

Keycloak使具有自定义配置解析器成为可能,因此您可以选择用于每个请求的适配器配置。 在SAML中,配置仅在登录处理中有趣; 用户登录后,会话将被身份验证,并且keycloak-saml.xml返回的是不同的。 因此,为同一会话返回相同的配置是正确的方法。

为了实现这一点,创建一个实现org.keycloak.适配器.saml.SamlConfigResolver。 下面的示例使用主机头,以找到正确的配置,并从应用程序的Java类路径加载它和关联的元素:

包装 示例;

导入 java.io.InputStream;
导入 org.keycloak.适配器.saml.SamlConfigResolver;
导入 组织。Keycloak。适配器。saml。SamlDeployment;
导入 组织。密钥斗篷。适配器。saml。配置。解析器。部署生成器;
导入 org.keycloak.adapters.saml.config.parsers.ResourceLoader;
导入 组织。Keycloak。适配器。spi。HttpFacade;
导入 org.keycloak.saml.com星期一.异常.解析异常;

公众  Samlmultiptenantresolver 工具SamlConfigResolver {

    @ 覆盖
    公众SamlDeployment解析 (HttpFacade.Request) {
        字符串主机 = 请求。getHeader (主机);
        字符串领域 =null;
        如果(主机。包含 (租户1)) {
            领域 =租户1;
        }其他 如果(主机。包含 (租户2)) {
            领域 =租户2;
        }其他{
            投掷 新的 非法状态例外(无法猜测要加载的keycloak-saml.xml);
        }

        输入流is = getClass()。getResourceAsStream (/+ 境界 +-keycloak-saml.xml);
        如果(is = =null) {
            投掷 新的 非法状态例外(找不到文件/+ 境界 +-keycloak-saml.xml);
        }

        资源加载器 =新的资源资源 () {
            @ 覆盖
            公众 输入流获取资源 (字符串路径) {
                返回getClass()。getResourceAsStream (路径);
            }
        };

        尝试{
            返回 新的DeploymentBuilder()。构建 (是,加载器);
        }抓住(解析异常e) {
            投掷 新的 非法状态例外(无法加载SAML部署,e);
        }
    }
}

您还必须配置哪个SamlConfigResolver要与keycloak.config.resolver上下文参数在您的web.xml:

<网络应用>
    ...
    <上下文参数>
        <参数名称>keycloak.config.resolver</参数名称>
        <参数值>示例。samlmultiptenantresolver</参数值>
    </上下文参数>
</网络应用>

3.1.13。从旧版本迁移

迁移到1.9.0
SAML SP客户端适配器更改

Keycloak SAML SP客户端适配器现在需要一个特定的端点,/saml向你的国内流离失所者登记。 除了它具有的任何其他绑定之外,SamlFilter还必须绑定到/saml。 这必须这样做,因为SAML POST绑定会吃掉请求输入流,这对于依赖它的客户端来说真的很糟糕。

3.2。mod_auth_mellon Apache HTTPD模块

mod_auth_mellon模块是SAML的Apache HTTPD插件。 如果您的语言/环境支持使用Apache HTTPD作为代理,那么您可以使用mod_auth_mellon使用SAML保护您的web应用程序。 有关此模块的更多详细信息,请参见mod_auth_mellonGitHub回购。

要配置mod_auth_mellon,您需要:

  • 身份提供程序 (IdP) 实体描述符XML文件,它描述了与Keycloak或另一个SAML IdP的连接

  • 一个SP实体描述符XML文件,它描述了您要保护的应用程序的SAML连接和配置。

  • 私钥PEM文件,它是PEM格式的文本文件,定义了应用程序用来签署文档的私钥。

  • 证书PEM文件,它是一个文本文件,为您的应用程序定义证书。

  • mod_auth_mellon-specific Apache HTTPD模块配置。

如果您已经在Keycloak应用程序服务器上的某个领域中定义并注册了客户端应用程序,则Keycloak可以生成所需的所有文件,但Apache HTTPD模块配置除外。

要生成Apache HTTPD模块配置,请完成以下步骤:

  1. 转到SAML客户端的安装页面,然后选择Mod Auth Mellon文件选项。

    mod_auth_mellon配置下载

    mod auth梅隆配置下载

  2. 点击下载要下载包含您需要的XML描述符和PEM文件的zip文件。

3.2.1。使用密钥斗篷配置mod_auth_mellon

涉及两个主机:

  • 运行Keycloak的主机,它将被称为 $ idp_host,因为Keycloak是SAML身份提供程序 (IdP)。

  • web应用程序正在运行的主机,它将被称为 $ sp_host。 在SAML中,使用IdP的应用程序称为服务提供商 (SP)。

以下所有步骤都需要在具有root权限的 $ sp_host上执行。

安装软件包

要安装必要的软件包,您需要:

  • 阿帕奇网络服务器 (httpd)

  • 适用于Apache的梅隆SAML SP附加模块

  • 创建X509证书的工具

要安装必要的软件包,请运行以下命令:

百胜安装httpd mod_auth_mellon mod_ssl openssl
为Apache SAML创建配置目录

建议将与Apache使用SAML相关的配置文件保存在一个位置。

创建位于Apache配置根目录/etc/httpd下的名为saml2的新目录:

mkdir /etc/httpd/saml2
配置Mellon服务提供商

Apache附加模块的配置文件位于/etc/httpd/conf.d目录中,文件名扩展名为.conf。 您需要创建/etc/httpd/conf.d/mellon.conf文件,并在其中放置Mellon的配置指令。

Mellon的配置指令可以大致分为两类信息:

  • 使用SAML身份验证保护哪些url

  • 当引用受保护的URL时,将使用哪些SAML参数。

Apache配置指令通常遵循URL空间中的分层树结构,称为位置。 您需要为Mellon指定一个或多个要保护的URL位置。 您可以灵活地添加适用于每个位置的配置参数。 您可以将所有必要的参数添加到位置块,也可以将Mellon参数添加到特定受保护位置继承的URL位置层次结构中较高的公共位置 (或两者的某种组合)。 由于无论哪个位置触发SAML操作,SP都以相同的方式运行,因此此处使用的示例配置将常见的Mellon配置指令放置在层次结构的根目录中,然后可以使用最少的指令定义要由Mellon保护的特定位置。 此策略避免为每个受保护位置重复相同的参数。

此示例只有一个受保护的位置: https:// $ sp_host/private。

要配置Mellon服务提供商,请完成以下步骤:

  1. 使用以下内容创建文件/etc/httpd/conf.d/mellon.conf:

 <位置 / >
    MellonEnable信息
    梅隆点路径/梅隆/
    Mellonspmetaadatafile/etc/httpd/saml2/mellon_metaadata.xml
    MellonSPPrivateKeyFile /etc/httpd/saml2/mellon.key
    MellonSPCertFile /etc/httpd/saml2/mellon.crt
    Mellonidpmetaadatafile/etc/httpd/saml2/idp_metaadata.xml
 </位置>
 <位置 /私人 >
    授权梅隆
    MellonEnable auth
    要求有效-用户
 </位置>
上面代码中引用的一些文件是在后面的步骤中创建的。

浏览器计划为SameSiteCookie的属性Lax。 此设置意味着 只有当请求起源于同一域时,cookie才会被发送到应用程序。 这种行为会影响 SAML POST绑定可能变得不起作用。 保留的全部功能mod_auth_mellon模块, 我们建议设置SameSite值至对于由mod_auth_mellon。 不这样做可能会导致 无法使用Keycloak登录。

要设置SameSite值至,将以下配置添加到<位置/>在您的梅隆。conf 文件。

梅隆塞科科基开
MellonCookieSameSite无

此配置的支持可在mod_auth_mellon0.16.0版本的模块。

创建服务提供商元数据

在SAML idp和SPs中交换SAML元数据,它是XML格式的。 元数据的架构是标准,因此确保参与的SAML实体可以使用彼此的元数据。 您需要:

  • SP利用的IdP的元数据

  • 描述提供给国内流离失所者的SP的元数据

SAML元数据的组件之一是X509证书。 这些证书用于两个目的:

  • 签署SAML消息,以便接收端可以证明消息源自预期方。

  • 在传输过程中加密消息 (很少使用,因为SAML消息通常发生在受TLS保护的传输上)

如果您已经拥有证书颁发机构 (CA),则可以使用自己的证书,或者可以生成自签名证书。 为了简单起见,在本示例中使用了自签名证书。

因为Mellon的SP元数据必须反映已安装版本mod_auth_mellon的功能,所以必须是有效的SP元数据XML,并且必须包含X509证书 (除非您熟悉X509证书生成,否则其创建可以是钝器)。生成SP元数据的最方便方法是使用包含在mod_auth_mellon包 (mellon_create_metadata.sh) 中的工具。 生成的元数据总是可以在以后编辑,因为它是一个文本文件。 该工具还会创建您的X509密钥和证书。

SAML idp和SPs使用称为EntityID的唯一名称来标识自己。 要使用Mellon元数据创建工具,您需要:

  • EntityID,通常是SP的URL,通常是可以检索SP元数据的SP的URL

  • SP的SAML消息将被消费的URL,Mellon调用MellonEndPointPath。

要创建SP元数据,请完成以下步骤:

  1. 创建几个辅助外壳变量:

    fqdn = '主机名'
    梅隆 _ 端点 _ 网址 = "https:// ${fqdn}/梅隆"
    mellon_entity_id = "${mellon_endpoint_url}/元数据"
    file_prefix = "$ (回声" $ mellon_entity_id "| sed 's/[^ A-Za-z.]/_/g' | sed 's/_ */_/g')"
  2. 通过运行以下命令调用Mellon元数据创建工具:

    /usr/libexec/mod_auth_mellon/mellon_create_metaada.sh $ mellon_entity_id $ mellon_endpoint_url
  3. 将生成的文件移动到它们的目的地 (在上面创建的/etc/httpd/conf.d/mellon.conf文件中引用):

    mv ${file_prefix}。证书/etc/httpd/saml2/mellon.crt
    mv ${file_prefix}.key /etc/httpd/saml2/mellon.key
    mv ${file_prefix}.xml /etc/httpd/saml2/mellon_metaada.xml
将Mellon服务提供商添加到Keycloak身份提供商

假设: Keycloak IdP已经安装在 $ idp_host上。

Keycloak支持多个租户,其中所有用户,客户端等都分组在所谓的领域中。 每个领域都独立于其他领域。 您可以在Keycloak中使用现有领域,但此示例显示了如何创建名为test_realm的新领域并使用该领域。

所有这些操作都是使用Keycloak管理web控制台执行的。 您必须具有 $ idp_host的管理员用户名和密码。

完成以下步骤:

  1. 打开管理控制台,输入管理员用户名和密码登录。

    登录管理控制台后,将有一个现有领域。 首先设置Keycloak时,默认情况下会创建一个根领域master。 任何先前创建的领域都在管理控制台的左上角的下拉列表中列出。

  2. 从境界下拉列表中选择添加领域

  3. 在名称字段中类型测试领域并点击创建

将Mellon服务提供商添加为领域的客户

在Keycloak中,SAML sp被称为客户端。 要添加SP,我们必须在领域的客户端部分。

  1. 单击左侧的 “客户端” 菜单项,然后单击创建在右上角创建新客户端。

添加Mellon SP客户端

要添加Mellon SP客户端,请完成以下步骤:

  1. 将客户端协议设置为SAML。 从客户端协议下拉列表中,选择saml

  2. 提供上面创建的Mellon SP元数据文件 (/etc/httpd/saml2/mellon_metadata.xml)。 根据浏览器运行的位置,您可能必须将SP元数据从 $ sp_host复制到浏览器运行的计算机上,以便浏览器可以找到文件。

  3. 点击保存

编辑梅隆SP客户端

我们建议设置几个客户端配置参数:

  • 确保 “强制绑定” 打开。

  • 将paospresponse添加到有效的重定向uri列表:

    1. 复制 “有效重定向uri” 中的后响应URL,然后将其粘贴到 “” 下方的空添加文本字段中。

    2. 将 “postResponse” 改为 “paosponse”。 (SAML ECP需要paospresponse URL。)

    3. 点击保存在底部。

许多SAML sp根据用户在组中的成员身份来确定授权。 Keycloak IdP可以管理用户组信息,但它不提供用户组,除非IdP配置为将其提供为SAML属性。

要将IdP配置为作为SAML属性提供用户组,请完成以下步骤:

  1. 单击客户端的映射器选项卡。

  2. 在Mappers页面的右上角,单击创建

  3. 从映射器类型下拉列表中选择组列表

  4. 将名称设置为 “组列表”。

  5. 将SAML属性名称设置为 “组”。

  6. 点击保存

其余步骤在 $ sp_host上执行。

检索身份提供程序元数据

现在,您已经在IdP上创建了领域,您需要检索与之关联的IdP元数据,以便Mellon SP识别它。 在先前创建的/etc/httpd/conf.d/mellon.conf文件中,MellonIdPMetadataFile被指定为/etc/httpd/saml2/idp_metadata.xml,但是到目前为止,该文件还不存在于 $ sp_host上。 要获取该文件,我们将从国内流离失所者那里检索它。

  1. 通过用正确的值替换 $ idp_host从IdP中检索文件:

    curl -k -o /etc/httpd/saml2/idp_metaada.xml \
    https:// $ idp_host/auth/realms/test_realm/protocol/saml/描述符

    梅隆现在已经完全配置好了。

  2. 要对Apache配置文件运行语法检查:

    apachectl配置测试
    Configtest等价于apachectl的-t参数。 如果配置测试显示任何错误,请在继续之前更正它们。
  3. 重启Apache服务器:

    systemctl重新启动httpd.服务

现在,您已经将Keycloak设置为test_realm中的SAML IdP,将mod_auth_mellon设置为SAML SP,通过针对$ idp_host国内流离失所者。

4. Docker注册表配置

默认情况下禁用Docker身份验证。 要启用请参阅配置文件

本节介绍如何配置Docker注册表以将Keycloak用作其身份验证服务器。

有关如何设置和配置Docker注册表的更多信息,请参见Docker注册表配置指南

4.1。Docker注册表配置文件安装

对于具有更高级Docker注册表配置的用户,通常建议提供您自己的注册表配置文件。 Keycloak Docker提供程序通过注册表配置文件格式选项。 选择此选项将生成类似于以下内容的输出:

身份验证:
  令牌:
    领域: http:// localhost:8080/auth/realms/master/protocol/docker-v2/auth
    服务: docker-测试
    发行者: http:// localhost:8080/auth/realms/master

然后可以将此输出复制到任何现有的注册表配置文件中。 请参阅注册表配置文件规范有关如何设置文件或从以下内容开始的更多信息一个基本的例子

不要忘记配置根certbundle带有Keycloak领域公共证书位置的字段。 如果没有这个参数,auth配置将无法工作。

4.2。Docker注册表环境变量覆盖安装

通常,对于开发或POC Docker注册表,使用简单的环境变量覆盖是合适的。 虽然这种方法通常不推荐用于生产,但当需要快速而肮脏的方法来建立注册表时,它可能会有所帮助。 只需使用变量覆盖来自 “客户端安装” 选项卡的格式选项,输出应显示如下所示:

REGISTRY_AUTH_TOKEN_REALM: http:// localhost:8080/auth/realms/master/protocol/docker-v2/auth
注册认证令牌服务: 码头工人测试
Registry_auth_token_issupendor: http:// localhost:8080/auth/realms/master
不要忘记配置注册 _ 授权 _ 令牌 _ 根证书用Keycloak领域的公共证书的位置覆盖。 如果没有这个参数,auth配置将无法工作。

4.3。Docker Compose YAML文件

这种安装方法是一种简单的方法,可以让docker注册表对Keycloak服务器进行身份验证。 它仅用于开发目的,绝不能在生产或类似生产的环境中使用。

zip文件安装机制为希望了解Keycloak服务器如何与Docker注册表交互的开发人员提供了快速入门。 为了配置:

  1. 从所需的领域,创建客户端配置。 此时,您将没有Docker注册表-quickstart将负责该部分。

  2. 从安装选项卡中选择 “Docker Compose YAML” 选项,然后下载。zip文件

  3. 将存档解压缩到所需位置,然后打开目录。

  4. 使用码头工人-组成

建议您在 “主” 以外的领域中配置Docker注册表客户端,因为HTTP基本身份验证流将不显示表单。

一旦进行了上述配置,并且keycloak服务器和Docker注册表正在运行,docker身份验证应该成功:

[用户 ~]# docker登录本地主机: 5000 -u $ 用户名
密码: *******
登录成功

5.客户注册

为了使应用程序或服务使用Keycloak,它必须在Keycloak中注册客户端。 管理员可以通过管理控制台 (或admin REST端点) 执行此操作,但是客户端也可以通过Keycloak客户端进行注册 注册服务。

客户端注册服务提供了对Keycloak客户端表示、OpenID Connect客户端元数据和SAML实体描述符的内置支持。 客户端注册服务端点为/auth/领域/<领域>/客户端-注册/<提供者>

内置支持提供商是:

  • 默认-Keycloak客户端表示 (JSON)

  • 安装-Keycloak适配器配置 (JSON)

  • openid-connect - OpenID Connect客户端元数据描述 (JSON)

  • saml2-entity-descriptor - SAML实体描述符 (XML)

以下各节将描述如何使用不同的提供程序。

5.1。身份验证

要调用客户端注册服务,您通常需要一个令牌。 令牌可以是承载令牌、初始访问令牌或注册访问令牌。 还有一种替代方法可以在没有任何令牌的情况下注册新客户端,但是您需要配置客户端注册策略 (请参见下文)。

5.1.1。承载令牌

承载令牌可以代表用户或服务帐户发行。 调用端点需要以下权限 (请参阅服务器管理指南有关更多详细信息):

  • 创建-客户端或管理-客户端-创建客户端

  • 查看-客户端或管理-客户端-查看客户端

  • 管理-客户端-更新或删除客户端

如果您使用的是承载令牌来创建客户端,建议您使用仅具有创建-客户端角色 (请参阅服务器管理指南有关更多详细信息)。

5.1.2。初始访问令牌

推荐的注册新客户端的方法是使用初始访问令牌。 初始访问令牌只能用于创建客户端,并且具有可配置的过期以及可以创建多少个客户端的可配置限制。

可以通过管理控制台创建初始访问令牌。 要创建新的初始访问令牌,请首先在管理控制台中选择领域,然后单击领域设置在左侧的菜单中,然后是 客户注册在页面中显示的选项卡中。 然后最后点击初始访问令牌子选项卡。

您现在将能够看到任何现有的初始访问令牌。 如果您有访问权限,则可以删除不再需要的令牌。 您只能检索 创建令牌时的值。 要创建新令牌,请单击创建。 您现在可以选择添加令牌应该有效的时间,以及如何 可以使用令牌创建许多客户端。 点击后保存显示令牌值。

现在复制/粘贴此令牌很重要,因为以后将无法检索它。 如果忘记复制/粘贴它,则删除令牌并创建另一个令牌。

通过将token值添加到请求中的授权标头,在调用客户端注册服务时将其用作标准承载令牌。 例如:

授权: bearer eyJhbGciOiJSUz...

5.1.3。注册访问令牌

当您通过客户端注册服务创建客户端时,响应将包括注册访问令牌。 注册访问令牌提供了稍后检索客户端配置的访问权限,也提供了更新或删除客户端的访问权限。 注册访问令牌以与承载令牌或初始访问令牌相同的方式包含在请求中。 注册访问令牌仅有效一次,使用后,响应将包括新令牌。

如果客户端是在客户端注册服务之外创建的,则它将没有与之关联的注册访问令牌。 您可以通过管理控制台创建一个。 如果您丢失了特定客户端的令牌,这也可能很有用。 要创建新令牌,请在管理控制台中找到客户端,然后单击凭据。 然后点击生成注册访问令牌

5.2。Keycloak表示

默认客户端注册提供程序可用于创建,检索,更新和删除客户端。 它使用Keycloak客户端表示格式,该格式提供了对配置客户端的支持,因为它们可以通过管理员进行配置 控制台,包括例如配置协议映射器。

要创建客户端,请创建客户端表示 (JSON),然后执行HTTP POST请求以/auth/领域/<领域>/客户端-注册/默认

它将返回一个还包括注册访问令牌的客户端表示。 如果要检索配置,更新或删除客户端,则应将注册访问令牌保存在某个位置。

要检索客户端表示,请执行HTTP GET请求/auth/realms/<领域>/客户端-注册/默认/<客户端id>

它还将返回一个新的注册访问令牌。

要更新客户端表示,请使用更新的客户端表示执行HTTP PUT请求,以: /auth/realms/<领域>/客户端-注册/默认/<客户端id>

它还将返回一个新的注册访问令牌。

要删除客户端表示,请执行HTTP删除请求: /auth/realms/<领域>/客户端-注册/默认/<客户端id>

5.3。Keycloak适配器配置

安装客户端注册提供程序可用于检索客户端的适配器配置。 除了令牌身份验证之外,您还可以使用HTTP基本身份验证使用客户端凭据进行身份验证。 为此,在请求中包括以下标头:

授权: 基本BASE64 (客户端id + ':' + 客户端-秘密)

要检索适配器配置,然后执行HTTP GET请求/auth/realms/<领域>/客户端-注册/安装/<客户端id>

公共客户端不需要身份验证。 这意味着对于JavaScript适配器,您可以使用上述URL直接从Keycloak加载客户端配置。

5.4。OpenID连接动态客户端注册

使用这些规范在Keycloak中注册客户端的端点是/auth/realms/<realm>/客户端-注册/openid-连接 [/<客户端id>]

该端点也可以在该领域的OpenID Connect发现端点中找到,/auth/realms/<realm>/。知名/openid-configuration

5.5。SAML实体描述符

SAML实体描述符端点仅支持使用SAML v2实体描述符创建客户端。 它不支持检索、更新或删除客户端。 对于这些操作,应使用Keycloak表示端点。 创建客户端时,将返回Keycloak客户端表示形式,其中包含有关创建的客户端的详细信息,包括注册访问令牌。

要创建客户端,请使用SAML实体描述符执行HTTP POST请求,以/auth/领域/<领域>/客户端-注册/saml2-entity-descriptor

5.6。使用卷曲的示例

下面的示例使用clientId创建一个客户端我的客户端使用卷曲。 你需要更换eyJhbGciOiJSUz&hellip;使用适当的初始访问令牌或 不记名令牌。

卷曲-X柱 \
    -d '{ "clientId": "我的客户端" }' \
    -H “内容类型: 应用程序/json” \
    -H “授权: bearer eyJhbGciOiJSUz...” \
    http:// localhost:8080/auth/realms/master/clients-registrations/default

5.7。使用Java客户端注册API的示例

客户端注册Java API使使用Java的客户端注册服务变得容易。 要使用包括依赖项组织。Keycloak: Keycloak-客户端-注册-应用编程接口:> 版本 <来自Maven。

有关使用客户端注册的完整说明,请参阅JavaDocs。 下面是创建客户端的示例。 你需要更换eyJhbGciOiJSUz&hellip;具有适当的初始访问令牌或承载令牌。

字符串令牌 =eyJhbGciOiJSUz...;

客户代表客户端 =新的客户代表 ();
客户端。setClientId(CLIENT_ID);

ClientRegistration reg = ClientRegistration.create()
    。url (http:// localhost:8080/auth,我的领域)
    。构建 ();

reg.auth(Auth.token(token));

客户端 = reg.create (客户端);

字符串注册accesstoken = 客户端。getRegistrationAccessToken();

5.8。客户注册策略

当前的计划是删除客户注册策略,以支持服务器管理指南。 客户端策略更加灵活,支持更多用例。

Keycloak目前支持通过客户端注册服务注册新客户端的两种方式。

  • 经过身份验证的请求-注册新客户端的请求必须包含初始访问令牌或者承载令牌如上所述。

  • 匿名请求-注册新客户端的请求根本不需要包含任何令牌

匿名客户端注册请求是非常有趣且功能强大的功能,但是您通常不希望任何人都可以注册新的 客户没有任何限制。 因此,我们有客户注册策略SPI,它提供了一种限制谁可以注册新客户以及在何种条件下的方法。

在Keycloak管理控制台中,您可以单击以客户注册选项卡,然后客户注册策略子选项卡。 在这里,您将看到哪些政策 默认情况下为匿名请求配置,以及为经过身份验证的请求配置了哪些策略。

匿名请求 (没有任何令牌的请求) 仅用于创建 (注册) 新客户端。 所以当你注册的时候 新客户端通过匿名请求,响应将包含注册访问令牌,该令牌必须用于特定客户端的读取,更新或删除请求。 但是,使用匿名注册的此注册访问令牌也将受到匿名策略的约束! 这意味着例如请求更新 客户端还需要来自受信任的主机,如果您有可信主机政策。 另外,例如,它将不被允许禁用需要同意更新客户端和 当需要同意政策存在等。

目前我们有这些策略实现:

  • 受信任主机策略-您可以配置受信任主机和受信任域的列表。 可以仅从这些主机或域发送对客户端注册服务的请求。 从某些不受信任的IP发送的请求将被拒绝。 新注册的客户端的url还必须仅使用那些受信任的主机或域。 例如,它是不允许的 要设置重定向URI指向某个不受信任的主机的客户端。 默认情况下,没有任何列入白名单的主机,因此实际上禁用了匿名客户端注册。

  • 需要同意的政策-新注册的客户将有允许同意开关已启用。 所以成功认证后,用户将始终 当他需要批准权限 (客户端范围) 时,请参阅同意屏幕。 这意味着客户将无法访问任何个人 除非用户批准,否则用户的信息或权限。

  • 协议映射器策略-允许配置白名单协议映射器实现。 无法注册新客户 或更新,如果它包含一些非白名单协议映射器。 请注意,此策略也用于经过身份验证的请求,因此 即使对于经过身份验证的请求,也存在一些限制,可以使用哪些协议映射器。

  • 客户端范围策略-允许白名单客户端范围,可与新注册或更新的客户端一起使用。 默认情况下没有白名单范围; 只有客户端范围,定义为领域默认客户端范围默认情况下被列入白名单。

  • 全面政策-新注册的客户将拥有允许的全范围开关已禁用。 这意味着他们不会有任何范围 其他客户端的领域角色或客户端角色。

  • 最大客户端策略-如果领域中的当前客户端数量相同或大于指定限制,则拒绝注册。 默认情况下,匿名注册200。

  • 客户端禁用策略-新注册的客户端将被禁用。 这意味着管理员需要手动批准和启用所有新注册的客户端。 默认情况下,即使匿名注册,也不使用此策略。

6.客户注册CLI

客户端注册CLI是一个命令行界面 (CLI) 工具,供应用程序开发人员在与Keycloak集成时以自助方式配置新客户端。 它专门设计用于与Keycloak客户端注册REST端点进行交互。

为了能够使用Keycloak,必须为任何应用程序创建或获取客户端配置。 您通常为托管在唯一主机名上的每个新应用程序配置一个新客户端。 当应用程序与Keycloak交互时,该应用程序使用客户端ID标识自己,因此Keycloak可以提供登录页面,单点登录 (SSO) 会话管理和其他服务。

您可以使用客户端注册CLI从命令行配置应用程序客户端,并且可以在shell脚本中使用它。

允许特定用户使用客户注册命令行界面Keycloak管理员通常使用管理控制台来配置具有适当角色的新用户,或者配置新的客户端和客户端密钥以授予对客户端注册REST API的访问权限。

6.1。配置新的常规用户以与客户端注册CLI一起使用

  1. 登录到管理控制台 (例如,http:// localhost:8080/auth/admin) as管理员

  2. 选择要管理的领域。

  3. 如果要使用现有用户,请选择要编辑的用户; 否则,请创建一个新用户。

  4. 选择角色映射> 客户端角色> 领域管理。 如果您在主领域,请选择名称-领域,其中名称是目标领域的名称。 您可以向主领域中的用户授予对任何其他领域的访问权限。

  5. 选择可用角色> 管理-客户端授予全套客户端管理权限。 另一种选择是选择视图-客户端对于只读或创建-客户端创建新客户。

    这些权限授予用户执行操作的能力,而无需使用初始访问令牌或者注册访问令牌

可以不分配任何领域管理用户的角色。 在这种情况下,用户仍然可以使用客户端注册CLI登录,但是如果没有初始访问令牌,则无法使用它。 尝试在没有令牌的情况下执行任何操作都会导致403禁止错误。

管理员可以从管理控制台通过领域设置> 客户端注册> 初始访问令牌菜单。

6.2。配置客户端以与客户端注册CLI一起使用

默认情况下,服务器将客户端注册CLI识别为管理-cli客户端,为每个新境界自动配置。 使用用户名登录时,不需要额外的客户端配置。

  1. 创建一个新的客户端 (例如,注册cli),如果要为客户端注册CLI使用单独的客户端配置。

  2. 切换启用标准流将其设置为

  3. 通过配置客户端来加强安全性访问类型作为机密并选择凭据> ClientId和Secret

    您可以配置客户端Id和秘密或者签署JWT凭据tab。

  4. 如果要使用与客户端关联的服务帐户,请通过选择要在客户的部分管理控制台

    1. 设置,更改访问类型机密,切换已启用服务帐户设置为,然后单击保存

    2. 点击服务帐户角色然后选择所需的角色来配置服务帐户的访问权限。 有关选择哪些角色的详细信息,请参见配置新的常规用户以与客户端注册CLI一起使用

  5. 切换启用直接访问授权将其设置为如果您想使用常规用户帐户而不是服务帐户。

  6. 如果客户端配置为机密,在运行时提供配置的密钥kcreg配置凭据通过使用-秘密选项。

  7. 指定哪个clientId使用 (例如,-- 客户端注册-cli) 运行时kcreg配置凭据

  8. 启用服务帐户后,您可以在运行时省略指定用户kcreg配置凭据并且仅提供客户端机密或密钥库信息。

6.3。安装客户端注册命令行界面

客户端注册CLI打包在Keycloak服务器发行版中。 您可以在bin目录。 Linux脚本被称为克里格.什,而Windows脚本被称为克里格.蝙蝠

将Keycloak服务器目录添加到您的路径设置客户端以从文件系统上的任何位置使用时。

例如,在:

  • Linux:

$ 导出路径 = $ 路径: $ KEYCLOAK_HOME/bin
$ kcreg.sh
  • 窗口:

c :\> 设置路径 = % 路径 %;% KEYCLOAK_HOME % \ bin
c :\> 克里格

钥匙锁 _ 主页指的是Keycloak服务器分发被解压缩的目录。

6.4。使用客户端注册CLI

  1. 通过使用您的凭据登录来启动经过身份验证的会话。

  2. 客户注册休息端点。

    例如,在:

    • Linux:

      $ kcreg.sh配置凭据-服务器http:// localhost:8080/auth-领域演示-用户用户-客户端reg-cli
      $ kcreg.sh create -s clientId = my_client -s 'redirectUris = [“http:// 本地主机: 8980/myapp/*”]'
      $ kcreg.sh获取我的客户端
    • 窗口:

      c :\> kcreg配置凭据-服务器http:// localhost:8080/auth-领域演示-用户用户-客户端reg-cli
      c :\> kcreg创建-s clientId = 我的客户端-s “重定向 = [” http:// 本地主机: 8980/我的应用/* “]”
      c :\> kcreg获取我的 _ 客户端

      在生产环境中,必须使用https:以避免将令牌暴露给网络嗅探器。

  3. 如果服务器的证书不是由Java默认证书信任库中包含的受信任证书颁发机构 (ca) 之一颁发的,请准备一个信任商店。jks文件并指示客户端注册CLI使用它。

    例如,在:

    • Linux:

      $ kcreg.sh配置信任商店-信任通行证 $ 密码 ~/。密钥斗篷/信任商店。jks
    • 窗口:

      c :\> kcreg配置信任商店-信任通行证 % 密码 % % 主页 % \。密钥斗篷 \ 信任商店。jks

6.4.1。登录

  1. 使用客户端注册CLI登录时,指定服务器端点URL和领域。

  2. 指定用户名或客户端id,这将导致使用特殊的服务帐户。 使用用户名时,必须使用指定用户的密码。 使用客户端ID时,您可以使用客户端密钥或签署JWT而不是密码。

无论采用哪种登录方式,登录的帐户都需要适当的权限才能执行客户端注册操作。 请记住,非主领域中的任何帐户只能具有管理同一领域中的客户端的权限。 如果您需要管理不同的领域,您可以在不同的领域配置多个用户,也可以在大师领域和添加角色,用于管理不同领域的客户端。

您不能使用客户端注册CLI配置用户。 使用管理控制台web界面或管理客户端CLI配置用户。 见服务器管理指南有关更多详细信息。

克里格成功登录后,它会接收授权令牌并将其保存在私有配置文件中,以便令牌可用于后续调用。 见使用替代配置有关配置文件的更多信息。

有关使用客户端注册CLI的更多信息,请参见内置帮助。

例如,在:

  • Linux:

$ kcreg.sh帮助
  • 窗口:

c :\> kcreg帮助

kcreg配置凭据-帮助有关启动经过身份验证的会话的更多信息。

6.4.2。使用替代配置

默认情况下,客户端注册CLI会自动在默认位置维护一个配置文件,。/.keycloak/kcreg.config,在用户的主目录下。 您可以使用-配置指向不同文件或位置以并行维护多个经过身份验证的会话的选项。 从单个线程执行绑定到单个配置文件的操作是最安全的方法。

不要使配置文件对系统上的其他用户可见。 配置文件包含访问令牌和应保密的秘密。

您可能希望通过使用-- 无配置选项与您的所有命令,即使它不太方便,需要更多的令牌请求这样做。 使用每个克里格调用。

6.4.3。初始访问和注册访问令牌

没有在要使用的Keycloak服务器上配置帐户的开发人员可以使用客户端注册CLI。 仅当领域管理员向开发人员发出初始访问令牌时,才有可能。 由领域管理员决定如何以及何时发行和分发这些令牌。 领域管理员可以限制初始访问令牌的最大期限以及可以用它创建的客户端总数。

一旦开发人员拥有了初始访问令牌,开发人员就可以使用它来创建新客户端,而无需使用kcreg配置凭据。 初始访问令牌可以存储在配置文件中,也可以指定为kcreg创建指挥。

例如,在:

  • Linux:

$ kcreg.sh配置初始令牌 $ 令牌
$ kcreg.sh创建-s clientId = 我的客户端

或者

$ kcreg.sh创建-s clientId = 我的客户端-t $ 令牌
  • 窗口:

c :\> kcreg配置初始令牌 %
c :\> kcreg创建-s clientId = 我的客户端

或者

c :\> kcreg创建-s clientId = 我的客户端-t % 令牌 %

当使用初始访问令牌时,服务器响应包括新发布的注册访问令牌。 该客户端的任何后续操作都需要通过使用该令牌进行身份验证来执行,该令牌仅对该客户端有效。

客户端注册CLI会自动使用其私有配置文件将此令牌与其关联的客户端一起保存和使用。 只要将相同的配置文件用于所有客户端操作,开发人员就不需要进行身份验证即可读取,更新或删除以这种方式创建的客户端。

客户注册有关初始访问和注册访问令牌的更多信息。

运行kcreg配置初始令牌-帮助kcreg配置注册令牌-帮助有关如何使用客户端注册CLI配置令牌的更多信息的命令。

6.4.4。创建客户端配置

使用凭据进行身份验证或配置初始访问令牌后的第一个任务通常是创建新客户端。 通常,您可能希望使用准备好的JSON文件作为模板,并设置或覆盖某些属性。

下面的示例演示如何读取JSON文件,覆盖它可能包含的任何客户端id,设置任何其他属性,并在成功创建后将配置打印为标准输出。

  • Linux:

$ kcreg.sh创建-f client-template.json -s clientId = 我的客户端-s baseUrl =/我的客户端-s重定向 =["/我的客户端/*"]' -o
  • 窗口:

C :\> kcreg创建-f client-template.json -s clientId = 我的客户端-s baseUrl =/我的客户端-s "重定向 = ["/我的客户端/* "]" -o

运行kcreg创建-帮助有关kcreg创建指挥。

您可以使用kcreg attrs列出可用属性。 请记住,没有检查许多配置属性的有效性或一致性。 由您来指定适当的值。 请记住,您的id字段中不应该有任何id字段 模板,不应将它们指定为参数kcreg创建指挥。

6.4.5。检索客户端配置

您可以通过使用克里格得到指挥。

例如,在:

  • Linux:

$ kcreg.sh获取我的客户端
  • 窗口:

C :\> kcreg获取我的客户端

您还可以将客户端配置检索为适配器配置文件,您可以将其与web应用程序一起打包。

例如,在:

  • Linux:

$ kcreg.sh获取我的客户端安装> keycloak.json
  • 窗口:

C :\> kcreg获取我的客户端-e安装> keycloak.json

运行kcreg获得-帮助命令以获取有关克里格得到指挥。

6.4.6。修改客户端配置

更新客户端配置有两种方法。

一种方法是在获得当前配置后向服务器提交一个完整的新状态,将其保存到文件中,对其进行编辑,然后将其发布回服务器。

例如,在:

  • Linux:

$ kcreg.sh获取我的客户端> 我的客户端.json
$ vi myclient.json
$ kcreg.sh更新我的客户端-f我的客户端.json
  • 窗口:

C :\> kcreg获取我的客户端> 我的客户端.json
C :\> 记事本我的客户端.json
C :\> kcreg更新我的客户端-f我的客户端.json

第二种方法获取当前客户端,设置或删除其上的字段,然后一步将其发布回去。

例如,在:

  • Linux:

$ kcreg.sh更新myclient -s启用 = false -d重定向
  • 窗口:

C :\> kcreg更新我的客户端启用 = false -d重定向

您还可以使用仅包含要应用的更改的文件,因此您不必指定太多的值作为参数。 在这种情况下,指定-- 合并要告诉客户端注册CLI,与其将JSON文件视为完整的新配置,不如将其视为要应用于现有配置的一组属性。

例如,在:

  • Linux:

$ kcreg.sh更新我的客户端-合并-d重定向-f我的更改。json
  • 窗口:

C :\> kcreg更新我的客户端-合并-d重定向-f我的更改。json

运行kcreg更新-帮助命令以获取有关kcreg更新指挥。

6.4.7。删除客户端配置

使用以下示例删除客户端。

  • Linux:

$ kcreg.sh删除我的客户端
  • 窗口:

C :\> kcreg删除我的客户端

运行kcreg删除-帮助命令以获取有关kcreg删除指挥。

6.4.8。刷新无效的注册访问令牌

当使用-- 无配置模式下,客户端注册CLI无法为您处理注册访问令牌。 在这种情况下,可能会失去对客户端最近发布的注册访问令牌的跟踪,这使得无法在该客户端上执行任何进一步的CRUD操作,而无需使用具有以下功能的帐户进行身份验证管理-客户端权限。

如果您具有权限,则可以为客户端颁发新的注册访问令牌,并将其打印到标准输出或保存到您选择的配置文件中。 否则,您必须要求领域管理员为您的客户发布一个新的注册访问令牌,并将其发送给您。 然后,您可以通过-- 令牌选项。 您也可以使用kcreg配置注册-令牌命令将新令牌保存在配置文件中,并让客户端注册CLI从那时起自动为您处理它。

运行kcreg更新令牌-帮助命令以获取有关kcreg更新-令牌指挥。

6.5。故障排除

  • 问: 登录时,我得到一个错误:参数client_assertion_type缺失 [无效 _client]

    答: 此错误意味着您的客户端配置了签署JWT令牌凭据,这意味着您必须使用-密钥库登录时的参数。

7.令牌交换

令牌交换是技术预览并且没有得到完全支持。 默认情况下,此功能被禁用。

启用以启动服务器-Dkeycloak。个人资料 = 预览 或者-Dkeycloak.profile.feature.token_exchange = 启用 。 有关更多详细信息,请参见配置文件

为了使用令牌交换,您还应该启用管理 _ 精细 _ 颗粒 _ 认证特征。 请看看配置文件

在Keycloak中,令牌交换是使用一组凭据或令牌来获得完全不同的令牌的过程。 客户端可能想要在不太可信的应用程序上调用,因此它可能想要降级它拥有的当前令牌。 客户端可能希望将Keycloak令牌交换为关联的社交提供商帐户存储的令牌。 您可能希望信任其他Keycloak领域或外国国内流离失所者铸造的外部令牌。 客户可能有需要 模拟用户。 以下是围绕令牌交换的Keycloak当前功能的简短摘要。

  • 客户端可以将为特定客户端创建的现有Keycloak令牌交换为针对其他客户端的新令牌

  • 客户端可以将现有的Keycloak令牌交换为外部令牌,即链接的Facebook帐户

  • 客户端可以将外部令牌交换为Keycloak令牌。

  • 客户端可以模拟用户

Keycloak中的令牌交换是一个非常松散的实现OAuth令牌交换IETF的规范。 我们对它进行了一些扩展,忽略了其中的一些内容,并松散地解释了规范的其他部分。 它是 领域的OpenID Connect令牌端点上的简单授权类型调用。

/auth/realms/{realm}/protocol/openid-connect/token

它接受表单参数 (应用程序/x-www-表单-urlencoded) 作为输入,输出取决于您请求交换的令牌的类型。 令牌交换是客户端端点,因此请求必须为调用客户端提供身份验证信息。 公共客户端将其客户端标识符指定为表单参数。 保密客户也可以使用表单参数 要传递他们的客户端id和机密、基本身份验证,或者但是您的管理员已经在您的 境界。 这是表单参数的列表

客户id

可能是必需的。 使用表单参数进行身份验证的客户端需要此参数。 如果你正在使用 基本身份验证,客户端JWT令牌或客户端证书身份验证,则不指定此参数。

客户 _ 秘密

可能需要。 对于使用表单参数进行身份验证并使用客户端机密作为凭据的客户端,此参数是必需的。 如果您领域中的客户端调用通过不同的方式进行了身份验证,请不要指定此参数。

Grant _ 类型

必填。 参数的值必须为urn:ietf:params:oauth:grant-type:token-exchange

主题 _ 令牌

可选。 代表代表提出请求的一方的身份的安全令牌。 如果您要将现有令牌交换为新令牌,则需要它。

主题 _ 发行人

可选。 标识主题 _ 令牌。 如果令牌来自当前领域,或者如果发行方 可以从主题 _ 令牌 _ 类型。 否则需要指定。 有效值是身份提供者为您的领域配置。 或发行人索赔标识符 由特定的身份提供者

主题 _ 令牌 _ 类型

可选。 此参数是用主题 _ 令牌参数。 此默认值 到urn:ietf:params:oauth: 令牌类型: 访问令牌如果主题 _ 令牌来自领域,是一个访问令牌。 如果它是外部令牌,则根据 主题 _ 发行人

请求 _ 令牌 _ 类型

可选。 此参数表示客户端要交换的令牌类型。 目前只有oauth 支持OpenID连接令牌类型。 默认值取决于它是否 是urn:ietf:params:oauth: 令牌类型: 刷新令牌在这种情况下,您将同时返回访问令牌和刷新 响应中的令牌。 其他适当的值是urn:ietf:params:oauth: 令牌类型: 访问令牌urn:ietf:params:oauth: 令牌类型: id_token

观众

可选。 此参数指定要为其铸造新令牌的目标客户端。

请求发放者

可选。 此参数指定客户端希望外部提供者铸造令牌。 它必须 成为身份提供者在领域内配置。

请求 _ 主题

可选。 如果您的客户端想要模拟其他用户,这将指定用户名或用户id。

范围

未实施。 此参数表示客户端的OAuth和OpenID Connect的目标集作用域 正在请求。 目前尚未实现,但一旦Keycloak对 一般范围。

我们目前只支持OpenID Connect和OAuth交换。 将来可能会根据用户需求添加对基于SAML的客户端和身份提供商的支持。

来自exchange调用的成功响应将返回HTTP 200响应代码,其内容类型为 取决于请求令牌类型请求发放者客户要求。 OAuth请求的令牌类型将返回 JSON文档,如OAuth令牌交换规格。

{
   访问令牌:.....,
   刷新令牌:.....,
   expires_in:....
 }

请求刷新令牌的客户端将在响应中返回访问和刷新令牌。 仅请求的客户 访问令牌类型将仅在响应中获取访问令牌。 过期信息可能包括也可能不包括 客户通过请求发放者参数。

错误响应通常属于400 HTTP响应代码类别,但可能会返回其他错误状态代码 取决于错误的严重程度。 错误响应可能包括内容,具体取决于请求发放者。 基于OAuth的交换可以返回JSON文档,如下所示:

{
   错误:....
   错误 _ 描述:....
}

根据exchange类型,可能会返回其他错误声明。 例如,OAuth身份提供者可以包括 一个额外的帐户链接网址如果用户没有到身份提供者的链接,则声明。 可以使用此链接 对于客户端发起的链接请求。

令牌交换设置需要了解细颗粒管理员权限 (请参阅服务器管理指南有关更多信息)。 您需要授予客户 交换许可。 这将在本章后面详细讨论。

本章的其余部分讨论了设置要求,并提供了不同交换场景的示例。 为了简单起见,让我们将当前领域铸造的令牌称为内部令牌和由铸造的令牌 外部领域或身份提供者作为外部令牌。

7.1。内部令牌到内部令牌交换

使用内部令牌到令牌交换,您将现有令牌铸造到特定客户端,并且您想要交换 此令牌是为其他目标客户端铸造的新令牌。 你为什么要这么做? 这种情况通常会发生 当客户端为自己铸造了令牌,并且需要向其他需要不同的应用程序发出额外请求时 访问令牌内的声明和权限。 这种类型的交换可能需要的其他原因是,如果你 需要执行 “权限降级”,其中您的应用程序需要在不太可信的应用程序上调用,而您不希望 传播您当前的访问令牌。

7.1.1。授予交易所许可

想要为其他客户端交换令牌的客户端需要在管理控制台中获得授权才能这样做。 你需要定义一个令牌交换要交换权限的目标客户端中的细粒度权限。

目标客户端权限

exchange目标客户端权限未设置

切换已启用权限切换到ON。

目标客户端权限

exchange目标客户端权限集

你应该看到一个令牌交换页面上的链接。 单击该按钮开始定义权限。 它会带给你 到这一页。

目标客户端交换权限设置

exchange目标客户端权限设置

您必须为此权限定义一个策略。 单击授权链接,转到政策选项卡并创建 a客户政策。

客户端策略创建

exchange目标客户端策略

您在这里输入起始客户端,即正在请求令牌交换的经过身份验证的客户端。 在你之后 创建此策略,返回目标客户端的令牌交换权限并添加您刚刚的客户端策略 定义。

应用客户端策略

exchange目标客户端exchange应用策略

您的客户端现在有权调用。 如果您不正确执行此操作,则会收到403禁止的响应 试着交换一下。

7.1.2。提出请求

当您的客户端将现有令牌交换为针对另一个客户端的令牌时,您必须使用观众参数。 此参数必须是您在管理控制台中配置的目标客户端的客户端标识符。

卷曲-X柱 \
    -d "client_id = 启动-客户端" \
    -d “客户端秘密 = 客户端秘密” \
    -- data-urlencode “grant_type = urn:ietf:params:oauth:grant-type:token-exchange” \
    -d "subject_token = ...." \
    -- data-urlencode “请求 _ 令牌 _ 类型 = urn:ietf: 参数: oauth: 令牌类型: 刷新令牌” \
    -d “受众 = 目标-客户” \
    http:// localhost:8080/auth/realms/myrealm/protocol/openid-connect/token

主题 _ 令牌参数必须是目标领域的访问令牌。 如果你的请求 _ 令牌 _ 类型参数 是刷新令牌类型,则响应将包含访问令牌,刷新令牌和过期。 这是 一个示例JSON响应,你从这个调用回来。

{
   访问令牌:....,
   刷新令牌:....,
   expires_in:3600
}

7.2。内部令牌到外部令牌交换

您可以将领域令牌换成外部身份提供者铸造的外部令牌。 此外部身份提供者 必须在身份提供者管理控制台的部分。 目前只有基于OAuth/OpenID连接的外部 支持身份提供者,这包括所有社交提供者。 Keycloak不执行到外部提供程序的反向通道交换。 所以如果账户 未链接,您将无法获取外部令牌。 能够获得外部令牌之一 必须满足以下条件:

  • 用户必须至少使用外部身份提供商登录一次

  • 用户必须已通过用户帐户服务与外部身份提供商链接

  • 用户帐户通过外部身份提供商使用客户发起的帐户链接API。

最后,必须已将外部身份提供程序配置为存储令牌,或者,上述操作之一必须 已使用与您要交换的内部令牌相同的用户会话执行。

如果未链接帐户,则exchange响应将包含可用于建立该帐户的链接。 这是 在提出请求节。

7.2.1。授予交易所许可

内部到外部令牌交换请求将被拒绝,并带有403的禁止响应,直到您授予 调用客户端与外部身份提供者交换令牌的权限。 授予权限 到客户端,您必须转到身份提供程序的配置页面到权限tab。

身份提供者权限

exchange idp权限未设置

切换已启用权限切换到true。

身份提供者权限

exchange idp权限集

你应该看到一个令牌交换页面上的链接。 单击该按钮开始定义权限。 它会带给你 到这一页。

身份提供者交换权限设置

exchange idp权限设置

您必须为此权限定义一个策略。 单击授权链接,转到政策选项卡并创建 a客户政策。

客户端策略创建

exchange idp客户端策略

您在这里输入起始客户端,即正在请求令牌交换的经过身份验证的客户端。 在你之后 创建此策略,返回到身份提供者的令牌交换权限并添加您刚刚的客户端策略 定义。

应用客户端策略

exchange idp应用策略

您的客户端现在有权调用。 如果您不正确执行此操作,则会收到403禁止的响应 试着交换一下。

7.2.2。提出请求

当您的客户端将现有的内部令牌交换给外部令牌时,您必须提供 请求发放者参数。 参数必须是配置的身份提供程序的别名。

卷曲-X柱 \
    -d "client_id = 启动-客户端" \
    -d “客户端秘密 = 客户端秘密” \
    -- data-urlencode “grant_type = urn:ietf:params:oauth:grant-type:token-exchange” \
    -d "subject_token = ...." \
    -- data-urlencode “请求 _ 令牌 _ 类型 = urn:ietf: 参数: oauth: 令牌类型: 访问 _ 令牌” \
    -d "请求 _ 发行人 = 谷歌" \
    http:// localhost:8080/auth/realms/myrealm/protocol/openid-connect/token

主题 _ 令牌参数必须是目标领域的访问令牌。 的请求 _ 令牌 _ 类型参数 一定是urn:ietf:params:oauth: 令牌类型: 访问令牌或者留空。 不支持其他请求的令牌类型 此时。 这是 一个示例成功的JSON响应,你从这个调用中回来。

{
   访问令牌:....,
   expires_in:3600
   帐户链接网址:https:// ....
}

如果外部身份提供程序由于任何原因未链接,您将获得HTTP 400响应代码 此JSON文档:

{
   错误:....,
   错误 _ 描述:...
   帐户链接网址:https:// ....
}

错误索赔将是令牌 _ 已过期或者未链接。 的帐户链接网址提供了索赔 这样客户端就可以执行客户发起的帐户链接。 大部分 (全部?) 提供商需要通过浏览器OAuth协议进行链接。 与帐户链接网址只需添加一个重定向uri 查询参数,您可以转发浏览器以执行链接。

7.3。外部令牌到内部令牌交换

您可以信任并交换由外部身份提供者铸造的外部令牌以获取内部令牌。 这可以是 用于在领域之间架起桥梁,或者只是信任来自您的社交提供商的令牌。 它的工作原理类似于身份提供者 浏览器登录,如果新用户不存在,则将其导入您的领域。

当前对外部令牌交换的限制是,如果外部令牌映射到现有用户, 除非现有用户已经具有指向外部身份的帐户链接,否则将不允许交换 提供商。

交换完成后,将在领域内创建用户会话,您将获得访问权限 和或刷新令牌取决于请求 _ 令牌 _ 类型参数值。 你应该注意到这个新的 用户会话将保持活动状态,直到它超时或直到您调用域的注销端点传递此 新的访问令牌。

这些类型的更改需要在管理控制台中配置身份提供程序。

目前不支持SAML身份提供程序。 Twitter令牌也不能交换。

7.3.1。授予交易所许可

在进行外部令牌交换之前,您必须授予调用客户端进行交换的权限。 这个 许可的授予方式与授予内部到外部许可

如果您还提供观众参数,其值指向不同的客户端而不是调用客户端,您 还必须向调用客户端授予交换权限,以便在观众参数。 如何 要做到这一点就是前面讨论过在本节中。

7.3.2。提出请求

主题 _ 令牌 _ 类型必须是urn:ietf:params:oauth: 令牌类型: 访问令牌或者urn:ietf:params:oauth: 令牌类型: jwt。 如果类型是urn:ietf:params:oauth: 令牌类型: 访问令牌您必须指定主题 _ 发行人参数,它必须是 配置的身份提供程序的别名。 如果类型是urn:ietf:params:oauth: 令牌类型: jwt,提供商将通过 的发行人JWT中的索赔必须是提供商的别名,或者提供商配置中的注册发行人。

对于验证,如果令牌是访问令牌,则将调用提供商的用户信息服务以验证令牌。 成功的通话 将意味着访问令牌是有效的。 如果主题令牌是JWT,并且提供者启用了签名验证,则将尝试, 否则,它将默认也在用户信息服务上调用以验证令牌。

默认情况下,所铸造的内部令牌将使用调用客户端使用协议来确定令牌中的内容 为调用客户端定义的映射器。 或者,您可以使用观众 参数。

卷曲-X柱 \
    -d "client_id = 启动-客户端" \
    -d “客户端秘密 = 客户端秘密” \
    -- data-urlencode “grant_type = urn:ietf:params:oauth:grant-type:token-exchange” \
    -d "subject_token = ...." \
    -d “subject_issuer = myoidcsprovider” \
    -- data-urlencode “subject_token_type = urn:ietf:params:oauth:token-type:access_token” \
    -d “受众 = 目标-客户” \
    http:// localhost:8080/auth/realms/myrealm/protocol/openid-connect/token

如果你的请求 _ 令牌 _ 类型参数 是刷新令牌类型,则响应将包含访问令牌,刷新令牌和过期。 这是 一个示例JSON响应,你从这个调用回来。

{
   访问令牌:....,
   刷新令牌:....,
   expires_in:3600
}

7.4。模仿

对于内部和外部令牌交换,客户端可以代表用户请求模拟不同的用户。 例如,您可能有一个需要模拟用户的管理员应用程序,以便支持工程师可以调试 一个问题。

7.4.1。授予交易所许可

主题令牌代表的用户必须具有模拟其他用户的权限。 请参阅 服务器管理指南关于如何启用此权限。 它可以通过角色或通过 精细谷物管理权限。

7.4.2。提出请求

按照其他章节的描述进行请求,除了额外指定请求 _ 主题参数。 的 此参数的值必须是用户名或用户id。

卷曲-X柱 \
    -d "client_id = 启动-客户端" \
    -d “客户端秘密 = 客户端秘密” \
    -- data-urlencode “grant_type = urn:ietf:params:oauth:grant-type:token-exchange” \
    -d "subject_token = ...." \
    -- data-urlencode “请求 _ 令牌 _ 类型 = urn:ietf: 参数: oauth: 令牌类型: 访问 _ 令牌” \
    -d “受众 = 目标-客户” \
    -d "请求主题 = wburke" \
    http:// localhost:8080/auth/realms/myrealm/protocol/openid-connect/token

7.5。直接裸体模仿

您可以发出内部令牌交换请求,而无需提供主题 _ 令牌。 这被称为直接 赤裸裸的模仿,因为它会对客户端产生很大的信任,因为该客户端可以模仿该领域的任何用户。 您可能需要它来桥接无法获得要交换的主题令牌的应用程序。 例如, 您可能正在集成直接使用LDAP执行登录的旧应用程序。 在这种情况下,传统应用程序 能够对用户本身进行身份验证,但无法获取令牌。

为客户启用直接裸模仿是非常危险的。 如果客户的凭据曾经 被盗,该客户端可以冒充系统中的任何用户。

7.5.1。授予交易所许可

如果观众提供了参数,则调用客户端必须具有与客户端交换的权限。 如何 设置此设置将在本章前面讨论。

此外,必须向调用客户端授予模拟用户的权限。 在管理控制台中,转到 用户屏幕并单击权限tab。

用户权限

交换用户权限未设置

切换已启用权限切换到true。

身份提供者权限

exchange用户权限集

你应该看到一个模仿页面上的链接。 单击该按钮开始定义权限。 它会带给你 到这一页。

用户模拟权限设置

交换用户权限设置

您必须为此权限定义一个策略。 单击授权链接,转到政策选项卡并创建 a客户政策。

客户端策略创建

交换用户客户端策略

您在这里输入起始客户端,即正在请求令牌交换的经过身份验证的客户端。 在你之后 创建此策略,返回用户模仿权限并添加您刚刚的客户端策略 定义。

应用客户端策略

交换用户应用策略

您的客户端现在拥有冒充用户的权限。 如果您不正确执行此操作,则会收到403禁止的响应 尝试进行这种类型的交换。

公共客户不允许直接进行裸体模仿。

7.5.2。提出请求

要发出请求,只需指定请求 _ 主题参数。 这必须是的用户名或用户id 有效用户。 您还可以指定一个观众如果你愿意,参数。

卷曲-X柱 \
    -d "client_id = 启动-客户端" \
    -d “客户端秘密 = 客户端秘密” \
    -- data-urlencode “grant_type = urn:ietf:params:oauth:grant-type:token-exchange” \
    -d "请求主题 = wburke" \
    http:// localhost:8080/auth/realms/myrealm/protocol/openid-connect/token

7.6。使用服务帐户扩展权限模型

授予客户端exchange权限时,您不必为每个客户端手动启用这些权限。 如果客户端具有与之关联的服务帐户,则可以使用角色将权限分组在一起并分配交换权限 通过为客户的服务帐户分配角色。 例如,您可以定义一个裸体交换角色和任何具有该角色的服务帐户 角色可以进行裸交换。

7.7。Exchange漏洞

当您开始允许令牌交换时,您必须注意并小心各种事情。

首先是公共客户。 公共客户端没有或需要客户端凭据来执行交换。 任何有效的人 令牌将能够模拟公共客户并执行公共客户允许执行的交换。 如果有 如果任何由您的领域管理的不可信任的客户端,公共客户端可能会在您的权限模型中打开漏洞。 这就是为什么直接裸交换不允许公共客户端,并且如果呼叫客户端是公共的,则会以错误中止。

可以将Facebook,Google等提供的社交令牌交换为领域令牌。 小心警惕什么 允许使用交换令牌,因为在这些社交网站上创建虚假帐户并不难。 使用默认角色、组和身份提供者映射器来控制哪些属性和角色 分配给外部社交用户。

直接裸体交换是相当危险的。 您非常信任呼叫客户端,它永远不会泄漏出去 它的客户端凭据。 如果这些凭据被泄露,那么小偷可以冒充你系统中的任何人。 这是直接的 与拥有现有令牌的机密客户端形成对比。 您有两个身份验证因素,访问令牌和客户端 凭据,并且您只与一个用户打交道。 所以少用直接裸交换。