1概要


  • Spring Cloud Config

    ** は、複数のアプリケーションや環境にまたがる分散構成を保存および提供するためのSpringのクライアント/サーバーアプローチです。

この構成ストアは、理想的には

Git

バージョン管理下でバージョン管理され、アプリケーション実行時に変更することができます。サポートされているすべての設定ファイル形式を

Environment




PropertySourceまたは@Value


などの構成要素と共に使用するSpringアプリケーションには非常に適していますが、任意のプログラミング言語を実行する環境で使用できます。

今回の記事では、

Git

-based設定サーバーの設定方法、単純な

REST

アプリケーションサーバーでの使用方法、暗号化されたプロパティ値を含む安全な環境の設定方法の例に焦点を当てます。


2プロジェクトの設定と依存関係

いくつかのコードを書く準備をするために、まず2つの新しい

Maven

プロジェクトを作成します。サーバープロジェクトは、


https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.cloud%22%20AND%20a%3A%22spring-cloud-config-に依存しています。

server%22[spring-cloud-config-server]

モジュール、および


https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.boot%22%

20AND%20a%3A%22スプリングブートスターターセキュリティ%22[春ブートスターターセキュリティ]

and


https://search.maven.org/classic/#search%7C1%7Cg%3A%22org

.springframework.boot%22%20AND%20a%3A%22spring-boot-starter-web%22[spring-boot-starter-web]

スターターバンドル:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
    <version>1.1.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>1.4.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>1.4.0.RELEASE</version>
</dependency>

しかし、クライアントプロジェクトの場合は、


https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.cloud%22%20AND%20a%3A%のみが必要になります。

22spring-cloud-starter-config%22[spring-cloud-starter-config]




https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.boot%

22%20AND%20a%3A%22スプリングブートスターターweb%22[スプリングブートスターターwebモジュール]

:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
    <version>1.1.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>1.4.0.RELEASE</version>
</dependency>


3設定サーバーの実装

アプリケーションの主要部分はconfigクラスです。より具体的には/spring-boot-application-configuration[

@ SpringBootApplication

]です。これは

auto-configure

アノテーション__ @ EnableConfigServerを介して必要な設定をすべて引き込みます。

@SpringBootApplication
@EnableConfigServer
public class ConfigServer {

    public static void main(String[]arguments) {
        SpringApplication.run(ConfigServer.class, arguments);
    }
}

今度は、サーバーがlistenしているサーバー

port

と、バージョン管理された設定内容を提供する

Git

-urlを設定する必要があります。後者は、

http



ssh

、またはローカルファイルシステム上の単純な

file

などのプロトコルで使用できます。

  • ヒント:** 同じ設定リポジトリを指す複数の設定サーバーインスタンスを使用する予定の場合は、リポジトリをローカルの一時フォルダに複製するようにサーバーを設定できます。しかし、2要素認証を使用するプライベートリポジトリには注意が必要です。取り扱いが困難です。そのような場合は、ローカルのファイルシステムにクローンを作成してコピーを操作する方が簡単です。

利用可能な

リポジトリURLを設定するための

プレースホルダ変数と検索パターン__もあります。しかし、これは私たちの記事の範囲を超えています。あなたが興味を持っているなら、公式ドキュメントは始めるのに良い場所です。

また、アプリケーションを再起動するたびに自動生成されるパスワードを避けるために、

application.properties



Basic-Authentication

のユーザー名とパスワードを設定する必要があります。

server.port=8888
spring.cloud.config.server.git.uri=ssh://localhost/config-repo
spring.cloud.config.server.git.clone-on-start=true
security.user.name=root
security.user.password=s3cr3t


4設定ストレージとしてのGitリポジトリ

私たちのサーバーを完成させるために、設定されたURLの下で

Git

リポジトリを初期化し、いくつかの新しいプロパティファイルを作成し、それらをいくつかの値で普及させる必要があります。

設定ファイルの名前は通常のSpring

application.properties

のように構成されていますが、 ‘application’という単語の代わりに設定された名前、例えばクライアントのプロパティ

spring.application.name’

の値が使用され、その後にダッシュとアクティブプロファイルが続きます。例えば:

$> git init
$> echo 'user.role=Developer' > config-client-development.properties
$> echo 'user.role=User'      > config-client-production.properties
$> git add .
$> git commit -m 'Initial config-client properties'

  • トラブルシューティング:**

    ssh

    関連の認証問題が発生した場合は、sshサーバーで

    〜/.ssh/known

    hosts



    〜/.ssh/authorized

    keys

    を再確認してください。


5設定の問い合わせ

これでサーバーを起動できました。私たちのサーバーが提供する

Git

-supported設定APIは以下のパスを使って問い合わせることができます。

