Hurtig introduktion til Spring Cloud Configuration

1. Oversigt

Spring Cloud Config er Spring's klient / server tilgang til lagring og betjening af distribuerede konfigurationer på tværs af flere applikationer og miljøer.

Denne konfigurationsbutik er ideelt versioneret under Git versionskontrol og kan ændres ved programkørsel. Mens det passer meget godt i Spring-applikationer ved hjælp af alle de understøttede konfigurationsfilformater sammen med konstruktioner som Miljø, PropertySource eller @Value, det kan bruges i ethvert miljø, der kører ethvert programmeringssprog.

I denne opskrivning vil vi fokusere på et eksempel på, hvordan man opsætter en Git-backed konfigurationsserver, brug den på en simpel måde HVILE applikationsserver og opsætte et sikkert miljø inklusive krypterede ejendomsværdier.

2. Opsætning af projekt og afhængigheder

For at blive klar til at skrive noget kode opretter vi to nye Maven projekter først. Serverprojektet er afhængig af spring-cloud-config-server samt modulet spring-boot-starter-sikkerhed og spring-boot-starter-web starter bundter:

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

Men for klientprojektet har vi kun brug for spring-cloud-starter-config og spring-boot-starter-web-moduler:

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

3. En implementering af Config Server

Hoveddelen af ​​applikationen er en konfigurationsklasse - mere specifikt en @SpringBootApplication - der trækker alle de krævede opsætninger igennem automatisk konfiguration kommentar @EnableConfigServer:

@SpringBootApplication @EnableConfigServer offentlig klasse ConfigServer {offentlig statisk ugyldigt hoved (String [] argumenter) {SpringApplication.run (ConfigServer.class, argumenter); }} 

Nu skal vi konfigurere serveren Havn som vores server lytter til og en Git-url, der leverer vores versionskontrollerede konfigurationsindhold. Sidstnævnte kan bruges med protokoller som http, ssh eller en simpel fil på et lokalt filsystem.

Tip: Hvis du planlægger at bruge flere konfigurationsserverforekomster, der peger på det samme konfigurationslager, kan du konfigurere serveren til at klone din repo i en lokal midlertidig mappe. Men vær opmærksom på private opbevaringssteder med tofaktorautentisering, de er svære at håndtere! I et sådant tilfælde er det lettere at klone dem på dit lokale filsystem og arbejde med kopien.

Der er også nogle pladsholdervariabler og søgemønstre til konfiguration af repository-url ledig; men dette er uden for anvendelsesområdet for vores artikel. Hvis du er interesseret, er den officielle dokumentation et godt sted at starte.

Vi skal også indstille et brugernavn og en adgangskode til Grundlæggende godkendelse i vores application.properties for at undgå en automatisk genereret adgangskode ved hver genstart af applikationen:

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 = rodfjeder.security.user.password = s3cr3t

4. Et Git-lager som konfigurationslager

For at fuldføre vores server skal vi initialisere en Git lager under den konfigurerede url, opret nogle nye egenskabsfiler og populariser dem med nogle værdier.

Navnet på konfigurationsfilen er sammensat som et normalt forår application.properties, men i stedet for ordet 'applikation' et konfigureret navn, f.eks. ejendommens værdi 'Spring.application.name' af klienten bruges efterfulgt af en bindestreg og den aktive profil. For eksempel:

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

Fejlfinding: Hvis du løber ind ssh-relaterede godkendelsesproblemer, dobbeltkontrol ~ / .ssh / known_hosts og ~ / .ssh / autoriserede_taster på din ssh-server!

5. Forespørgsel om konfigurationen

Nu er vi i stand til at starte vores server. Det Git-backed konfigurations API leveret af vores server kan forespørges ved hjælp af følgende stier:

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

I hvilken {etiket} pladsholder refererer til en Git-gren, {Ansøgning} til klientens applikationsnavn og {profil} til klientens aktuelle aktive applikationsprofil.

Så vi kan hente konfigurationen til vores planlagte config-klient, der kører under udviklingsprofil i filialen mestre via:

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

