Snelle introductie tot Spring Cloud-configuratie

1. Overzicht

Spring Cloud Config is Spring's client / server-benadering voor het opslaan en bedienen van gedistribueerde configuraties over meerdere applicaties en omgevingen.

Dit configuratiearchief is idealiter onder versie van Git versiebeheer en kan tijdens de runtime van de toepassing worden gewijzigd. Hoewel het heel goed past in Spring-applicaties die alle ondersteunde configuratiebestandsindelingen gebruiken, samen met constructies zoals Milieu, PropertySource of @Value, het kan worden gebruikt in elke omgeving met elke programmeertaal.

In dit artikel zullen we ons concentreren op een voorbeeld van hoe u een Git-backed config-server, gebruik het in een eenvoudige RUST UIT applicatieserver en het opzetten van een veilige omgeving inclusief versleutelde eigenschapswaarden.

2. Projectconfiguratie en afhankelijkheden

Om voor te bereiden op het schrijven van wat code, maken we twee nieuwe Maven projecten eerst. Het serverproject vertrouwt op het spring-cloud-config-server module, evenals de spring-boot-starter-security en spring-boot-starter-web startersbundels:

 org.springframework.cloud spring-cloud-config-server org.springframework.boot spring-boot-starter-security org.springframework.boot spring-boot-starter-web 

Voor het klantproject hebben we echter alleen de spring-cloud-starter-config en de spring-boot-starter-webmodules:

 org.springframework.cloud spring-cloud-starter-config org.springframework.boot spring-boot-starter-web 

3. Een Config Server-implementatie

Het grootste deel van de applicatie is een configuratieklasse - meer specifiek een @SpringBootApplication - die alle vereiste instellingen binnenhaalt via de automatisch configureren annotatie @EnableConfigServer:

@SpringBootApplication @EnableConfigServer openbare klasse ConfigServer {openbare statische leegte hoofd (String [] argumenten) {SpringApplication.run (ConfigServer.class, argumenten); }} 

Nu moeten we de server configureren haven waarop onze server luistert en een Git-url die onze versie-gecontroleerde configuratie-inhoud biedt. Dit laatste kan worden gebruikt met protocollen zoals http, ssh of een simpele het dossier op een lokaal bestandssysteem.

Tip: Als u van plan bent om meerdere configuratieserverinstanties te gebruiken die naar dezelfde configuratieopslagplaats verwijzen, kunt u de server configureren om uw opslagplaats naar een lokale tijdelijke map te klonen. Maar let op privérepository's met tweefactorauthenticatie, ze zijn moeilijk te hanteren! In dat geval is het gemakkelijker om ze op uw lokale bestandssysteem te klonen en met de kopie te werken.

Er zijn er ook enkele placeholder variabelen en zoekpatronen voor het configureren van het repository-url beschikbaar; maar dit valt buiten het bestek van ons artikel. Als u geïnteresseerd bent, is de officiële documentatie een goede plek om te beginnen.

We moeten ook een gebruikersnaam en wachtwoord instellen voor het Basisverificatie in onze application.properties om een ​​automatisch gegenereerd wachtwoord te vermijden bij elke herstart van de applicatie:

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

4. Een Git-opslagplaats als configuratie-opslag

Om onze server te voltooien, moeten we een Git repository onder de geconfigureerde url, maak enkele nieuwe eigenschappenbestanden aan en maak ze populair met enkele waarden.

De naam van het configuratiebestand is opgebouwd als een normale Spring application.properties, maar in plaats van het woord ‘applicatie 'een geconfigureerde naam, bijv. de waarde van het onroerend goed ‘Spring.application.name ' van de client wordt gebruikt, gevolgd door een streepje en het actieve profiel. Bijvoorbeeld:

$> git init $> echo 'user.role = Developer'> config-client-development.properties $> echo 'user.role = Gebruiker'> config-client-production.properties $> git add. $> git commit -m 'Initiële configuratie-client eigenschappen'

Probleemoplossen: Als je tegenkomt ssh-gerelateerde authenticatieproblemen, dubbele controle ~ / .ssh / bekende_hosts en ~ / .ssh / geautoriseerde_toetsen op uw SSH-server!

5. Opvragen van de configuratie

Nu kunnen we onze server starten. De Git-gebaseerde configuratie-API die door onze server wordt geleverd, kan worden opgevraagd met behulp van de volgende paden:

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

Waarin de {etiket} placeholder verwijst naar een Git branch, {toepassing} naar de toepassingsnaam van de client en het {profiel} naar het huidige actieve applicatieprofiel van de klant.

We kunnen dus de configuratie ophalen voor onze geplande configuratieclient die onder het ontwikkelprofiel in de branch draait meester via:

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

6. De implementatie van de klant