----/{application}/{profile}[/{label}]/{application}-{profile}.yml/{label}/{application}-{profile}.yml/{application}-{profile}.properties/{label}/{application}-{profile}.properties
----


\ {label}

プレースホルダーはGitブランチを、

\ {application}

はクライアントのアプリケーション名を、

\ {profile}

はクライアントの現在アクティブなアプリケーションプロファイルを表します。

それで、私たちはブランチ

master

で開発プロファイルの下で走っている私たちの計画された設定クライアントのための設定を取得することができます:

$> curl http://root:[email protected]:8888/config-client/development/master


6. クライアント実装

次に、クライアントの面倒を見ましょう。これは非常に単純なクライアントアプリケーションで、1つの

GET

メソッドを持つ

REST

コントローラで構成されています。

サーバーを取得するための構成は、

bootstrap.application

という名前のリソースファイルに配置する必要があります。このファイルは(名前が示すように)アプリケーションの起動時に非常に早く読み込まれるためです。

@SpringBootApplication
@RestController
public class ConfigClient {

    @Value("${user.role}")
    private String role;

    public static void main(String[]args) {
        SpringApplication.run(ConfigClient.class, args);
    }

    @RequestMapping(
      value = "/whoami/{username}",
      method = RequestMethod.GET,
      produces = MediaType.TEXT__PLAIN__VALUE)
    public String whoami(@PathVariable("username") String username) {
        return String.format("Hello!
          You're %s and you'll become a(n) %s...\n", username, role);
    }
}

アプリケーション名に加えて、アクティブプロファイルと接続詳細もb

__ootstrap.properties

__に入れます。

spring.application.name=config-client
spring.profiles.active=development
spring.cloud.config.uri=http://localhost:8888
spring.cloud.config.username=root
spring.cloud.config.password=s3cr3t

テストするために、設定が私たちのサーバーから正しく受け取られていて、

role value

が私たちのコントローラーメソッドにインジェクトされた場合、クライアントをブートした後にそれを単にカールさせます:

$> curl http://localhost:8080/whoami/Mr__Pink

応答が次のようなものであれば、

Spring Cloud Config Server

とそのクライアントは今のところうまく機能しています。

Hello! You're Mr__Pink and you'll become a(n) Developer...


7. 暗号化と復号化

  • 要件** :Springの暗号化および復号化機能と共に暗号的に強力な鍵を使用するには、

    JVMに