6. Klientimplementering

Lad os derefter tage os af klienten. Dette vil være en meget enkel klientapplikation, der består af en HVILE controller med en metode.

Konfigurationen for at hente vores server skal placeres i en ressourcefil med navnet bootstrap.application, fordi denne fil (som navnet antyder) indlæses meget tidligt, mens applikationen starter:

@SpringBootApplication @ RestController offentlig klasse ConfigClient {@Value ("$ {user.role}") privat strengrolle; public static void main (String [] args) {SpringApplication.run (ConfigClient.class, args); } @GetMapping (værdi = "/ whoami / {brugernavn}", producerer = MediaType.TEXT_PLAIN_VALUE) offentlig String whoami (@PathVariable ("brugernavn") String brugernavn) {return String.format ("Hej! Du er% s og du bliver en (n)% s ... \ n ", brugernavn, rolle); }}

Ud over applikationsnavnet sætter vi også den aktive profil og forbindelsesoplysningerne i vores bootstrap.properties:

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

For at teste, om konfigurationen modtages korrekt fra vores server og rolleværdi bliver injiceret i vores controller-metode, vi krøller den simpelthen efter opstart af klienten:

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

Hvis svaret er som følger, er vores Spring Cloud Config Server og dets klient fungerer fint for nu:

Hej! Du er Mr_Pink, og du bliver en (n) udvikler ...

7. Kryptering og dekryptering

Krav: For at bruge kryptografisk stærke nøgler sammen med Spring-krypterings- og dekrypteringsfunktioner har du brug for ‘Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files’ installeret i din JVM. Disse kan f.eks. Downloades fra Oracle. Følg instruktionerne i download for at installere. Nogle Linux-distributioner giver også en installerbar pakke gennem deres pakkehåndtering.

Da konfigurationsserveren understøtter kryptering og dekryptering af ejendomsværdier, kan du bruge offentlige arkiver som lager til følsomme data som brugernavne og adgangskoder. Krypterede værdier er præfikset med strengen {cipher} og kan genereres ved et REST-opkald til stien '/ Krypter', hvis serveren er konfigureret til at bruge en symmetrisk nøgle eller et nøglepar.

Et slutpunkt til dekryptering er også tilgængeligt. Begge slutpunkter accepterer en sti, der indeholder pladsholdere til programmets navn og dets aktuelle profil: ‘/ * / {Name} / {profile} '. Dette er især nyttigt til styring af kryptografi pr. Klient. Inden de bliver nyttige, skal du dog konfigurere en kryptografisk nøgle, som vi vil gøre i næste afsnit.

Tip: Hvis du bruger curl til at kalde en- / dekryptering API, er det bedre at bruge –Data-urlencode option (i stedet for –Data / -d), eller indstil "Content-Type" -overskriften eksplicit til 'Tekst / almindelig'. Dette sikrer en korrekt håndtering af specialtegn som '+' i de krypterede værdier.

Hvis en værdi ikke kan dekrypteres automatisk under hentning gennem klienten, er dens nøgle omdøbes med selve navnet, foran ordet 'ugyldig'. Dette skal f.eks. Forhindre brugen af ​​en krypteret værdi som adgangskode.

Tip: Når du opretter et lager, der indeholder YAML-filer, skal du omgive dine krypterede og præfikserede værdier med enkelt-citater! Med egenskaber er dette ikke tilfældet.

7.1. CSRF

Som standard muliggør Spring Security CSRF-beskyttelse for alle anmodninger, der sendes til vores ansøgning.

Derfor at være i stand til at bruge / kryptere og / dekrypter slutpunkter, lad os deaktivere CSRF for dem:

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

7.2. Key Management

Konfigurationsserveren er som standard aktiveret til at kryptere ejendomsværdier på en symmetrisk eller asymmetrisk måde.

At bruge symmetrisk kryptografi, skal du blot indstille ejendommen 'Krypter.nøgle' i din application.properties til en hemmelighed efter eget valg. Alternativt kan du overføre miljøvariablen ENCRYPT_KEY.

