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-uri 和 jwk-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 的集成的主要内容,如果未能解决你的问题,请参考以下文章
Swarm 的 Spring Cloud Data Flow 支持
Spring Cloud Data Flow 的自定义任务中缺少参数