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

Spring Cloud Data Flow security configuracion and integration with RedHat SSO

我们正尝试按照文档 (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 有限制?

根据文档,我们设置了这些属性:

所以我们有一些考虑:

最后,我们在 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中转换introspect uri。

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

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

我相信只要使用 issuer-urijwk-set-uri 就可以为您提供一个有效的设置(您仍然需要找出角色映射的范围),因为 Spring 安全部门正在使用这些来自动配置 oauth 设置。当我们还没有完全使用 Spring Security 5.3 系列时,所有其他设置都有些过时了。

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

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

先对原先的考虑做一些评论:

  • 令牌的内省需要属性 resourceserver.opaquetoken,因此我们非常确定当我们收到 REST 请求时它们是必需的并且它必须具有授权 header --> 即.
  • 如果我们不使用UAA,属性是否应该命名为uaa? --> 只是一个标签,你可以随便放。它创建所有相关属性之间的关系,是出现在登录页面中的文本。
  • 当我们尝试访问 de UI 时,它会重定向到 authorization-uri 因为 authorization-grant-type=authorization_code,所以它会登录在 SSO 中,是这样吗? --> 是的,这显示了一个带有标签 (link) 的页面,该标签在上一点中使用,重定向到您的 SSO 登录页面。
  • 如果我们使用 grant-type 密码,它会直接请求 username/password 登录,它在哪里验证? --> 在旧版本中在 SCDF 中,可以直接在配置文件中设置用户名和密码,但这不再可用。我没有继续研究这个选项,因为 authorization_code 我们让它工作了。
  • user-info 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 服务器的响应中(当它不是 'username' 时)。
  • 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 中到 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 ://我的主机名/*).
  • 完成前一点后,将每个 客户端范围 分配给正确的 客户端角色