Til asymmetrisk kryptografi, kan du indstille 'Krypter.nøgle' til en PEM-kodet strengværdi eller konfigurer en keystore at bruge.

Da vi har brug for et meget beskyttet miljø til vores demoserver, valgte vi sidstnævnte mulighed og genererede en ny keystore, inklusive en RSA nøglepar med Java nøgleværktøj 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

Derefter tilføjer vi den oprettede nøglelager til vores servere bootstrap.properties og kør det igen:

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 næste trin kan vi forespørge krypteringsendepunktet og tilføje svaret som værdi til en konfiguration i vores lager:

$> 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 'Tilføjet krypteret adgangskode' $> curl -X POST // root: [email protected]: 8888 / refresh

For at teste, hvis vores opsætning fungerer korrekt, ændrer vi ConfigClient klasse og genstart vores klient:

@SpringBootApplication @ RestController offentlig klasse ConfigClient {... @Value ("$ {user.password}") privat strengadgangskode; ... offentlig String whoami (@PathVariable ("brugernavn") String brugernavn) {return String.format ("Hej! Du er% s og du bliver en (n)% s," + "men kun hvis din adgangskode er '% s'! \ n ", brugernavn, rolle, adgangskode); }}

En sidste forespørgsel mod vores klient viser os, hvis vores konfigurationsværdi bliver korrekt dekrypteret:

$> curl // localhost: 8080 / whoami / Mr_Pink Hej! Du er Mr_Pink, og du bliver udvikler (n), men kun hvis din adgangskode er 'd3v3L'!

7.3. Brug af flere taster

Hvis du f.eks. Vil bruge flere nøgler til kryptering og dekryptering: en dedikeret en til hver serverede applikation, kan du tilføje et andet præfiks i form af {navn: værdi} imellem {cipher} præfiks og BASE64-kodet ejendomsværdi.

Config-serveren forstår præfikser som {hemmelighed: min-krypto-hemmelighed} eller {key: my-key-alias} næsten uden for kassen. Sidstnævnte mulighed har brug for en konfigureret nøglelager i din application.properties. Denne nøglelager søges efter et matchende nøgealias. For eksempel:

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

For scenarier uden keystore skal du implementere en @Bønne af typen TextEncryptorLocator som håndterer opslag og returnerer a TextEncryptor-Objekt for hver tast.

7.4. Serverer krypterede egenskaber

Hvis du vil deaktivere kryptografi på serversiden og håndtere dekryptering af ejendomsværdier lokalt, kan du sætte følgende i din servers application.properties:

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

Desuden kan du slette alle de andre 'krypterings * egenskaber for at deaktivere HVILE slutpunkter.

8. Konklusion

Nu er vi i stand til at oprette en konfigurationsserver til at levere et sæt konfigurationsfiler fra en Git lager til klientapplikationer. Der er et par andre ting, du kan gøre med en sådan server.

For eksempel:

  • Server konfiguration i YAML eller Ejendomme format i stedet for JSON - også med pladsholdere løst. Hvilket kan være nyttigt, når du bruger det i miljøer, der ikke er fra foråret, hvor konfigurationen ikke er kortlagt direkte til en PropertySource.
  • Server konfigurationsfiler i almindelig tekst - igen valgfrit med løste pladsholdere. Dette kan f.eks. Være nyttigt at give en miljøafhængig logningskonfiguration.
  • Integrer konfigurationsserveren i et program, hvor den konfigurerer sig fra en Git lager, i stedet for at køre som en enkeltstående applikation, der betjener klienter. Derfor skal nogle bootstrap-egenskaber indstilles og / eller @EnableConfigServer annotering skal fjernes, hvilket afhænger af brugssagen.
  • Gør konfigurationsserveren tilgængelig på Spring Netflix Eureka service discovery og aktiver automatisk server discovery i config klienter. Dette bliver vigtigt, hvis serveren ikke har nogen fast placering, eller hvis den bevæger sig på sin placering.

Og for at afslutte finder du kildekoden til denne artikel på Github.