Leitfaden zur Frühjahrssitzung

REST Top

Ich habe gerade den neuen Learn Spring- Kurs angekündigt , der sich auf die Grundlagen von Spring 5 und Spring Boot 2 konzentriert:

>> Überprüfen Sie den Kurs

1. Übersicht

Spring Session hat das einfache Ziel, die Sitzungsverwaltung von den Einschränkungen der auf dem Server gespeicherten HTTP-Sitzung zu befreien.

Die Lösung erleichtert die gemeinsame Nutzung von Sitzungsdaten zwischen Diensten in der Cloud, ohne an einen einzelnen Container (z. B. Tomcat) gebunden zu sein. Darüber hinaus werden mehrere Sitzungen im selben Browser und das Senden von Sitzungen in einem Header unterstützt.

In diesem Artikel verwenden wir Spring Session , um Authentifizierungsinformationen in einer Web-App zu verwalten. Während Spring Session Daten mit JDBC, Gemfire oder MongoDB beibehalten kann, verwenden wir Redis .

Eine Einführung in Redis finden Sie in diesem Artikel.

2. Ein einfaches Projekt

Lassen Sie uns zunächst ein einfaches Spring Boot- Projekt erstellen , das später als Basis für unsere Sitzungsbeispiele verwendet wird:

 org.springframework.boot spring-boot-starter-parent 2.2.6.RELEASE     org.springframework.boot spring-boot-starter-security   org.springframework.boot spring-boot-starter-web   org.springframework.boot spring-boot-starter-test test  

Unsere Anwendung läuft mit Spring Boot und der übergeordnete POM bietet Versionen für jeden Eintrag. Die neueste Version jeder Abhängigkeit finden Sie hier: Spring-Boot-Starter-Sicherheit, Spring-Boot-Starter-Web, Spring-Boot-Starter-Test.

Fügen wir in application.properties auch einige Konfigurationseigenschaften für unseren Redis-Server hinzu :

spring.redis.host=localhost spring.redis.port=6379

3. Spring Boot-Konfiguration

Für Spring Boot reicht es aus, die folgenden Abhängigkeiten hinzuzufügen , und die automatische Konfiguration kümmert sich um den Rest:

 org.springframework.boot spring-boot-starter-data-redis   org.springframework.session spring-session-data-redis 

Wir verwenden das übergeordnete Boot- POM , um die Versionen hier festzulegen , sodass diese garantiert mit unseren anderen Abhängigkeiten funktionieren. Die neueste Version jeder Abhängigkeit finden Sie hier: Spring-Boot-Starter-Data-Redis, Spring-Session.

4. Standard Spring Config (kein Boot)

Schauen wir uns auch die Integration und Konfiguration der Spring-Session ohne Spring Boot an - nur mit einfachem Spring.

4.1. Abhängigkeiten

Erstens, wenn wir fügen feder Sitzung zu einem Standard - Frühling Projekt, müssen wir explizit definieren:

 org.springframework.session spring-session 1.2.2.RELEASE   org.springframework.data spring-data-redis 1.5.0.RELEASE 

Die neuesten Versionen dieser Module finden Sie hier: spring-session, spring-data-redis.

4.2. Konfiguration der Frühlingssitzung

Fügen wir nun eine Konfigurationsklasse für die Frühlingssitzung hinzu :

@Configuration @EnableRedisHttpSession public class SessionConfig extends AbstractHttpSessionApplicationInitializer { @Bean public JedisConnectionFactory connectionFactory() { return new JedisConnectionFactory(); } }

@EnableRedisHttpSession und die Erweiterung von AbstractHttpSessionApplicationInitializer erstellen und verkabeln einen Filter vor unserer gesamten Sicherheitsinfrastruktur, um nach aktiven Sitzungen zu suchen und den Sicherheitskontext anhand der in Redis gespeicherten Werte zu füllen .

Vervollständigen wir diese Anwendung nun mit einem Controller und der Sicherheitskonfiguration.

5. Anwendungskonfiguration

Navigieren Sie zu unserer Hauptanwendungsdatei und fügen Sie einen Controller hinzu:

