Rask introduksjon til Spring Cloud Configuration

1. Oversikt

Spring Cloud Config er Spring's klient / server tilnærming for lagring og servering av distribuerte konfigurasjoner i flere applikasjoner og miljøer.

Denne konfigurasjonsbutikken er ideelt versjonert under Git versjonskontroll og kan endres ved programkjøring. Selv om det passer veldig bra i vårapplikasjoner som bruker alle støttede konfigurasjonsfilformater sammen med konstruksjoner som Miljø, PropertySource eller @Value, den kan brukes i ethvert miljø som kjører hvilket som helst programmeringsspråk.

I denne oppskriften vil vi fokusere på et eksempel på hvordan du setter opp en Git-backed config server, bruk den på en enkel HVILE applikasjonsserver og sette opp et sikkert miljø inkludert krypterte eiendomsverdier.

2. Prosjektoppsett og avhengigheter

For å gjøre deg klar for å skrive litt kode, lager vi to nye Maven prosjekter først. Serverprosjektet er avhengig av spring-cloud-config-server modul, samt vår-boot-starter-sikkerhet og spring-boot-starter-web startpakker:

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

Men for klientprosjektet trenger vi bare spring-cloud-starter-config og vår-boot-starter-web-moduler:

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

3. En Config Server-implementering

Hoveddelen av applikasjonen er en konfigurasjonsklasse - nærmere bestemt en @SpringBootApplication - som trekker i alt nødvendig oppsett gjennom automatisk konfigurering kommentar @EnableConfigServer:

@SpringBootApplication @EnableConfigServer offentlig klasse ConfigServer {public static void main (String [] argumenter) {SpringApplication.run (ConfigServer.class, argumenter); }} 

Nå må vi konfigurere serveren havn som serveren vår lytter til og en Git-url som gir vårt versjonskontrollerte konfigurasjonsinnhold. Sistnevnte kan brukes med protokoller som http, ssh eller en enkel fil på et lokalt filsystem.

Tips: Hvis du planlegger å bruke flere konfigurasjonsserverforekomster som peker til samme konfigurasjonsdatabase, kan du konfigurere serveren til å klone repoen din i en lokal midlertidig mappe. Men vær oppmerksom på private arkiver med tofaktorautentisering, de er vanskelige å håndtere! I et slikt tilfelle er det lettere å klone dem på det lokale filsystemet og jobbe med kopien.

Det er også noen plassholdervariabler og søkemønstre for å konfigurere depot-url tilgjengelig; men dette er utenfor omfanget av artikkelen vår. Hvis du er interessert, er den offisielle dokumentasjonen et godt sted å starte.

Vi må også angi et brukernavn og et passord for Grunnleggende autentisering i vår application.properties for å unngå et automatisk generert passord ved hver applikasjonsstart:

server.port = 8888 spring.cloud.config.server.git.uri = ssh: // localhost / config-repo spring.cloud.config.server.git.clone-on-start = true spring.security.user.name = rotfjær.sikkerhet.bruker.passord = s3cr3t

4. Et Git Repository som konfigurasjonslagring

For å fullføre serveren vår, må vi initialisere en Git lager under den konfigurerte url, lage noen nye eiendomsfiler og popularisere dem med noen verdier.

Navnet på konfigurasjonsfilen er sammensatt som en vanlig vår application.properties, men i stedet for ordet ‘applikasjon’ et konfigurert navn, f.eks. verdien av eiendommen ‘Vår.applikasjon.navn’ av klienten brukes, etterfulgt av en bindestrek og den aktive profilen. For eksempel:

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

Feilsøking: Hvis du støter på ssh-relaterte autentiseringsproblemer, dobbeltsjekk ~ / .ssh / kjent_hosts og ~ / .ssh / autoriserte_taster på ssh-serveren din!

5. Spørring av konfigurasjonen

Nå kan vi starte serveren vår. De Git-backed konfigurasjons-API gitt av serveren vår kan spørres ved hjelp av følgende baner:

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

I hvilken {merkelapp} plassholder refererer til en Git-gren, {applikasjon} til klientens applikasjonsnavn og {profil} til klientens nåværende aktive applikasjonsprofil.

Så vi kan hente konfigurasjonen for den planlagte konfigurasjonsklienten vår som kjører under utviklingsprofil i grenen herre via:

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

