[JAVA] Erstellen Sie mit Spring Boot 2.0 einen Spring Cloud Config Server mit Sicherheit

Was diesmal zu machen

スクリーンショット 2018-03-09 14.56.50.png

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).

Umgebung

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.

Erstellen eines Konfigurations-Repositorys

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

Priorität setzen

Wenn eine andere Datei eine Einstellung mit demselben Namen hat, wird sie in der folgenden Reihenfolge priorisiert (die höhere wird priorisiert).

  1. Anwendungsname-Profilname.Eigenschaften
  2. Anwendungsname.Eigenschaften
  3. Anwendungsprofil name.properties
  4. application.properties

Konfigurationsserver erstellen

(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.

スクリーンショット 2018-03-09 13.08.27.png

(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

Machen Sie einen Kunden

(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.

スクリーンショット 2018-03-09 13.09.59.png

(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;
    }
}

Starten Sie Config Server und rufen Sie die Einstellungen mit curl ab

(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.

Holen Sie sich Wert vom Kunden

(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.

Ändern Sie den Wert während der Ausführung

(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 Benutzername actuator 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!!!!!!!!!!!!!!!!!!!!!!!!!"
}

Recommended Posts

Erstellen Sie mit Spring Boot 2.0 einen Spring Cloud Config Server mit Sicherheit
Erstellen Sie einen Web-API-Server mit Spring Boot
Erstellen Sie mit Spring Boot einen Mikrodienst
Erstellen Sie mit Spring Security 2.1 eine einfache Demo-Site mit Spring Security
Google Cloud Platform mit Spring Boot 2.0.0
Erreichen Sie die BASIC-Authentifizierung mit Spring Boot + Spring Security
Erstellen Sie eine Website mit Spring Boot + Gradle (jdk1.8.x)
Erstellen Sie mit Spring Boot eine einfache Such-App
Hash-Passwörter mit Spring Boot + Spring Security (mit Salt, mit Stretching)
Versuchen Sie die LDAP-Authentifizierung mit Spring Security (Spring Boot) + OpenLDAP
Erstellen Sie eine CRUD-App mit Spring Boot 2 + Thymeleaf + MyBatis
Erstellen Sie eine Spring Boot-Umgebung mit Windows + VS-Code
[Einführung in Spring Boot] Authentifizierungsfunktion mit Spring Security
Erstellen Sie mit Docker eine Spring Boot-Entwicklungsumgebung
Verwendungshinweis zu Spring Security: Zusammenarbeit mit Spring MVC und Boot
Implementieren Sie eine einfache Rest-API mit Spring Security mit Spring Boot 2.0
Erstellen Sie Restapi mit Spring Boot (bis zum Ausführen der App)
Generieren Sie mit Spring Boot einen Barcode
Hallo Welt mit Spring Boot
Java-Konfiguration mit Spring MVC
Beginnen Sie mit Spring Boot
Hallo Welt mit Spring Boot!
Führen Sie LIFF mit Spring Boot aus
SNS-Login mit Spring Boot
Anmeldefunktion mit Spring Security
Spring Boot beginnend mit Docker
Hallo Welt mit Spring Boot
Setzen Sie Cookies mit Spring Boot
Verwenden Sie Spring JDBC mit Spring Boot
Modul mit Spring Boot hinzufügen
Erste Schritte mit Spring Boot
Versuchen Sie es mit Spring Boot Security
Mail mit Spring Boot verschicken
Verwenden Sie die Standardauthentifizierung mit Spring Boot
Implementierte Authentifizierungsfunktion mit Spring Security ②
gRPC auf Spring Boot mit grpc-spring-boot-Starter
Hot Deploy mit Spring Boot-Entwicklung
Spring Boot Tutorial Verwenden der Spring Security-Authentifizierung
Spring Boot Programmierung mit VS Code
Bis "Hallo Welt" mit Spring Boot
Erstellen Sie eine Anfrage-App mit Spring Boot
Implementierte Authentifizierungsfunktion mit Spring Security ①
Erhalten Sie Validierungsergebnisse mit Spring Boot
Oauth2-Authentifizierung mit Spring Cloud Gateway
(Intellij) Hallo Welt mit Spring Boot
Ich habe GraphQL mit Spring Boot ausprobiert
[Java] LINE-Integration mit Spring Boot
Beginnend mit Spring Boot 0. Verwenden Sie Spring CLI
Ich habe Flyway mit Spring Boot ausprobiert
Implementieren Sie einen einfachen Web-REST-API-Server mit Spring Boot + MySQL
Ich habe versucht, einen OAuth-Client mit Spring Boot / Security (LINE-Anmeldung) zu implementieren.
Teil 1: Versuchen Sie, die von Spring Security 5 unterstützte OAuth 2.0-Anmeldung mit Spring Boot zu verwenden
So erstellen Sie mit Spring Boot einen eigenen Controller, der / error entspricht
Verarbeitung beim Starten einer Anwendung mit Spring Boot
Erstellen einer Spring Boot-Entwicklungsumgebung in Vagrant
So lesen Sie Request Body mit Spring Boot + Spring Security mehrmals
Erstellen Sie mit dem Befehl cURL + tar ein Spring Boot-App-Entwicklungsprojekt
Hallo Welt mit Eclipse + Spring Boot + Maven