Laten we vervolgens voor de klant zorgen. Dit wordt een zeer eenvoudige clienttoepassing, bestaande uit een RUST UIT controller met een KRIJGEN methode.

De configuratie, om onze server op te halen, moet in een bronbestand met de naam worden geplaatst bootstrap.application, omdat dit bestand (zoals de naam al aangeeft) heel vroeg zal worden geladen terwijl de applicatie start:

@SpringBootApplication @RestController openbare klasse ConfigClient {@Value ("$ {user.role}") privé String-rol; openbare statische leegte hoofd (String [] args) {SpringApplication.run (ConfigClient.class, args); } @GetMapping (value = "/ whoami / {gebruikersnaam}", produceert = MediaType.TEXT_PLAIN_VALUE) openbare String whoami (@PathVariable ("gebruikersnaam") String gebruikersnaam) {return String.format ("Hallo! Je bent% s en je wordt een (n)% s ... \ n ", gebruikersnaam, rol); }}

Naast de naam van de applicatie zetten we ook het actieve profiel en de verbindingsgegevens in ons bootstrap.properties:

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

Om te testen of de configuratie correct is ontvangen van onze server en het rolwaarde wordt geïnjecteerd in onze controllermethode, we krullen het eenvoudigweg na het opstarten van de client:

$> curl // localhost: 8080 / whoami / Mr_Pink

Als het antwoord als volgt is, is onze Spring Cloud Config Server en de klant werkt voorlopig prima:

Hallo! Jij bent Mr_Pink en je wordt een (n) Developer ...

7. Versleuteling en ontsleuteling

Vereiste: Om cryptografisch sterke sleutels samen met Spring-coderings- en decoderingsfuncties te gebruiken, hebt u de ‘Java Cryptography Extension (JCE) Onbeperkte machtsbeleidsbestanden voor jurisdictie ' geïnstalleerd in uw JVM. Deze zijn bijvoorbeeld te downloaden bij Oracle. Volg de instructies bij de download om te installeren. Sommige Linux-distributies bieden ook een installeerbaar pakket via hun pakketbeheerders.

Omdat de configuratieserver codering en decodering van eigenschapswaarden ondersteunt, kunt u openbare opslagplaatsen gebruiken als opslag voor gevoelige gegevens zoals gebruikersnamen en wachtwoorden. Versleutelde waarden worden voorafgegaan door de tekenreeks {cijfer} en kan worden gegenereerd door een REST-oproep naar het pad ‘/ Versleutelen ', als de server is geconfigureerd om een ​​symmetrische sleutel of een sleutelpaar te gebruiken.

Er is ook een te decoderen eindpunt beschikbaar. Beide eindpunten accepteren een pad met tijdelijke aanduidingen voor de naam van de toepassing en het huidige profiel: ‘/ * / {Naam} / {profiel} '. Dit is vooral handig voor het beheren van cryptografie per client. Voordat ze echter nuttig worden, moet u een cryptografische sleutel configureren, wat we in de volgende sectie zullen doen.

Tip: Als u curl gebruikt om de en- / decryptie-API aan te roepen, is het beter om de –Data-urlencode optie (in plaats van –Gegevens / -d), of stel de koptekst ‘Content-Type 'expliciet in op ‘Tekst / gewoon '. Dit zorgt voor een correcte afhandeling van speciale tekens zoals ‘+ 'in de gecodeerde waarden.

Als een waarde niet automatisch kan worden ontsleuteld tijdens het ophalen via de client, is het sleutel wordt hernoemd met de naam zelf, voorafgegaan door het woord ‘ongeldig '. Dit zou bijvoorbeeld het gebruik van een versleutelde waarde als wachtwoord moeten voorkomen.

Tip: Bij het opzetten van een repository die YAML-bestanden bevat, moet u uw gecodeerde en voorvoegsels plaatsen met enkele aanhalingstekens! Bij Properties is dit niet het geval.

7.1. CSRF

Spring Security schakelt standaard CSRF-bescherming in voor alle verzoeken die naar onze applicatie worden gestuurd.

Daarom om het / versleutelen en / decoderen eindpunten, laten we de CSRF voor hen uitschakelen:

@Configuration public class SecurityConfiguration breidt WebSecurityConfigurerAdapter uit {@Override public void configure (HttpSecurity http) genereert uitzondering {http.csrf () .ignoringAntMatchers ("/ encrypt / **") .ignoringAntMatchers ("/ decrypt / **"); super.configure (http); }}

7.2. Sleutelbeheer

De configuratieserver is standaard ingeschakeld om eigenschapswaarden op een symmetrische of asymmetrische manier te versleutelen.