    Java Cryptography Extension(JCE)無制限強度管轄ポリシーファイルが必要です。/www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html[Oracle]。

インストールするには、ダウンロードに含まれている指示に従ってください。 Linuxディストリビューションの中には、パッケージマネージャを介してインストール可能なパッケージを提供するものもあります。

設定サーバーはプロパティ値の暗号化と復号化をサポートしているので、ユーザー名やパスワードなどの機密データ用のストレージとしてパブリックリポジトリを使用できます。暗号化された値の先頭には文字列

\ {cipher}

があり、サーバーが対称鍵または鍵ペアを使用するように構成されている場合は、パス__ ‘/encrypt’へのREST呼び出しによって生成できます。

復号化するためのエンドポイントも利用可能です。両方のエンドポイントは、アプリケーションの名前とその現在のプロファイルのプレースホルダーを含むパスを受け入れます:

´/** /\ {name}/\ {profile}’

。これは、クライアントごとに暗号化方式を制御するのに特に便利です。しかし、それらが有用になる前に、あなたは我々が次のセクションで行うであろう暗号化キーを設定しなければならない。

  • ヒント:** curlを使用して暗号化/復号化APIを呼び出す場合は、(

    – data/-d

    ではなく)

    – data-urlencode

    オプションを使用するか、または明示的に ‘Content-Type’ヘッダーを設定してください。

    ‘text/plain’

    。これにより、暗号化された値に含まれる「」などの特殊文字を正しく処理できます。

クライアントを介してフェッチしている間に値が自動的に復号化されない場合は、その

key

の名前の前に「invalid」という語が付いた名前に変更されます。これは、例えば、暗号化された値をパスワードとして使用するのを防ぎます。

  • ヒント:** YAMLファイルを含むリポジトリをセットアップするときは、暗号化されたプレフィックスの付いた値を一重引用符で囲む必要があります。プロパティでは、これは当てはまりません。


7.1. 鍵管理

設定サーバーはデフォルトで対称または非対称の方法でプロパティ値を暗号化することができます。

  • 対称暗号化** を使用するには、

    application.properties



    encrypt.keyプロパティをあなたが選んだ秘密に設定するだけです。あるいは、環境変数

    ENCRYPT

    KEY

    を渡すこともできます。

  • 非対称暗号化** の場合は、

    encrypt.key



    PEM

    エンコードされた文字列値に設定するか、使用する

    keystore

    を設定できます。

デモサーバーには高度に安全な環境が必要なので、後者のオプションを選択し、最初にJavaの

keytool

を使用して

RSA

キーペアを含む新しいキーストアを生成します。

$> keytool -genkeypair -alias config-server-key \
       -keyalg RSA -keysize 4096 -sigalg SHA512withRSA \
       -dname 'CN=Config Server,OU=Spring Cloud,O=Baeldung' \
       -keypass my-k34-s3cr3t -keystore config-server.jks \
       -storepass my-s70r3-s3cr3t

その後、作成したキーストアをサーバーの

application.properties

に追加して再実行します。

encrypt.key-store.location=classpath:/config-server.jks
encrypt.key-store.password=my-s70r3-s3cr3t
encrypt.key-store.alias=config-server-key
encrypt.key-store.secret=my-k34-s3cr3t

次のステップとして、暗号化エンドポイントに問い合わせて、レスポンスを値としてリポジトリの設定に追加します。

$> export PASSWORD=$(curl -X POST --data-urlencode d3v3L \
       http://root:[email protected]:8888/encrypt)
$> echo "user.password=$PASSWORD" >> config-client-development.properties
$> git commit -am 'Added encrypted password'
$> curl -X POST http://root:[email protected]:8888/refresh

テストするには、セットアップが正しく機能しているかどうか、

ConfigClient

クラスを変更してクライアントを再起動します。

@SpringBootApplication
@RestController
public class ConfigClient {

    ...

    @Value("${user.password}")
    private String password;

    ...
    public String whoami(@PathVariable("username") String username) {
        return String.format("Hello!
          You're %s and you'll become a(n) %s, " +
          "but only if your password is '%s'!\n",
          username, role, password);
    }
}

設定値が正しく復号化されていれば、クライアントに対する最後のクエリで表示されます。

$> curl http://localhost:8080/whoami/Mr__Pink
Hello! You're Mr__Pink and you'll become a(n) Developer, \
  but only if your password is 'd3v3L'!

** 7.2. 複数のキーを使う

暗号化と復号化に複数の鍵を使用したい場合(例えば、提供されるアプリケーションごとに専用の鍵)、

\ {cipher}

接頭部と

\ {cipher}

接頭部の間に

\ {name:value}

の形式の接頭部を追加できます

BASE64

でエンコードされたプロパティ値

設定サーバは

\ {secret:my-crypto-secret}



\ {key:my-key-alias}

のような接頭辞をすぐに使えます。後者のオプションでは、

application.properties

に設定済みのキーストアが必要です。このキーストアで一致するキーエイリアスが検索されます。

user.password={cipher}{secret:my-499-s3cr3t}AgAMirj1DkQC0WjRv...
user.password={cipher}{key:config-client-key}AgAMirj1DkQC0WjRv...

キーストアのないシナリオでは、ルックアップを処理して各キーの

TextEncryptor

オブジェクトを返す

TextEncryptorLocator

タイプの

@ Bean

を実装する必要があります。


7.3. 暗号化されたプロパティを配信する

サーバー側の暗号化を無効にし、プロパティ値の復号化をローカルで処理する場合は、サーバーの

application.properties

に次のように入力します。

spring.cloud.config.server.encrypt.enabled=false

さらに、他のすべての「encrypt。** 」プロパティを削除して

REST

エンドポイントを無効にすることもできます。


8結論

これで、

Git

リポジトリからクライアントアプリケーションに一連の設定ファイルを提供するための設定サーバーを作成できました。

そのようなサーバーでできることが他にもいくつかあります。

例えば:


  • JSONの代わりに

    YAML

    または

    Properties__形式で設定を提供する

プレースホルダも解決されています。設定が

PropertySource

に直接マップされていない、Spring以外の環境で使用する場合に便利です。

  • プレーンテキストの設定ファイルを提供します – 順番にオプションで

解決されたプレースホルダこれは例えば環境に依存するロギング設定を提供するのに役立ちます。

  • 設定サーバーをアプリケーションに組み込み、そこで設定します。

クライアントにサービスを提供するスタンドアロンのアプリケーションとして実行されるのではなく、

Git

リポジトリから自身を実行します。そのため、いくつかのブートストラッププロパティを設定したり、

@ EnableConfigServer

アノテーションを削除したりする必要があります。これはユースケースによって異なります。

  • Spring Netflix Eurekaサービスで設定サーバーを利用可能にする

設定クライアントの自動サーバー検出を有効にして有効にします。これは、サーバーに固定位置がない場合、またはサーバーがその位置に移動する場合に重要になります。

最後に、この記事のソースコード


on Github


を見つけてください。