Spring Cloud Data Flow 安全配置和与 RedHat SSO 的集成

Posted

技术标签:

【中文标题】Spring Cloud Data Flow 安全配置和与 RedHat SSO 的集成【英文标题】:Spring Cloud Data Flow security configuracion and integration with RedHat SSO 【发布时间】:2020-11-09 22:28:39 【问题描述】:

我们正在尝试按照文档 (https://docs.spring.io/spring-cloud-dataflow/docs/current-SNAPSHOT/reference/htmlsingle/#configuration-security) 打开 Spring Cloud Data Flow 的安全性,但我们有一些我们无法填补的知识空白。

根据第 9.2 点,可以使用 OAuth 2.0 配置身份验证并将其与 SSO 集成。我们使用 RedHat SSO,因此我们正在尝试将它们两者集成,但我们无法使其正常工作,是否可能或使用的 SSO 存在限制?

根据文档,我们设置了以下属性:

spring.security.oauth2.client.registration.uaa.client-id=xxxxxxx spring.security.oauth2.client.registration.uaa.client-secret=xxxxxx spring.security.oauth2.client.registration.uaa.redirect-uri='baseUrl/login/oauth2/code/registrationId' spring.security.oauth2.client.registration.uaa.authorization-grant-type=authorization_code spring.security.oauth2.client.registration.uaa.scope[0]=openid spring.security.oauth2.client.provider.uaa.jwk-set-uri=../openid-connect/certs spring.security.oauth2.client.provider.uaa.token-uri=../openid-connect/token spring.security.oauth2.client.provider.uaa.user-info-uri=../openid-connect/userinfo spring.security.oauth2.client.provider.uaa.user-name-attribute=user_name spring.security.oauth2.client.provider.uaa.authorization-uri=../openid-connect/auth spring.security.oauth2.resourceserver.opaquetoken.introspection-uri=../openid-connect/token/introspect spring.security.oauth2.resourceserver.opaquetoken.client-id=xxxxxxx spring.security.oauth2.resourceserver.opaquetoken.client-secret=xxxxxxx

所以我们有一些考虑:

属性 resourceserver.opaquetoken 是自省令牌所必需的,因此我们很确定当我们收到 REST 请求时它们是必需的,并且它必须具有 Authorization 标题 如果我们不使用 UAA,是否应该将属性命名为 uaa? 当我们尝试访问 de UI 时,它会重定向到 authorization-uri,因为 authorization-grant-type=authorization_code,所以它会在 SSO 中登录,对吗? 如果我们使用授权类型密码,它将直接请求用户名/密码进行登录,它在哪里进行验证? 用户信息 URI 是强制性的,但它真的被使用了吗? 其他 URI(jwk 和令牌)用于什么? 为什么重定向 URI 有这种格式?这些变量指向哪里?

最后,我们在 Docker 容器中运行的 SCDF 中测试了配置,但它“什么也没做”:

dataflow-server    | DEBUG 1 --- [nio-9393-exec-1] org.apache.tomcat.util.http.Parameters   : Set query string encoding to UTF-8
dataflow-server    | DEBUG 1 --- [nio-9393-exec-1] o.a.t.util.http.Rfc6265CookieProcessor   : Cookies: Parsing b[]: JSESSIONID=55694CBB4F694DD2E345AF61AF90B05D
dataflow-server    | DEBUG 1 --- [nio-9393-exec-1] o.a.catalina.connector.CoyoteAdapter     :  Requested cookie session id is 55694CBB4F694DD2E345AF61AF90B05D
dataflow-server    | DEBUG 1 --- [nio-9393-exec-1] o.a.c.authenticator.AuthenticatorBase    : Security checking request POST /tasks/executions
dataflow-server    | DEBUG 1 --- [nio-9393-exec-1] org.apache.catalina.realm.RealmBase      :   No applicable constraints defined
dataflow-server    | DEBUG 1 --- [nio-9393-exec-1] o.a.c.a.jaspic.AuthConfigFactoryImpl     : Loading persistent provider registrations from [/tmp/tomcat.1807897745863872641.9393/conf/jaspic-providers.xml]
dataflow-server    | DEBUG 1 --- [nio-9393-exec-1] o.a.c.authenticator.AuthenticatorBase    : Not subject to any constraint
dataflow-server    |  INFO 1 --- [nio-9393-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
dataflow-server    | DEBUG 1 --- [nio-9393-exec-1] o.apache.catalina.core.StandardWrapper   :   Returning non-STM instance
dataflow-server    | DEBUG 1 --- [nio-9393-exec-1] org.apache.tomcat.util.http.Parameters   : Set encoding to UTF-8
dataflow-server    | DEBUG 1 --- [nio-9393-exec-1] org.apache.tomcat.util.http.Parameters   : Start processing with input [name=microapabatch&arguments=--my.arguments.sleep=2000+--my.arguments.forceFailure=false]
dataflow-server    | TRACE 1 --- [nio-9393-exec-1] s.n.www.protocol.http.HttpURLConnection  : ProxySelector Request for https://xxxxxxxxxxxxxxxxxxxxxxxx/openid-connect/token/introspect
dataflow-server    | TRACE 1 --- [nio-9393-exec-1] s.n.www.protocol.http.HttpURLConnection  : Looking for HttpClient for URL https://xxxxxxxxxxxxxxxxxxxxxxxx/openid-connect/token/introspect and proxy value of DIRECT
dataflow-server    | TRACE 1 --- [nio-9393-exec-1] s.n.www.protocol.http.HttpURLConnection  : Creating new HttpsClient with url:https://xxxxxxxxxxxxxxxxxxxxxxxx/openid-connect/token/introspect and proxy:DIRECT with connect timeout:-1
dataflow-server    | TRACE 1 --- [nio-9393-exec-1] s.n.www.protocol.http.HttpURLConnection  : Proxy used: DIRECT
dataflow-server    | DEBUG 1 --- [nio-9393-exec-1] o.a.tomcat.util.net.SocketWrapperBase    : Socket: [org.apache.tomcat.util.net.NioEndpoint$NiosocketWrapper@1376a3b7:org.apache.tomcat.util.net.NioChannel@198ec8c7:java.nio.channels.SocketChannel[connected local=/172.18.0.4:9393 remote=/172.18.0.1:33758]], Read from buffer: [0]
dataflow-server    | DEBUG 1 --- [nio-9393-exec-1] org.apache.tomcat.util.net.NioEndpoint   : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@1376a3b7:org.apache.tomcat.util.net.NioChannel@198ec8c7:java.nio.channels.SocketChannel[connected local=/172.18.0.4:9393 remote=/172.18.0.1:33758]], Read direct from socket: [0]
dataflow-server    | DEBUG 1 --- [nio-9393-exec-1] o.apache.coyote.http11.Http11Processor   : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@1376a3b7:org.apache.tomcat.util.net.NioChannel@198ec8c7:java.nio.channels.SocketChannel[connected local=/172.18.0.4:9393 remote=/172.18.0.1:33758]], Status in: [OPEN_READ], State out: [OPEN]
dataflow-server    | DEBUG 1 --- [nio-9393-exec-1] o.a.coyote.http11.Http11NioProtocol      : Pushed Processor [org.apache.coyote.http11.Http11Processor@17492586]
dataflow-server    | DEBUG 1 --- [nio-9393-exec-1] org.apache.tomcat.util.net.NioEndpoint   : Registered read interest for [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@1376a3b7:org.apache.tomcat.util.net.NioChannel@198ec8c7:java.nio.channels.SocketChannel[connected local=/172.18.0.4:9393 remote=/172.18.0.1:33758]]

