6.2. 配置
SAML 客户端适配器由放置在 WAR 部署中的 XML 文件 /WEB-INF/keycloak-saml.xml
来配置。配置可能类似如下:
<keycloak-saml-adapter xmlns="urn:keycloak:saml:adapter" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:keycloak:saml:adapter https://www.keycloak.org/schema/keycloak_saml_adapter_1_10.xsd"> <SP entityID="http://localhost:8081/sales-post-sig/" sslPolicy="EXTERNAL" nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" logoutPage="/logout.jsp" forceAuthentication="false" isPassive="false" turnOffChangeSessionIdOnLogin="false" autodetectBearerOnly="false"> <Keys> <Key signing="true" > <KeyStore resource="/WEB-INF/keystore.jks" password="store123"> <PrivateKey alias="http://localhost:8080/sales-post-sig/" password="test123"/> <Certificate alias="http://localhost:8080/sales-post-sig/"/> </KeyStore> </Key> </Keys> <PrincipalNameMapping policy="FROM_NAME_ID"/> <RoleIdentifiers> <Attribute name="Role"/> </RoleIdentifiers> <RoleMappingsProvider id="properties-based-role-mapper"> <Property name="properties.resource.location" value="/WEB-INF/role-mappings.properties"/> </RoleMappingsProvider> <IDP entityID="idp" signaturesRequired="true"> <SingleSignOnService requestBinding="POST" bindingUrl="http://localhost:8081/realms/demo/protocol/saml" /> <SingleLogoutService requestBinding="POST" responseBinding="POST" postBindingUrl="http://localhost:8081/realms/demo/protocol/saml" redirectBindingUrl="http://localhost:8081/realms/demo/protocol/saml" /> <Keys> <Key signing="true"> <KeyStore resource="/WEB-INF/keystore.jks" password="store123"> <Certificate alias="demo"/> </KeyStore> </Key> </Keys> </IDP> </SP> </keycloak-saml-adapter>
<keycloak-saml-adapter xmlns="urn:keycloak:saml:adapter"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:keycloak:saml:adapter https://www.keycloak.org/schema/keycloak_saml_adapter_1_10.xsd">
<SP entityID="http://localhost:8081/sales-post-sig/"
sslPolicy="EXTERNAL"
nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
logoutPage="/logout.jsp"
forceAuthentication="false"
isPassive="false"
turnOffChangeSessionIdOnLogin="false"
autodetectBearerOnly="false">
<Keys>
<Key signing="true" >
<KeyStore resource="/WEB-INF/keystore.jks" password="store123">
<PrivateKey alias="http://localhost:8080/sales-post-sig/" password="test123"/>
<Certificate alias="http://localhost:8080/sales-post-sig/"/>
</KeyStore>
</Key>
</Keys>
<PrincipalNameMapping policy="FROM_NAME_ID"/>
<RoleIdentifiers>
<Attribute name="Role"/>
</RoleIdentifiers>
<RoleMappingsProvider id="properties-based-role-mapper">
<Property name="properties.resource.location" value="/WEB-INF/role-mappings.properties"/>
</RoleMappingsProvider>
<IDP entityID="idp"
signaturesRequired="true">
<SingleSignOnService requestBinding="POST"
bindingUrl="http://localhost:8081/realms/demo/protocol/saml"
/>
<SingleLogoutService
requestBinding="POST"
responseBinding="POST"
postBindingUrl="http://localhost:8081/realms/demo/protocol/saml"
redirectBindingUrl="http://localhost:8081/realms/demo/protocol/saml"
/>
<Keys>
<Key signing="true">
<KeyStore resource="/WEB-INF/keystore.jks" password="store123">
<Certificate alias="demo"/>
</KeyStore>
</Key>
</Keys>
</IDP>
</SP>
</keycloak-saml-adapter>
您可以使用 ${…}
enclosure 作为系统属性替换。例如 ${jboss.server.config.dir}
。要获得 XML 配置文件中不同元素的详细信息,请参阅 Red Hat build of Keycloak SAML Galleon feature pack 详细配置。
6.2.1. 保护 WAR
这部分论述了如何通过在 WAR 软件包中添加配置和编辑文件来直接保护 WAR。
创建 keycloak-saml.xml
并在 WAR 的 WEB-INF
目录中创建后,您必须在 web.xml
中将 auth-method
设置为 KEYCLOAK-SAML
。您还必须使用标准 servlet 安全性为您的 URL 指定角色基础限制。以下是 web.xml 文件示例:
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd" version="6.0"> <module-name>customer-portal</module-name> <security-constraint> <web-resource-collection> <web-resource-name>Admins</web-resource-name> <url-pattern>/admin/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>admin</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <security-constraint> <web-resource-collection> <web-resource-name>Customers</web-resource-name> <url-pattern>/customers/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>user</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <login-config> <auth-method>KEYCLOAK-SAML</auth-method> <realm-name>this is ignored currently</realm-name> </login-config> <security-role> <role-name>admin</role-name> </security-role> <security-role> <role-name>user</role-name> </security-role> </web-app>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
version="6.0">
<module-name>customer-portal</module-name>
<security-constraint>
<web-resource-collection>
<web-resource-name>Admins</web-resource-name>
<url-pattern>/admin/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>Customers</web-resource-name>
<url-pattern>/customers/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>user</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>KEYCLOAK-SAML</auth-method>
<realm-name>this is ignored currently</realm-name>
</login-config>
<security-role>
<role-name>admin</role-name>
</security-role>
<security-role>
<role-name>user</role-name>
</security-role>
</web-app>
除 auth-method
设置外的所有标准 servlet 设置。
6.2.2. 使用红帽构建的 Keycloak SAML subsystem 保护 WAR
您不必打开 WAR,以便使用红帽构建的 Keycloak 来保护它。另外,您还可以通过红帽构建 Keycloak SAML Adapter 子系统进行外部保护。虽然您不必将 KEYCLOAK-SAML 指定为 auth-method
,您仍必须在 web.xml
中定义 安全约束
。但是,您不必创建 WEB-INF/keycloak-saml.xml
文件。这个元数据改为在服务器的 domain.xml
或 standalone.xml
子系统配置部分中的 XML 中定义。
<extensions> <extension module="org.keycloak.keycloak-saml-adapter-subsystem"/> </extensions> <profile> <subsystem xmlns="urn:jboss:domain:keycloak-saml:1.1"> <secure-deployment name="WAR MODULE NAME.war"> <SP entityID="APPLICATION URL"> ... </SP> </secure-deployment> </subsystem> </profile>
<extensions>
<extension module="org.keycloak.keycloak-saml-adapter-subsystem"/>
</extensions>
<profile>
<subsystem xmlns="urn:jboss:domain:keycloak-saml:1.1">
<secure-deployment name="WAR MODULE NAME.war">
<SP entityID="APPLICATION URL">
...
</SP>
</secure-deployment>
</subsystem>
</profile>
secure-deployment
name
属性标识您要保护的 WAR。其值是 web.xml
中定义的 module-name
,并附加 .war
。其余的配置使用与 General Adapter Config 中定义的 keycloak-saml.xml
配置相同的 XML 语法。
配置示例:
<subsystem xmlns="urn:jboss:domain:keycloak-saml:1.1"> <secure-deployment name="saml-post-encryption.war"> <SP entityID="http://localhost:8080/sales-post-enc/" sslPolicy="EXTERNAL" nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" logoutPage="/logout.jsp" forceAuthentication="false"> <Keys> <Key signing="true" encryption="true"> <KeyStore resource="/WEB-INF/keystore.jks" password="store123"> <PrivateKey alias="http://localhost:8080/sales-post-enc/" password="test123"/> <Certificate alias="http://localhost:8080/sales-post-enc/"/> </KeyStore> </Key> </Keys> <PrincipalNameMapping policy="FROM_NAME_ID"/> <RoleIdentifiers> <Attribute name="Role"/> </RoleIdentifiers> <IDP entityID="idp"> <SingleSignOnService signRequest="true" validateResponseSignature="true" requestBinding="POST" bindingUrl="http://localhost:8080/realms/saml-demo/protocol/saml"/> <SingleLogoutService validateRequestSignature="true" validateResponseSignature="true" signRequest="true" signResponse="true" requestBinding="POST" responseBinding="POST" postBindingUrl="http://localhost:8080/realms/saml-demo/protocol/saml" redirectBindingUrl="http://localhost:8080/realms/saml-demo/protocol/saml"/> <Keys> <Key signing="true" > <KeyStore resource="/WEB-INF/keystore.jks" password="store123"> <Certificate alias="saml-demo"/> </KeyStore> </Key> </Keys> </IDP> </SP> </secure-deployment> </subsystem>
<subsystem xmlns="urn:jboss:domain:keycloak-saml:1.1">
<secure-deployment name="saml-post-encryption.war">
<SP entityID="http://localhost:8080/sales-post-enc/"
sslPolicy="EXTERNAL"
nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
logoutPage="/logout.jsp"
forceAuthentication="false">
<Keys>
<Key signing="true" encryption="true">
<KeyStore resource="/WEB-INF/keystore.jks" password="store123">
<PrivateKey alias="http://localhost:8080/sales-post-enc/" password="test123"/>
<Certificate alias="http://localhost:8080/sales-post-enc/"/>
</KeyStore>
</Key>
</Keys>
<PrincipalNameMapping policy="FROM_NAME_ID"/>
<RoleIdentifiers>
<Attribute name="Role"/>
</RoleIdentifiers>
<IDP entityID="idp">
<SingleSignOnService signRequest="true"
validateResponseSignature="true"
requestBinding="POST"
bindingUrl="http://localhost:8080/realms/saml-demo/protocol/saml"/>
<SingleLogoutService
validateRequestSignature="true"
validateResponseSignature="true"
signRequest="true"
signResponse="true"
requestBinding="POST"
responseBinding="POST"
postBindingUrl="http://localhost:8080/realms/saml-demo/protocol/saml"
redirectBindingUrl="http://localhost:8080/realms/saml-demo/protocol/saml"/>
<Keys>
<Key signing="true" >
<KeyStore resource="/WEB-INF/keystore.jks" password="store123">
<Certificate alias="saml-demo"/>
</KeyStore>
</Key>
</Keys>
</IDP>
</SP>
</secure-deployment>
</subsystem>
6.2.3. 为 JSESSIONID cookie 设置 SameSite 值
浏览器正在计划将 Cookie 的 SameSite
属性的默认值设为 Lax
。此设置意味着,只有请求来自同一域时才会将 Cookie 发送到应用程序。这个行为可能会影响 SAML POST 绑定,这可能会无法正常工作。要保留 SAML 适配器的完整功能,我们建议为容器创建的 JSESSIONID
cookie 将 SameSite
值设置为 None
。不这样做可能会导致在每次请求红帽构建的 Keycloak 时重置容器的会话。
为了避免将 SameSite
属性设置为 None
,请考虑切换到 REDIRECT 绑定(如果可以接受)或 OIDC 协议(如果不需要这个临时解决方案)。
要将 Wildfly/EAP 中的 JSESSIONID
cookie 的 SameSite
值设置为 None
,请将包含以下内容的文件 undertow-handlers.conf
添加到应用的 WEB-INF
目录中:
samesite-cookie(mode=None, cookie-pattern=JSESSIONID)
samesite-cookie(mode=None, cookie-pattern=JSESSIONID)
从版本 19.1.0 开始,对此配置的支持包括在 Wildfly 中。