Több belépési pont a tavaszi biztonságban

1. Áttekintés

Ebben a gyors bemutatóban megnézzük, hogyan kell definiáljon több belépési pontot a Spring Security alkalmazásban.

Ez főleg többszörös meghatározását vonja maga után http blokkok egy XML konfigurációs fájlban vagy több HttpBiztonság példányok kiterjesztésével WebSecurityConfigurerAdapter osztály többször.

2. Maven-függőségek

A fejlesztéshez a következő függőségekre lesz szükségünk:

 org.springframework.boot spring-boot-starter-security 2.2.2.RELEASE org.springframework.boot spring-boot-starter-web 2.2.2.RELEASE org.springframework.boot spring-boot-starter-thymeleaf 2.2.2. RELEASE org.springframework.boot spring-boot-starter-test 2.2.2.RELEASE org.springframework.security spring-security-test 5.2.2.RELEASE 

A spring-boot-starter-security, spring-boot-starter-web, spring-boot-starter-thymeleaf, spring-boot-starter-test, spring-security-test legújabb verziói letölthetők a Maven Central webhelyről.

3. Több belépési pont

3.1. Több belépési pont több HTTP elemmel

Határozzuk meg a fő konfigurációs osztályt, amely egy felhasználói forrást fog tárolni:

@Configuration @EnableWebSecurity public class MultipleEntryPointsSecurityConfig {@Bean public UserDetailsService userDetailsService () dobja a Kivételt {InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager (); manager.createUser (Felhasználó .withUsername ("felhasználó") .jelszó (encoder (). encode ("userPass")) .roles ("USER"). build ()); manager.createUser (Felhasználó .withUsername ("admin") .jelszó (encoder (). encode ("adminPass")) .roles ("ADMIN"). build ()); visszatérési menedzser; } @Bean public PasswordEncoder kódoló () {return new BCryptPasswordEncoder (); }}

Most nézzük meg hogyan definiálhatunk több belépési pontot a biztonsági konfigurációnkban.

Itt az Alapos hitelesítés által vezérelt példát fogjuk használni, és ezt jól ki fogjuk használni A Spring Security támogatja a több HTTP elem meghatározását konfigurációinkban.

A Java konfiguráció használatakor a több biztonsági tartomány definiálásának módja az, hogy többel rendelkezik @ Konfiguráció osztályok, amelyek kiterjesztik a WebSecurityConfigurerAdapter alaposztály - mindegyik saját biztonsági konfigurációval rendelkezik. Ezek az osztályok lehetnek statikusak és elhelyezhetők a fő konfigurációban.

Az a fő motiváció, hogy egy alkalmazásban több belépési pont legyen, ha különböző típusú felhasználók vannak, akik hozzáférhetnek az alkalmazás különböző részeihez.

Határozzunk meg egy konfigurációt három belépési ponttal, mindegyik különböző jogosultságokkal és hitelesítési módokkal:

  • egyet a HTTP alaphitelesítést használó adminisztrációs felhasználók számára
  • egyet azoknak a rendszeres felhasználóknak, akik űrlaphitelesítést használnak
  • és egyet vendégfelhasználók számára, akik nem igényelnek hitelesítést

Az adminisztrátori felhasználók számára meghatározott belépési pont biztosítja az űrlap URL-jeit / admin / ** csak az ADMIN szerepkörrel rendelkező felhasználók számára engedélyezhető, és HTTP alapú hitelesítést igényel típusú belépési ponttal BasicAuthenticationEntryPoint amelyet a authenticationEntryPoint () módszer:

@Configuration @Order (1) public static class App1ConfigurationAdapter kiterjeszti a WebSecurityConfigurerAdapter {@Orride védett void konfigurációt (HttpSecurity http) dobja a {http.antMatcher ("/ admin / **") kivételt. GYÁRTÓ ") .és (). HttpBasic (). AuthenticationEntryPoint (authenticationEntryPoint ()); } @Bean public AuthenticationEntryPoint hitelesítésEntryPoint () {BasicAuthenticationEntryPoint entryPoint = új BasicAuthenticationEntryPoint (); entryPoint.setRealmName ("rendszergazda"); return entryPoint; }}

A @Rendelés Az egyes statikus osztályok feliratozása azt a sorrendet jelzi, amelyben a konfigurációk úgy tekinthetők, hogy megtalálják a kért URL-nek megfelelőt. A rendelés Minden osztály értékének egyedinek kell lennie.

A típusú bab BasicAuthenticationEntryPoint megköveteli az ingatlant igazi neve be kell állítani.

3.2. Több belépési pont, ugyanaz a HTTP elem

Ezután határozzuk meg az űrlap URL-jeinek konfigurációját / user / ** amelyhez a USER szerepkörrel rendelkező rendszeres felhasználók űrlaphitelesítéssel férhetnek hozzá:

A @Configuration @Order (2) public static class ) .and () // formLogin configuration .and () .exceptionHandling () .defaultAuthenticationEntryPointFor (loginUrlauthenticationEntryPointWithWarning (), new AntPathRequestMatcher ("/ user / private / **")) .defaultAuthenticationEntryPointFor (loginU felhasználó / általános / ** ")); }}

Mint láthatjuk, a authenticationEntryPoint () metódus mellett a belépési pontok meghatározásának egy másik módja a defaultAuthenticationEntryPointFor () módszer. Ez meghatározhat több belépési pontot, amelyek megfelelnek a különböző feltételeknek a RequestMatcher tárgy.

A RequestMatcher Az interfész megvalósításai különböző típusú feltételeken alapulnak, például illesztési út, médiatípus vagy regexp. Példánkban az AntPathRequestMatch segítségével két különböző belépési pontot állítottunk be az űrlapok URL-jéhez / user / private / ** és / user / general / **.

Ezután meg kell határoznunk a belépési pontokat ugyanabban a statikus konfigurációs osztályban:

@Bean public AuthenticationEntryPoint loginUrlauthenticationEntryPoint () {return new LoginUrlAuthenticationEntryPoint ("/ userLogin"); } @Bean public AuthenticationEntryPoint loginUrlauthenticationEntryPointWithWarning () {return new LoginUrlAuthenticationEntryPoint ("/ userLoginWithWarning"); }

A lényeg itt az, hogy miként állítsuk be ezeket a többszörös belépési pontokat - nem feltétlenül mindegyik megvalósítási részleteit.

Ebben az esetben a belépési pontok mind típusúak LoginUrlAuthenticationEntryPoint, és használjon más bejelentkezési oldal URL-t: /bejelentkezés egy egyszerű bejelentkezési oldalhoz és / userLoginWithWarning egy bejelentkezési oldal esetében, amely figyelmeztetést is megjelenít, amikor megpróbálja elérni a / user / privát URL-ek.

Ehhez a konfigurációhoz a /bejelentkezés és / userLoginWithWarning MVC-leképezések és két oldal szabványos bejelentkezési űrlappal.

Az űrlap hitelesítéséhez nagyon fontos megjegyezni, hogy a konfigurációhoz szükséges minden URL-nek, például a bejelentkezési feldolgozási URL-nek is követnie kell a / user / ** formátumban, vagy más módon kell konfigurálni, hogy hozzáférhető legyen.

Mindkét fenti konfiguráció átirányítja a /403 URL, ha a megfelelő szerepkör nélküli felhasználó megpróbál hozzáférni egy védett URL-hez.

Vigyázzon arra, hogy a babokra egyedi neveket használjon, még akkor is, ha azok különböző statikus osztályokban vannak, különben az egyik felülírja a másikat.

3.3. Új HTTP elem, nincs belépési pont

Végül definiáljuk az űrlap URL-jeinek harmadik konfigurációját /vendég/** amely lehetővé teszi minden típusú felhasználó számára, beleértve a nem hitelesített felhasználókat is:

@Configuration @Order (3) public static class App3ConfigurationAdapter kiterjeszti a WebSecurityConfigurerAdapter {védett void configure (HttpSecurity http) dobja a (z) {http.antMatcher ("/ guest / **") kivételt. }}

3.4. XML konfiguráció

Vessünk egy pillantást a három egyenértékű XML konfigurációjára HttpBiztonság példák az előző szakaszban.

A várakozásoknak megfelelően ez három külön XML-t fog tartalmazni blokkok.

A / admin / ** Az XML-konfiguráció által használt URL-ek a belépési pont-ref attribútuma http-basic elem:

Megjegyzendő itt, hogy XML konfiguráció használata esetén a szerepeknek formájúaknak kell lenniük SZEREP_.

A. Konfigurációja / user / ** Az URL-eket két részre kell bontani http blokkolja az xml-t, mert nincs közvetlen megfelelője az defaultAuthenticationEntryPointFor () módszer.

Az URL / user / general / ** konfigurációja:

  // űrlap-bejelentkezés konfigurációja 

A / user / private / ** URL-ek hasonló konfigurációt definiálhatunk:

  // űrlap-bejelentkezés konfigurációja 

A /vendég/** URL-ek, amelyekkel rendelkezünk http elem:

Fontos itt az is, hogy legalább egy XML blokknak meg kell egyeznie a / ** mintával.

4. Hozzáférés a védett URL-ekhez

4.1. MVC konfiguráció

Hozzunk létre kérés-hozzárendeléseket, amelyek megfelelnek az általunk biztosított URL-mintáknak:

@Controller public class PagesController {@GetMapping ("/ admin / myAdminPage") public String getAdminPage () {return "multipleHttpElems / myAdminPage"; } @GetMapping ("/ user / general / myUserPage") public String getUserPage () {return "multipleHttpElems / myUserPage"; } @GetMapping ("/ user / private / myPrivateUserPage") public String getPrivateUserPage () {return "multipleHttpElems / myPrivateUserPage"; } @GetMapping ("/ guest / myGuestPage") public String getGuestPage () {return "multipleHttpElems / myGuestPage"; } @GetMapping ("/ multipleHttpLinks") public String getMultipleHttpLinksPage () {return "multipleHttpElems / multipleHttpLinks"; }}

A / multipleHttpLinks a leképezés egy egyszerű HTML oldalt jelenít meg, amely linkeket tartalmaz a védett URL-ekre:

Adminisztrációs oldal Felhasználói oldal Privát felhasználói oldal Vendégoldal

A védett URL-eknek megfelelő HTML-oldalak mindegyikének egyszerű szövege és visszalinkje lesz:

Üdvözöljük admin! Vissza a linkekhez

4.2. Az alkalmazás inicializálása

A példánkat Spring Boot alkalmazásként fogjuk futtatni, ezért határozzunk meg egy osztályt a fő módszerrel:

@SpringBootApplication public class MultipleEntryPointsApplication {public static void main (String [] args) {SpringApplication.run (MultipleEntryPointsApplication.class, args); }}

Ha használni akarjuk az XML konfigurációt, akkor hozzá kell adnunk a @ImportResource ({“classpath *: spring-security-multiple-entry.xml”}) annotáció főosztályunknak.

4.3. A biztonsági konfiguráció tesztelése

Állítsunk be egy JUnit tesztosztályt, amelyet a védett URL-ek tesztelésére használhatunk:

@RunWith (SpringRunner.class) @WebAppConfiguration @SpringBootTest (class = MultipleEntryPointsApplication.class) public class MultipleEntryPointsTest {@Autowired private WebApplicationContext wac; @Autowired privát FilterChainProxy springSecurityFilterChain; privát MockMvc mockMvc; @A nyilvános void beállítása előtt () {this.mockMvc = MockMvcBuilders.webAppContextSetup (this.wac) .addFilter (springSecurityFilterChain) .build (); }}

Ezután teszteljük az URL-eket a admin felhasználó.

A / admin / adminPage Alapvető HTTP-hitelesítés nélküli URL-re számíthatunk egy jogosulatlan állapotkód fogadására, és a hitelesítés hozzáadása után az állapotkódnak 200 OK-nak kell lennie.

Ha megpróbálja elérni a / user / userPage URL-t az adminisztrátorral, meg kell kapnunk a 302 Tiltott állapotot:

@Test public void, amikor aTestAdminCredentials_thenOk () kiveti a (z) {mockMvc.perform (get ("/ admin / myAdminPage")) kivételt. És az Expect (status (). IsUnauthorized ()); mockMvc.perform (get ("/ admin / myAdminPage") .with (httpBasic ("admin", "adminPass")))). ésExpect (status (). isOk ()); mockMvc.perform (get ("/ user / myUserPage") .with (user ("admin"). jelszó ("adminPass"). szerepek ("ADMIN"))). andExpect (status (). isForbidden ()); }

Hozzunk létre egy hasonló tesztet a normál felhasználói hitelesítő adatok segítségével az URL-ek eléréséhez:

@Test public void, amikor a TestUserCredentials_thenOk () kiveti a (z) {mockMvc.perform (get ("/ user / general / myUserPage")) kivételt. ÉsExpect (status (). IsFound ()); mockMvc.perform (get ("/ user / general / myUserPage") .with (felhasználó ("felhasználó"). jelszó ("userPass"). szerepek ("FELHASZNÁLÓ"))).) és várakozás (állapot (). isOk () ); mockMvc.perform (get ("/ admin / myAdminPage") .with (user ("user"). jelszó ("userPass"). szerepek ("USER"))) .andExpect (status (). isForbidden ()); }

A második tesztben láthatjuk, hogy az űrlap hitelesítés hiánya 302 állapotot eredményez a jogosulatlan helyett, mivel a Spring Security átirányítja a bejelentkezési űrlaphoz.

Végül hozzunk létre egy tesztet, amelyben hozzáférünk a / guest / guestPage Az URL mind a három típusú hitelesítést elvégzi, és igazolja, hogy 200 OK állapotot kapunk:

@Test public void givenAnyUser_whenGetGuestPage_thenOk () dobja a Kivételt {mockMvc.perform (get ("/ guest / myGuestPage")). ÉsExpect (status (). IsOk ()); mockMvc.perform (get ("/ guest / myGuestPage") .with (user ("user"). jelszó ("userPass"). szerepek ("USER"))) .andExpect (status (). isOk ()); mockMvc.perform (get ("/ guest / myGuestPage") .with (httpBasic ("admin", "adminPass"))) .andExpect (status (). isOk ()); }

5. Következtetés

Ebben az oktatóanyagban bemutattuk, hogyan konfigurálhat több belépési pontot a Spring Security használatakor.

A példák teljes forráskódja megtalálható a GitHub oldalon. Az alkalmazás futtatásához szüntesse meg a MultipleEntryPointsApplicationkezdő osztály címke a pom.xml és futtassa a parancsot mvn spring-boot: fut, majd hozzáfér a / multipleHttpLinks URL.

Vegye figyelembe, hogy a HTTP Basic Authentication használatakor nem lehet kijelentkezni, ezért a hitelesítés eltávolításához be kell zárnia és újra meg kell nyitnia a böngészőt.

A JUnit teszt futtatásához használja a megadott Maven profilt entryPoints a következő paranccsal:

mvn clean install -PentryPoints