6. Klientimplementeringen

La oss ta vare på klienten. Dette vil være en veldig enkel klientapplikasjon, bestående av en HVILE kontroller med en metode.

Konfigurasjonen, for å hente serveren vår, må plasseres i en ressursfil med navnet bootstrap.application, fordi denne filen (som navnet tilsier) lastes inn veldig tidlig mens applikasjonen starter:

@SpringBootApplication @ RestController offentlig klasse ConfigClient {@Value ("$ {user.role}") privat streng rolle; public static void main (String [] args) {SpringApplication.run (ConfigClient.class, args); } @GetMapping (value = "/ whoami / {brukernavn}", produserer = MediaType.TEXT_PLAIN_VALUE) offentlig String whoami (@PathVariable ("brukernavn") String brukernavn) {return String.format ("Hei! Du er% s og du blir en (n)% s ... \ n ", brukernavn, rolle); }}

I tillegg til applikasjonsnavnet legger vi også den aktive profilen og tilkoblingsdetaljene i vår bootstrap.properties:

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

For å teste om konfigurasjonen er riktig mottatt fra serveren vår og rolleverdi blir injisert i vår kontrollermetode, vi bare krøller den etter oppstart av klienten:

$> krøll // localhost: 8080 / whoami / Mr_Pink

Hvis svaret er som følger, er vårt Spring Cloud Config Server og klienten fungerer bra for nå:

Hallo! Du er Mr_Pink og du vil bli en (n) utvikler ...

7. Kryptering og dekryptering

Krav: For å bruke kryptografisk sterke nøkler sammen med Spring-kryptering og dekrypteringsfunksjoner trenger du ‘Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files’ installert i din JVM. Disse kan lastes ned for eksempel fra Oracle. Følg instruksjonene i nedlastingen for å installere. Noen Linux-distribusjoner gir også en installerbar pakke gjennom deres pakkeforvaltere.

Siden konfigurasjonsserveren støtter kryptering og dekryptering av eiendomsverdier, kan du bruke offentlige arkiver som lagring for sensitive data som brukernavn og passord. Krypterte verdier er prefikset med strengen {cipher} og kan genereres ved en REST-samtale til stien ‘/ Kryptere’, hvis serveren er konfigurert til å bruke en symmetrisk nøkkel eller et nøkkelpar.

Et sluttpunkt for å dekryptere er også tilgjengelig. Begge endepunktene godtar en bane som inneholder plassholdere for navnet på programmet og dets nåværende profil: ‘/ * / {Name} / {profile} '. Dette er spesielt nyttig for å kontrollere kryptografi per klient. Men før de blir nyttige, må du konfigurere en kryptografisk nøkkel som vi vil gjøre i neste avsnitt.

Tips: Hvis du bruker curl for å ringe en- / dekryptering API, er det bedre å bruke –Data-urlencode alternativ (i stedet for –Data / -d), eller sett overskriften 'Content-Type' eksplisitt til ‘Tekst / vanlig’. Dette sikrer korrekt håndtering av spesialtegn som ‘+’ i de krypterte verdiene.

Hvis en verdi ikke kan dekrypteres automatisk mens den hentes gjennom klienten, er dens nøkkel omdøpes med selve navnet, foran ordet ‘ugyldig’. Dette skal forhindre for eksempel bruk av en kryptert verdi som passord.

Tips: Når du setter opp et depot som inneholder YAML-filer, må du omgi dine krypterte og prefikserte verdier med enkelt anførselstegn! Med Properties er dette ikke tilfelle.

7.1. CSRF

Som standard aktiverer Spring Security CSRF-beskyttelse for alle forespørslene som sendes til søknaden vår.

Derfor å kunne bruke / kryptere og / dekryptere sluttpunkter, la oss deaktivere CSRF for dem:

@Configuration offentlig klasse SecurityConfiguration utvider WebSecurityConfigurerAdapter {@Override public void configure (HttpSecurity http) kaster unntak {http.csrf () .ignoringAntMatchers ("/ encrypt / **") .ignoringAntMatchers ("/ dekrypter / **"); super.configure (http); }}

7.2. Nøkkeladministrasjon