似乎问题出在'remote=/172.18.0.1:33758',但是我们无法解释如何在这个本地IP中转换自省uri。

【问题讨论】:

【参考方案1】:

这些都是简单的 Spring Security OAuth 设置和概念在那里有更好的记录。我们正在为 keycloak 添加更好的扩展坞,但与此同时,我的旧测试 dataflow-keycloak 可能会帮助您入门。

在最近的版本中,我们添加了一种更好的方式来使用纯 jwt 密钥,我们将其记录在 Azure/AD 中。计划是为 keycloak 添加类似的部分。

我相信仅仅通过使用 issuer-urijwk-set-uri 应该给你一个工作设置(你仍然需要弄清楚角色映射的范围)作为Spring Security 使用这些来自动配置 oauth 设置。当我们还没有完全使用 Spring Security 5.3 线时,所有其他设置都有点旧。

对于 RH SSO,我不确定您是在谈论一些全局共享实例还是您的私有设置。

【讨论】:

【参考方案2】:

对于像我这样的新手,我将添加一些在 SCDF 中配置安全性时需要考虑的要点

首先,一些cmets对原来的考虑:

resourceserver.opaquetoken 属性对于令牌的自省来说是必需的,所以我们很确定当我们收到一个 REST 请求并且它必须有 Authorization 标头时它们是必需的 --> 就是这样。 如果我们不使用UAA,属性是否应该命名为uaa? --> 它只是一个标签,你可以放任何你想要的东西。它创建了所有相关属性之间的关系,是登录页面中显示的文本。 当我们尝试访问de UI时,它会重定向到authorization-uri,因为authorization-grant-type=authorization_code,所以它会登录SSO,对吗? --> 是的,这将显示一个页面,其中包含上一点中使用的标签(链接)重定向到您的 SSO 登录页面。 如果我们使用授权类型密码,它将直接请求用户名/密码进行登录,它在哪里进行验证? --> 在旧版本的 SCDF 中,可以直接在配置文件,但这不再可用。我没有继续研究这个选项,因为我们使用了授权码。 用户信息 URI 是强制性的,但是,它真的被使用了吗? --> 是的,它用于身份验证流程的某个点。 其他 URI(jwk 和令牌)用于什么? --> 是身份验证流程的一部分 为什么重定向 URI 有这种格式?这些变量指向哪里? --> 一旦你通过身份验证,你就会被重定向到这个 url,其中'baseUrl' 是你的主机名,它会自动解析。