@RestController public class SessionController { @RequestMapping("/") public String helloAdmin() { return "hello admin"; } }

Dies gibt uns einen Endpunkt zum Testen.

Fügen Sie als Nächstes unsere Sicherheitskonfigurationsklasse hinzu:

@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("admin") .password(passwordEncoder().encode("password")) .roles("ADMIN"); } @Override protected void configure(HttpSecurity http) throws Exception { http .httpBasic().and() .authorizeRequests() .antMatchers("/").hasRole("ADMIN") .anyRequest().authenticated(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }

Dies schützt unsere Endpunkte mit einer grundlegenden Authentifizierung und richtet einen Benutzer zum Testen ein.

6. Testen

Lassen Sie uns zum Schluss alles testen - wir werden hier einen einfachen Test definieren, der es uns ermöglicht, zwei Dinge zu tun:

  • Verwenden Sie die Live-Webanwendung
  • Sprich mit Redis

Lassen Sie uns zuerst die Dinge einrichten:

public class SessionControllerTest { private Jedis jedis; private TestRestTemplate testRestTemplate; private TestRestTemplate testRestTemplateWithAuth; private String testUrl = "//localhost:8080/"; @Before public void clearRedisData() { testRestTemplate = new TestRestTemplate(); testRestTemplateWithAuth = new TestRestTemplate("admin", "password", null); jedis = new Jedis("localhost", 6379); jedis.flushAll(); } }

Beachten Sie, wie wir diese beiden Clients einrichten - den HTTP-Client und den Redis-Client. Zu diesem Zeitpunkt sollten natürlich der Server (und Redis) betriebsbereit sein, damit wir über diese Tests mit ihnen kommunizieren können.

Beginnen wir mit dem Testen, ob Redis leer ist:

@Test public void testRedisIsEmpty() { Set result = jedis.keys("*"); assertEquals(0, result.size()); }

Testen Sie nun, ob unsere Sicherheit einen 401 für nicht authentifizierte Anforderungen zurückgibt:

@Test public void testUnauthenticatedCantAccess() { ResponseEntity result = testRestTemplate.getForEntity(testUrl, String.class); assertEquals(HttpStatus.UNAUTHORIZED, result.getStatusCode()); }

Als Nächstes testen wir, ob Spring Session unser Authentifizierungstoken verwaltet:

@Test public void testRedisControlsSession() { ResponseEntity result = testRestTemplateWithAuth.getForEntity(testUrl, String.class); assertEquals("hello admin", result.getBody()); //login worked Set redisResult = jedis.keys("*"); assertTrue(redisResult.size() > 0); //redis is populated with session data String sessionCookie = result.getHeaders().get("Set-Cookie").get(0).split(";")[0]; HttpHeaders headers = new HttpHeaders(); headers.add("Cookie", sessionCookie); HttpEntity httpEntity = new HttpEntity(headers); result = testRestTemplate.exchange(testUrl, HttpMethod.GET, httpEntity, String.class); assertEquals("hello admin", result.getBody()); //access with session works worked jedis.flushAll(); //clear all keys in redis result = testRestTemplate.exchange(testUrl, HttpMethod.GET, httpEntity, String.class); assertEquals(HttpStatus.UNAUTHORIZED, result.getStatusCode()); //access denied after sessions are removed in redis }

First, our test confirms that our request was successful using the admin authentication credentials.

Then we extract the session value from the response headers and use it as our authentication in our second request. We validate that, and then clear all the data in Redis.

Finally, we make another request using the session cookie and confirm that we are logged out. This confirms that Spring Session is managing our sessions.

7. Conclusion

Spring Session is a powerful tool for managing HTTP sessions. With our session storage simplified to a configuration class and a few Maven dependencies, we can now wire up multiple applications to the same Redis instance and share authentication information.

Wie immer sind alle Beispiele auf Github verfügbar.

REST unten

Ich habe gerade den neuen Learn Spring- Kurs angekündigt , der sich auf die Grundlagen von Spring 5 und Spring Boot 2 konzentriert:

>> Überprüfen Sie den Kurs