Die BASIC-Authentifizierung wird zwischen Curl und Client sowie zwischen Client und Config Server angewendet. Ursprünglich ist OAuth 2.0 wahrscheinlich besser, aber das ist eine weitere Gelegenheit.
Der Beispielcode wird auf [GitHub] hochgeladen (https://github.com/MasatoshiTada/boot2-config-server-sample).
Zum Zeitpunkt des Schreibens wurde Spring Cloud Finchley noch nicht offiziell veröffentlicht. Bitte beachten Sie, dass sich die technischen Daten in Zukunft ändern können.
Informationen zum Konfigurationsserver selbst finden Sie in Maki-sans Blog. Bitte beachten Sie jedoch, dass dies ein Artikel vor der offiziellen Veröffentlichung ist, sodass es einige Unterschiede zum aktuellen gibt.
Sie können Git oder SVN als Repository verwenden. Dieses Mal werde ich GitHub verwenden. Klicken Sie hier für URL-> https://github.com/MasatoshiTada/app-config Bitte gabeln und benutzen!
application.properties Diese Einstellung wird für alle Anwendungen und alle Profile verwendet.
application.properties
message=Hello application!
common=common
application-xxx.properties Diese Einstellung wird von allen Anwendungen verwendet, jedoch nur von einem bestimmten Profil ("xxx" ist der Profilname).
application-dev.properties
message=Hello application-dev!
common=common-dev
application-qa.properties
message=Hello application-qa!
common=common-qa
client.properties Diese Einstellung wird nur für alle Profile in der Anwendung verwendet, deren Name "client" ist.
client.properties
message=Hello client!
server.port=8081
#Wird zum Aktualisieren von Einstellungen verwendet/Aktivieren Sie den Aktualisierungsendpunkt
management.endpoints.web.exposure.include=refresh
#Stellen Sie die Protokollstufe von Spring Security auf Trace ein, um die interne Ausführung besser sehen zu können.
logging.level.org.springframework.security=trace
Die dritte Zeile,
management.endpoints.web.exposure.include = refresh
, ist eine neue Einstellung aus Spring Boot 2.0. In Spring Boot 2.0 sind nur die in dieser Einstellung beschriebenen Endpunkte aktiviert (mehrere Spezifikationen können durch Kommas getrennt angegeben werden).
client-xxx.properties Diese Einstellung wird nur für bestimmte Profile nur in Anwendungen verwendet, deren Name "client" ist ("xxx" ist der Profilname).
client-dev.properties
message=Hello client-dev!
server.port=8082
client-qa.properties
message=Hello client-qa!
server.port=8083
foo.properties Diese Einstellung wird für alle Profile nur in Anwendungen verwendet, deren Name "foo" ist.
foo.properties
message=Hello foo!
server.port=9001
foo-xxx.properties Diese Einstellung wird nur für bestimmte Profile nur in Anwendungen verwendet, deren Name "foo" ist ("xxx" ist der Profilname).
foo-dev.properties
message=Hello foo-dev!
server.port=9002
foo-qa.properties
message=Hello foo-qa!
server.port=9003
Wenn eine andere Datei eine Einstellung mit demselben Namen hat, wird sie in der folgenden Reihenfolge priorisiert (die höhere wird priorisiert).
(1) Erstellen Sie eine Vorlage mit Spring Initializr. Entscheiden Sie entsprechend für "Gruppe" und "Artefakt" und fügen Sie "Konfigurationsserver" und "Sicherheit" unter "Abhängigkeiten" hinzu.
(2) Fügen Sie der Klasse mit der main () -Methode @ EnableConfigServer
hinzu.
@SpringBootApplication
@EnableConfigServer //Fügen Sie dies hinzu
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
(3) Erstellen Sie eine Java Config-Klasse für Spring Security. Erstellen Sie einen Benutzer mit einem beliebigen Benutzernamen und Kennwort und aktivieren Sie die BASIC-Authentifizierung.
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// "client"Erstellen Sie einen Benutzer
//Verwenden Sie NoOpPasswordEncoder nicht in der Produktion, sondern BCryptPasswordEncoder
auth.inMemoryAuthentication()
.passwordEncoder(NoOpPasswordEncoder.getInstance())
.withUser("client").password("password").roles("CLIENT");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
//Aktivieren Sie die BASIC-Authentifizierung, sodass alle URLs authentifiziert werden müssen, bevor auf sie zugegriffen werden kann
http.httpBasic();
http.authorizeRequests()
.anyRequest().authenticated();
}
}
Wie in den Kommentaren erwähnt, codiert NoOpPasswordEncoder überhaupt keine Kennwörter und sollte nicht in der Produktion verwendet werden (bereits in Spring Security 5 veraltet). Dieses Mal benutze ich es nur zum Lernen.
(4) Beschreiben Sie die Einstellungen in application.properties.
#Git-Repository-URL
spring.cloud.config.server.git.uri=https://github.com/MasatoshiTada/app-config.git
#Portnummer dieses Konfigurationsservers
server.port=8888
(1) Erstellen Sie eine Vorlage mit Spring Initializr. Entscheiden Sie entsprechend für "Gruppe" und "Artefakt" und fügen Sie "Web", "Konfigurationsclient", "Aktor" und "Sicherheit" in "Abhängigkeiten" hinzu.
(2) Erstellen Sie eine Java Config-Klasse für Spring Security. Erstellen Sie zwei Benutzer mit einem beliebigen Benutzernamen und Kennwort (trennen Sie die Rollen und geben Sie ihnen einen beliebigen Rollennamen).
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// "ACTUATOR"Wann"USER"Wannいう2つのロールのユーザーを作る
//Verwenden Sie NoOpPasswordEncoder nicht in der Produktion!
auth.inMemoryAuthentication()
.passwordEncoder(NoOpPasswordEncoder.getInstance())
.withUser("actuator").password("password").roles("ACTUATOR").and()
.withUser("user").password("password").roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
//Aktivieren Sie die BASIC-Authentifizierung
http.httpBasic();
//Auf Actuator-Endpunkte kann nur über die ACTUATOR-Rolle zugegriffen werden.
//Auf andere kann von jeder Rolle zugegriffen werden, solange Sie angemeldet sind
http.authorizeRequests()
.requestMatchers(EndpointRequest.toAnyEndpoint()).hasRole("ACTUATOR")
.anyRequest().authenticated();
//CSRF in der Produktion nicht deaktivieren!
http.csrf().disable();
}
}
Dieses Mal haben wir CSRF deaktiviert, um zu vermeiden, dass die Stichprobe zu komplex wird. Bitte deaktivieren Sie es nicht in der Produktionsumgebung und holen Sie sich auf irgendeine Weise ein Token, bevor Sie mit Curl darauf zugreifen.
(3) Beschreiben Sie die Einstellungen in bootstrap.properties.
#Anwendungsname für diesen Client
spring.application.name=client
#Server-URL konfigurieren
spring.cloud.config.uri=http://localhost:8888/
#Benutzername und Passwort für den Zugriff auf Config Server
#(Erstellt mit Java Config von Config Server)
spring.cloud.config.username=client
spring.cloud.config.password=password
bootstrap.properties beschreibt die Starteinstellungen und wird nur in der Spring Cloud-Umgebung verwendet.
(4) Erstellen Sie einen geeigneten Controller, der den von Config Server erhaltenen Wert zurückgibt. Hängen Sie "@ RefreshScope" an die Klasse an.
@RefreshScope // "POST /actuator/refresh"Zerstört die Instanz dieser Klasse
@RestController
@RequestMapping("/hello")
public class HelloController {
private final String message;
private final String common;
//Rufen Sie den von Config Server erhaltenen Wert mit dem Konstruktor ab
public HelloController(@Value("${message}") String message, @Value("${common}") String common) {
this.message = message;
this.common = common;
}
@GetMapping
public Map<String, String> hello() {
HashMap<String, String> map = new HashMap<>();
map.put("message", message);
map.put("common", common);
return map;
}
}
(1) Starten Sie nur den Konfigurationsserver. (2) Sie können den Wert von application.properties erhalten, indem Sie auf "/ application / default" zugreifen.
$ curl -X GET -u client:password http://localhost:8888/application/default | jq
{
"name": "application",
"profiles": [
"default"
],
"label": null,
"version": "e87b3c3ff0239394963e3bddf0a2982db5064339",
"state": null,
"propertySources": [
{
"name": "https://github.com/MasatoshiTada/app-config.git/application.properties",
"source": {
"message": "Hello application!",
"common": "common"
}
}
]
}
(2) Sie können die Werte von application.properties und application-dev.properties abrufen, indem Sie auf / application / dev
zugreifen.
$ curl -X GET -u client:password http://localhost:8888/application/dev | jq
{
"name": "application",
"profiles": [
"dev"
],
"label": null,
"version": "e87b3c3ff0239394963e3bddf0a2982db5064339",
"state": null,
"propertySources": [
{
"name": "https://github.com/MasatoshiTada/app-config.git/application-dev.properties",
"source": {
"message": "Hello application-dev!",
"common": "common-dev"
}
},
{
"name": "https://github.com/MasatoshiTada/app-config.git/application.properties",
"source": {
"message": "Hello application!",
"common": "common"
}
}
]
}
Obwohl nicht beschrieben, können Sie die Werte von application.properties und application-qa.properties abrufen, indem Sie auf
/ application / qa
zugreifen.
(3) Sie können die Werte von application.properties und client.properties abrufen, indem Sie auf "/ client / default" zugreifen.
$ curl -X GET -u client:password http://localhost:8888/client/default | jq
{
"name": "client",
"profiles": [
"default"
],
"label": null,
"version": "e87b3c3ff0239394963e3bddf0a2982db5064339",
"state": null,
"propertySources": [
{
"name": "https://github.com/MasatoshiTada/app-config.git/client.properties",
"source": {
"message": "Hello client!",
"server.port": "8081",
"management.endpoints.web.exposure.include": "refresh",
"logging.level.org.springframework.security": "trace"
}
},
{
"name": "https://github.com/MasatoshiTada/app-config.git/application.properties",
"source": {
"message": "Hello application!",
"common": "common"
}
}
]
}
Obwohl nicht beschrieben, können Sie die Werte von application.properties und foo.properties abrufen, indem Sie auf
/ foo / default
zugreifen.
(4) Durch Zugriff auf / client / dev
können Sie die Werte von application.properties, application-dev.properties, client.properties, client-dev.properties abrufen.
$ curl -X GET -u client:password http://localhost:8888/client/dev | jq
{
"name": "client",
"profiles": [
"dev"
],
"label": null,
"version": "e87b3c3ff0239394963e3bddf0a2982db5064339",
"state": null,
"propertySources": [
{
"name": "https://github.com/MasatoshiTada/app-config.git/client-dev.properties",
"source": {
"message": "Hello client-dev!",
"server.port": "8082"
}
},
{
"name": "https://github.com/MasatoshiTada/app-config.git/application-dev.properties",
"source": {
"message": "Hello application-dev!",
"common": "common-dev"
}
},
{
"name": "https://github.com/MasatoshiTada/app-config.git/client.properties",
"source": {
"message": "Hello client!",
"server.port": "8081",
"management.endpoints.web.exposure.include": "refresh",
"logging.level.org.springframework.security": "trace"
}
},
{
"name": "https://github.com/MasatoshiTada/app-config.git/application.properties",
"source": {
"message": "Hello application!",
"common": "common"
}
}
]
}
Nicht aufgeführt,
- Sie können die Werte von application.properties, application-qa.properties, client.properties, client-qa.properties abrufen, indem Sie auf
/ client / qa
zugreifen.- Sie können die Werte von application.properties, application-dev.properties, foo.properties und foo-dev.properties abrufen, indem Sie auf
/ foo / dev
zugreifen.- Sie können die Werte von application.properties, application-qa.properties, foo.properties und foo-qa.properties abrufen, indem Sie auf
/ foo / qa
zugreifen.
Lassen Sie den Konfigurationsserver nach den obigen Überprüfungen laufen.
(1) Starten Sie den Client ohne Angabe eines Profils.
(2) Beim Start greift der Client mit der im vorherigen Kapitel angegebenen URL auf den Konfigurationsserver zu, basierend auf dem in spring.application.name
angegebenen Anwendungsnamen und dem ausgeführten Profilnamen (in diesem Fall / client. / default
). Für diesen Zugriff wird auch die BASIC-Authentifizierung verwendet (Benutzername client
, Passwort password
).
(3) Zugriff auf localhost: 8081 / hello
mit Curl.
$ curl -X GET -u user:password http://localhost:8081/hello | jq
{
"common": "common",
"message": "Hello client!"
}
"common" ist der Wert von application.properties. "message" ist auch in application.properties definiert, aber der Wert von client.properties wird aus der Prioritätsregel verwendet. Die Portnummer 8081, die ausgeführt wird, ist auch der Wert von client.properties.
(4) Stoppen Sie den Client einmal und starten Sie ihn mit dem Entwicklungsprofil neu. Das Profil wird durch ein Befehlszeilenargument mit "-" angegeben (zusätzlich kann es durch Umgebungsvariablen, JVM-Systemeigenschaften usw. angegeben werden).
client $ mvn clean package
client $ java -jar target/client-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev
client $ curl -X GET -u user:password http://localhost:8082/hello | jq
{
"common": "common-dev",
"message": "Hello client-dev!"
}
"common" ist der Wert von application-dev.properties. "message" ist der Wert von client-dev.properties. Die Portnummer 8082, die ausgeführt wird, ist auch der Wert von client-dev.properties.
(1) Stoppen Sie den aktuell ausgeführten Client und starten Sie ihn neu, ohne ein Profil anzugeben.
(2) Greifen Sie mit Curl auf den Endpunkt / hello
zu. Der Wert der Nachricht lautet "Hallo Client!".
$ curl -X GET -u user:password http://localhost:8081/hello | jq
{
"common": "common",
"message": "Hello client!"
}
(3) Schreiben Sie auf GitHub den Wert der Nachricht in client.properties neu.
message=Hello client!!!!!!!!!!!!!!!!!!!!!!!!!
(4) Greifen Sie erneut mit Curl auf den Endpunkt / hello
zu. Der Wert der Nachricht bleibt "Hallo Client!" Und hat sich nicht geändert. Dies liegt daran, dass der in GitHub geänderte Wert auf der Clientseite noch nicht berücksichtigt wurde.
$ curl -X GET -u user:password http://localhost:8081/hello | jq
{
"common": "common",
"message": "Hello client!"
}
(5) Zugriff auf "/ Aktuator / Auffrischen" mit Locken. Der Client greift dann auf den Konfigurationsserver zu, der den Wert von GitHub abruft und an den Client weitergibt.
$ curl -X POST -u actuator:password http://localhost:8081/actuator/refresh | jq
[
"config.client.version",
"message"
]
Beachten Sie, dass der mit
-u
angegebene Benutzernameactuator
ist. Dies ist ein Benutzer, der in Java Config auf dem Client erstellt wurde, und ein Benutzer in der Rolle "ACTUATOR", der über die Berechtigung zum Zugriff auf "/ actuator / **" verfügt.
(6) Beim Aktualisieren wird die Bean mit dem Zusatz "@ RefreshScope" (in diesem Fall "HelloController") zerstört. Die Instanz wird neu erstellt, wenn die Bean nach einer Aktualisierung zum ersten Mal benötigt wird (in diesem Fall, wenn Curl auf / hello
zugreift), und die neuen Einstellungen nach der Änderung werden verwendet.
$ curl -X GET -u user:password http://localhost:8081/hello | jq
{
"common": "common",
"message": "Hello client!!!!!!!!!!!!!!!!!!!!!!!!!"
}