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

Read CF environment nested JSON with @ConfigurationProperties

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

此服务变量位于整个 VCAP_SERVICE 环境变量的 user-provided 子 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}

我还创建了 class 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
}

并且这个 class 成功地将这些字段绑定到从 application.properties 收到的信息。

我要接收地图时出现问题:

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

我尝试添加到 SecurityProperties class 字段:

HashMap<String, String> authScopes;

但是失败了

我也试过内部 class

AuthScopes authScopes;

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

我运行出了别的想法。我只是不知道如何得到这个。我还将接受 VCAPS 中的 auth-scopes json 将被读取为字符串,然后我将解析它 - 没问题。问题是,即使我添加到 SecurityProperties 字段 String authScopes,它也恰好与这个字符串绑定:"${vcap.services.my-app-creds.credentials.auth-scopes}"。没什么用。

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

Spring Boot 通过 CloudFoundryVcapEnvironmentPostProcessor. That class reads the VCAP_SERVICES JSON and flattens it into a set of discrete properties. If you add Spring Boot actuators 向您的应用程序提供 vcap. 属性并访问 /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 完全变平了。 属性 名称使用点符号来反映 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 的值并将字符串解析为映射。