Konfigurasjonsserveren er som standard aktivert for å kryptere eiendomsverdier på en symmetrisk eller asymmetrisk måte.

Å bruke symmetrisk kryptografi, du må bare sette eiendommen ‘Encrypt.key ' i din application.properties til en hemmelighet du velger. Alternativt kan du sende inn miljøvariabelen ENCRYPT_KEY.

For asymmetrisk kryptografi, kan du stille ‘Encrypt.key ' til en PEM-kodet strengverdi eller konfigurere en keystore å bruke.

Fordi vi trenger et svært sikret miljø for demo-serveren vår, valgte vi det sistnevnte alternativet og genererte en ny nøkkellager, inkludert en RSA nøkkelpar, med Java nøkkelverktøy først:

$> 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

Etter det legger vi til den opprettede nøkkellageret til serverne våre bootstrap.properties og kjør den på nytt:

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

Som neste trinn kan vi spørre om krypteringsendepunktet og legge til svaret som verdi i en konfigurasjon i depotet vårt:

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

For å teste, om oppsettet vårt fungerer riktig, endrer vi ConfigClient klasse og start klienten på nytt:

@SpringBootApplication @ RestController offentlig klasse ConfigClient {... @Value ("$ {user.password}") privat strengpassord; ... offentlig String whoami (@PathVariable ("brukernavn") String brukernavn) {return String.format ("Hei! Du er% s og du blir en (n)% s," + ", men bare hvis din passord er '% s'! \ n ", brukernavn, rolle, passord); }}

En siste spørring mot klienten vår vil vise oss om konfigurasjonsverdien vår blir dekryptert riktig:

$> curl // localhost: 8080 / whoami / Mr_Pink Hei! Du er Mr_Pink og du vil bli (n) utvikler, \ men bare hvis passordet ditt er 'd3v3L'!

7.3. Bruke flere taster

Hvis du vil bruke flere nøkler til kryptering og dekryptering, for eksempel: en dedikert en for hver serverte applikasjon, kan du legge til et annet prefiks i form av {navn: verdi} mellom {cipher} prefikset og BASE64-kodet eiendomsverdi.

Konfigurasjonsserveren forstår prefikser som {hemmelighet: min-kryptohemmelighet} eller {key: my-key-alias} nesten ut av boksen. Sistnevnte alternativ trenger en konfigurert nøkkellager i din application.properties. Denne nøkkelbutikken søkes etter et matchende nøkkelalias. For eksempel:

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

For scenarier uten keystore må du implementere en @Bønne av typen TextEncryptorLocator som håndterer oppslaget og returnerer a TextEncryptor-Objekt for hver tast.

7.4. Serverer krypterte egenskaper

Hvis du vil deaktivere kryptering på serversiden og håndtere dekryptering av eiendomsverdier lokalt, kan du sette følgende i serverens application.properties:

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

Videre kan du slette alle de andre egenskapene for "kryptere. *" For å deaktivere HVILE endepunkter.

8. Konklusjon

Nå er vi i stand til å opprette en konfigurasjonsserver for å gi et sett med konfigurasjonsfiler fra en Git lager for klientapplikasjoner. Det er noen få andre ting du kan gjøre med en slik server.

For eksempel:

  • Server konfigurasjon i YAML eller Eiendommer format i stedet for JSON - også med plassholdere løst. Som kan være nyttig når du bruker den i miljøer som ikke er fra våren, der konfigurasjonen ikke er direkte kartlagt til en PropertySource.
  • Server konfigurasjonsfiler i ren tekst - i sin tur valgfritt med løste plassholdere. Dette kan være nyttig for eksempel for å gi en miljøavhengig loggkonfigurasjon.
  • Bygg konfigurasjonsserveren inn i et program, der den konfigurerer seg fra en Git repository, i stedet for å kjøre som frittstående program som betjener klienter. Derfor må noen bootstrap-egenskaper angis og / eller @EnableConfigServer merknader må fjernes, noe som avhenger av brukssaken.
  • Gjør konfigureringsserveren tilgjengelig på Spring Netflix Eureka service discovery og aktiver automatisk serveroppdagelse i config-klienter. Dette blir viktig hvis serveren ikke har noen fast plassering eller hvis den beveger seg på stedet.

Og for å avslutte, finner du kildekoden til denne artikkelen på Github.


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