现在,我们用来使其工作的配置:

spring.security.oauth2.client.registration.RedHatSSO.client-id=XXXXXXX spring.security.oauth2.client.registration.RedHatSSO.client-secret=YYYYYYY spring.security.oauth2.client.registration.RedHatSSO.redirect-uri=baseUrl/login/oauth2/code/registrationId -->注意包含值的脚标记符号(') ,它们是否必要取决于用于部署的基础架构。 spring.security.oauth2.client.registration.RedHatSSO.authorization-grant-type=authorization_code spring.security.oauth2.client.registration.RedHatSSO.scope[0]=openid spring.security.oauth2.client.provider.RedHatSSO.user-name-attribute=preferred_username -->这个属性是必须的,在响应中指明用户名所在属性的标签SSO 服务器(当它不是“用户名”时)。 spring.security.oauth2.client.provider.RedHatSSO.jwk-set-uri=https://ZZZZZZZZZZZZ/protocol/openid-connect/certs --> 所有这些端点 URI 都应该根据SSO 提供的端点。 spring.security.oauth2.client.provider.RedHatSSO.token-uri=https://ZZZZZZZZZZZZ/protocol/openid-connect/token spring.security.oauth2.client.provider.RedHatSSO.user-info-uri=https://ZZZZZZZZZZZZ/protocol/openid-connect/userinfo spring.security.oauth2.client.provider.RedHatSSO.authorization-uri=https://ZZZZZZZZZZZZ/protocol/openid-connect/auth spring.security.oauth2.resourceserver.opaquetoken.introspection-uri=https://ZZZZZZZZZZZZ/protocol/openid-connect/token/introspect spring.security.oauth2.resourceserver.opaquetoken.client-id=XXXXXXX spring.security.oauth2.resourceserver.opaquetoken.client-secret=YYYYYYY spring.cloud.dataflow.security.authorization.provider-role-mappings.RedHatSSO.map-oauth-scopes=true -->激活角色映射配置 spring.cloud.dataflow.security.authorization.provider-role-mappings.RedHatSSO.role-mappings.ROLE_CREATE=dataflow.create --> 所有这些属性都将 SCDF 中的每个 ROLE 映射到包含在SSO 服务器检索到的用户信息。 spring.cloud.dataflow.security.authorization.provider-role-mappings.RedHatSSO.role-mappings.ROLE_DEPLOY=dataflow.deploy spring.cloud.dataflow.security.authorization.provider-role-mappings.RedHatSSO.role-mappings.ROLE_DESTROY=dataflow.destroy spring.cloud.dataflow.security.authorization.provider-role-mappings.RedHatSSO.role-mappings.ROLE_MANAGE=dataflow.manage spring.cloud.dataflow.security.authorization.provider-role-mappings.RedHatSSO.role-mappings.ROLE_MODIFY=dataflow.modify spring.cloud.dataflow.security.authorization.provider-role-mappings.RedHatSSO.role-mappings.ROLE_SCHEDULE=dataflow.schedule spring.cloud.dataflow.security.authorization.provider-role-mappings.RedHatSSO.role-mappings.ROLE_VIEW=dataflow.view

最后,SSO 方面的一些注意事项(这可能因使用的工具而异,这是针对 Keycloak/RedHatSSO):

激活所有必要的 URI(令牌、用户信息、自省...)。 为 7 个 SCDF 角色定义 7 个客户端范围。 在 SSO 中为 SCDF 定义一个客户端,其中:激活 服务帐户,为客户端定义所有所需的角色(管理员、操作、普通用户...),分配 7 个 Client Scopes,为 username 字段定义一个 mapper 以避免当它为 null 时出错,并包含 redirect uri (真正的一个,SCDF 的主机名)在 Valid Redirect URIs 列表中(它与 http://myhostname/* 一起使用)。 完成上一点后,将每个客户端范围分配给正确的客户端角色

【讨论】:

以上是关于Spring Cloud Data Flow 安全配置和与 RedHat SSO 的集成的主要内容,如果未能解决你的问题,请参考以下文章

Spring Cloud Data Flow参考指南

Swarm 的 Spring Cloud Data Flow 支持

Spring Cloud Data Flow 的自定义任务中缺少参数

Spring Cloud Data Flow 编辑现有流

Spring Cloud Data Flow Grafana Prometheus 不显示流数据

如何在 Spring Cloud Data Flow 中为 Spring Batch 作业设置调度程序?