java - 使用@ConfigurationProperties读取CF环境嵌套JSON

标签 java spring spring-boot cloud-foundry configuration-files

我在 SpringBoot 上有一个部署到 Cloud Foundry 的应用程序。它有一个绑定(bind)服务,将一些信息附加到 VCAP_SERVICES,我可以在 application.properties 文件中使用这些信息来接收安全相关数据。

此服务变量位于整个 VCAP_SERVICE 环境变量的用户提供的子 json 中,如下所示:

  "user-provided": [
   {
    "credentials": {
     "auth-scopes": {
      "group-1": "superadmin",
      "group-2": "admin"
     },
     "base64ClientCredential": "SSBBTSBOT1QgVEhBVCBTSUxMWSA6LUQ=",
     "client-id": "my-app",
     "client-secret": "g1234567890",
     "token-info-uri": "https://XYZ.predix.io/check_token",
     "user-info-uri": "https://XYZ.predix.io/userinfo"
    },
    "label": "user-provided",
    "name": "my-app-creds",
    "syslog_drain_url": "",
    "tags": [],
    "volume_mounts": []
   }
  ]

在我的 application.properties 中我有

security.properties.client-id=${vcap.services.my-app-creds.credentials.client-id}
security.properties.client-secret=${vcap.services.my-app-creds.credentials.client-secret}
security.properties.token-info-uri=${vcap.services.my-app-creds.credentials.token-info-uri}
security.properties.user-info-uri=${vcap.services.my-app-creds.credentials.user-info-uri}
security.properties.auth-scopes=${vcap.services.my-app-creds.credentials.auth-scopes}

我还创建了类SecurityProperties来读取这些属性并存储在JAVA中:

@Component
@PropertySource("classpath:application.properties")
@ConfigurationProperties(prefix = "security.properties")
public class SecurityProperties {

    String clientId;
    String clientSecret;
    String tokenInfoUri;
    String userInfoUri;

    //Required getters and setters
}

此类成功地将这些字段绑定(bind)到从 application.properties 接收的信息。

当我想接收 map 时出现问题:

 "auth-scopes": {
  "group-1": "superadmin",
  "group-2": "admin"
 }

我尝试添加到 SecurityProperties 类字段:

HashMap<String, String> authScopes;

但是失败了

我也尝试过内部类

AuthScopes authScopes;

public static class AuthScopes {
    //various different implementations
    //to read this but no success at all
}

我没有其他想法了。我只是不知道如何得到这个。我还将接受来自 VCAPSauth-scopes json 将被读取为字符串,然后我将解析它 - 没问题。问题是,即使我添加到 SecurityProperties 字段 String authScopes 它也与以下字符串绑定(bind):"${vcap.services.my-app-creds .credentials.auth-scopes}”。没什么用处。

如果您有任何想法 - 请分享。

最佳答案

Spring Boot 通过 CloudFoundryVcapEnvironmentPostProcessor 提供 vcap. 属性。该类读取 VCAP_SERVICES JSON 并将其展平为一组离散属性。如果添加 Spring Boot actuators添加到您的应用程序并访问 /env 端点,您将看到创建的一组 vcap. 属性。

在您的示例中,属性将包含以下值:

"vcap": {
  ...
  "vcap.services.my-app-creds.credentials.auth-scopes.group-1": "******",
  "vcap.services.my-app-creds.credentials.auth-scopes.group-2": "******",
}

该列表中没有 vcap.services.my-service.credentials.auth-scopes 属性,因为 JSON 已完全扁平化。属性名称使用点表示法来反射(reflect) JSON 结构,但属性集中不保留层次结构。简而言之,您尝试执行的操作不适用于启动属性。

一种替代方法是将这些值设置为字符串,而不是 JSON 中的哈希值,如 "auth-scopes": "group-1:superadmin,group-2:admin""auth-scopes": "group-1=superadmin,group-2=admin"。然后,您的 SecurityProperties 可以获取 vcap.services.my-service.credentials.auth-scopes 的值并将字符串解析为映射。

关于java - 使用@ConfigurationProperties读取CF环境嵌套JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46936991/

相关文章:

spring - Gitlab CI 无法将 spring 应用程序连接到 postgres

java - Spring 应用程序的正确入口点是什么?

java - Spring Boot数据,MongoDB不返回结果

Java Mail 正在显示 <h2> 文本

java - 为什么不对 JSF 页面进行预编译(至少部分),而是在每次构建 View 时对其进行解析和评估?

java - SortedSet 上的 Guava Joiner

Spring-AMQP 和直接回复

java - MockMvc 使用模拟 session 绕过安全

java - 为什么我的 @Scheduled Spring Boot 任务在 Azure 中运行不一致?

java - 将线程安全对象放在 ThreadLocal 上有什么好处吗?