Om symmetrische cryptografie te gebruiken, u hoeft alleen de eigenschap in te stellen ‘Encrypt.key ' in uw application.properties naar een geheim naar keuze. Als alternatief kunt u de omgevingsvariabele doorgeven ENCRYPT_KEY.

Voor asymmetrische cryptografie, u kunt instellen ‘Encrypt.key ' naar een PEM-gecodeerde tekenreekswaarde of configureer een keystore gebruiken.

Omdat we een sterk beveiligde omgeving nodig hebben voor onze demo-server, hebben we voor de laatste optie gekozen en een nieuwe keystore gegenereerd, inclusief een RSA sleutelpaar, met de Java belangrijk hulpmiddel eerste:

$> 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 mijn-s70r3-s3cr3t

Daarna voegen we de aangemaakte keystore toe aan onze server bootstrap.properties en voer het opnieuw uit:

encrypt.keyStore.location = klassepad: /config-server.jks encrypt.keyStore.password = mijn-s70r3-s3cr3t encrypt.keyStore.alias = config-serversleutel encrypt.keyStore.secret = mijn-k34-s3cr3t

Als volgende stap kunnen we het encryptie-eindpunt opvragen en het antwoord als waarde toevoegen aan een configuratie in onze repository:

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

Om te testen of onze setup correct werkt, passen we het ConfigClient class en herstart onze client:

@SpringBootApplication @RestController openbare klasse ConfigClient {... @Value ("$ {user.password}") privé String-wachtwoord; ... public String whoami (@PathVariable ("gebruikersnaam") String gebruikersnaam) {return String.format ("Hallo! Je bent% s en je wordt een (n)% s," + "maar alleen als je wachtwoord is '% s'! \ n ", gebruikersnaam, rol, wachtwoord); }}

Een laatste vraag aan onze client zal ons laten zien of onze configuratiewaarde correct wordt gedecodeerd:

$> curl // localhost: 8080 / whoami / Mr_Pink Hallo! Je bent Mr_Pink en je wordt een (n) Developer, \ maar alleen als je wachtwoord 'd3v3L' is!

7.3. Meerdere sleutels gebruiken

Als u meerdere sleutels wilt gebruiken voor versleuteling en ontsleuteling, bijvoorbeeld: een speciale sleutel voor elke aangeboden toepassing, kunt u een ander voorvoegsel toevoegen in de vorm van {naam: waarde} tussen de {cijfer} prefix en de BASE64-gecodeerde eigenschapswaarde.

De configuratieserver begrijpt voorvoegsels zoals {geheim: mijn-crypto-geheim} of {key: my-key-alias} bijna out-of-the-box. De laatste optie heeft een geconfigureerde keystore nodig in uw application.properties. Deze keystore wordt doorzocht op een overeenkomende sleutelalias. Bijvoorbeeld:

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

Voor scenario's zonder keystore moet u een @Boon van het type TextEncryptorLocator die de opzoeking afhandelt en een TextEncryptor-Object voor elke sleutel.

7.4. Versleutelde eigenschappen aanbieden

Als u server-side cryptografie wilt uitschakelen en de decodering van eigenschapswaarden lokaal wilt afhandelen, kunt u het volgende in uw server plaatsen application.properties:

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

Bovendien kunt u alle andere ‘encrypt. * '- eigenschappen verwijderen om het RUST UIT eindpunten.

8. Conclusie

Nu kunnen we een configuratieserver maken om een ​​set configuratiebestanden van een Git repository naar clienttoepassingen. Er zijn een paar andere dingen die u kunt doen met zo'n server.

Bijvoorbeeld:

  • Serveer configuratie in YAML of Eigendommen formaat in plaats van JSON - ook met opgeloste tijdelijke aanduidingen. Wat handig kan zijn bij gebruik in niet-Spring-omgevingen, waar de configuratie niet direct is toegewezen aan een PropertySource.
  • Serveer configuratiebestanden in platte tekst - op hun beurt optioneel met opgeloste tijdelijke aanduidingen. Dit kan bijvoorbeeld handig zijn om een ​​omgevingsafhankelijke logconfiguratie te bieden.
  • Sluit de configuratieserver in een applicatie in, waar deze zichzelf configureert vanuit een Git repository, in plaats van te draaien als een zelfstandige applicatie die clients bedient. Daarom moeten sommige bootstrap-eigenschappen worden ingesteld en / of de @EnableConfigServer annotatie moet worden verwijderd, afhankelijk van het gebruik.
  • Maak de configuratieserver beschikbaar bij Spring Netflix Eureka-serviceherkenning en schakel automatische serverdetectie in configuratieclients in. Dit wordt belangrijk als de server geen vaste locatie heeft of op zijn locatie beweegt.

En om af te ronden, vindt u de broncode van dit artikel op Github.


$config[zx-auto] not found$config[zx-overlay] not found