Viaceré vstupné body v jarnej bezpečnosti

1. Prehľad

V tomto rýchlom výučbe sa pozrieme na to, ako na to definujte viac vstupných bodov v aplikácii Spring Security.

Znamená to hlavne definovanie viacerých http bloky v konfiguračnom súbore XML alebo vo viacerých HttpSecurity prípadoch rozšírením WebSecurityConfigurerAdapter triedy viackrát.

2. Maven závislosti

Na vývoj budeme potrebovať nasledujúce závislosti:

 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 test Spring-Boot-Starter 2.2.2.RELEASE org.springframework.security Spring-Security-Test 5.2.2.RELEASE 

Najnovšie verzie testov spring-boot-starter-security, spring-boot-starter-web, spring-boot-starter-thymeleaf, spring-boot-starter-test, spring-security-test si môžete stiahnuť z Maven Central.

3. Viac vstupných bodov

3.1. Viaceré vstupné body s viacerými prvkami HTTP

Poďme definovať hlavnú konfiguračnú triedu, ktorá bude obsahovať zdroj používateľa:

@Configuration @EnableWebSecurity verejná trieda MultipleEntryPointsSecurityConfig {@Bean public UserDetailsService userDetailsService () vyvolá výnimku {InMemoryUserDetailsManager manager = nový InMemoryUserDetailsManager (); manager.createUser (User .withUsername ("user") .password (encoder (). encode ("userPass")) .roles ("USER"). build ()); manager.createUser (Používateľ .withUsername ("admin") .password (encoder (). encode ("adminPass")) .roles ("ADMIN"). build ()); manažér návratu; } @Bean public PasswordEncoder encoder () {return new BCryptPasswordEncoder (); }}

Teraz sa pozrime na ako môžeme definovať viac vstupných bodov v našej konfigurácii zabezpečenia.

Použijeme tu príklad založený na základnom overovaní a túto skutočnosť dobre využijeme Spring Security podporuje definíciu viacerých prvkov HTTP v našich konfiguráciách.

Pri použití konfigurácie Java je spôsob, ako definovať viac bezpečnostných sfér, mať viac @ Konfigurácia triedy, ktoré rozširujú WebSecurityConfigurerAdapter základná trieda - každá s vlastnou konfiguráciou zabezpečenia. Tieto triedy môžu byť statické a umiestnené vo vnútri hlavnej konfigurácie.

Hlavnou motiváciou pre získanie viacerých vstupných bodov v jednej aplikácii je, ak existujú rôzne typy používateľov, ktorí majú prístup k rôznym častiam aplikácie.

Definujme konfiguráciu s tromi vstupnými bodmi, z ktorých každý má odlišné povolenia a režimy autentifikácie:

  • jeden pre administratívnych používateľov používajúcich základné overenie HTTP
  • jeden pre bežných používateľov, ktorí používajú overovanie formulárov
  • a jeden pre hosťujúcich používateľov, ktorí nevyžadujú overenie

Vstupný bod definovaný pre administratívnych používateľov zabezpečuje adresy URL formulára / admin / ** povoliť iba používateľov s rolou ADMIN a vyžaduje základné overenie HTTP so vstupným bodom typu BasicAuthenticationEntryPoint ktorý sa nastavuje pomocou authenticationEntryPoint () metóda:

@Configuration @Order (1) verejná statická trieda App1ConfigurationAdapter rozširuje WebSecurityConfigurerAdapter {@Override protected void configure (HttpSecurity http) vyvolá výnimku {http.antMatcher ("/ admin / **") .authorizeRequests (). AnyRequest (). HasRole (" ADMIN "). A (). HttpBasic (). AuthenticationEntryPoint (authenticationEntryPoint ()); } @Bean public AuthenticationEntryPoint authenticationEntryPoint () {BasicAuthenticationEntryPoint entryPoint = nový BasicAuthenticationEntryPoint (); entryPoint.setRealmName ("oblasť správcu"); vrátiť entryPoint; }}

The @Objednať anotácia pre každú statickú triedu označuje poradie, v akom sa konfigurácie budú považovať za také, ktoré zodpovedajú požadovanej adrese URL. The objednať hodnota pre každú triedu musí byť jedinečná.

Fazuľa typu BasicAuthenticationEntryPoint vyžaduje nehnuteľnosť skutočné meno byť nastavený.

3.2. Viaceré vstupné body, rovnaký prvok HTTP

Ďalej definujeme konfiguráciu adries URL formulára / užívateľ / ** ku ktorým majú prístup bežní používatelia s rolou USER pomocou autentifikácie formulára:

@Configuration @Order (2) verejná statická trieda App2ConfigurationAdapter rozširuje WebSecurityConfigurerAdapter {protected void configure (HttpSecurity http) vyvolá výnimku {http.antMatcher ("/ user / **") .authorizeRequests (). AnyRequest (). HasRole ("USER") ). a () // konfigurácia formLogin .and () .exceptionHandling () .defaultAuthenticationEntryPointFor (loginUrlauthenticationEntryPointWithWarning (), nový AntPathRequestMatcher ("/ user / private / **")) .defaultAuthenticationEntryPointFor (loginUrlauthenticationEntryPoint) užívateľ / všeobecný / ** ")); }}

Ako vidíme, ďalším spôsobom definovania vstupných bodov je okrem metódy authenticationEntryPoint () použitie defaultAuthenticationEntryPointFor () metóda. To môže definovať viac vstupných bodov, ktoré zodpovedajú rôznym podmienkam na základe a RequestMatcher objekt.

The RequestMatcher rozhranie má implementácie založené na rôznych typoch podmienok, ako napríklad zhoda cesty, typu média alebo regexp. V našom príklade sme použili AntPathRequestMatch na nastavenie dvoch rôznych vstupných bodov pre adresy URL formulárov / používateľ / súkromné ​​/ ** a / používateľ / všeobecné / **.

Ďalej musíme definovať vstupné body fazuľa v rovnakej triede statickej konfigurácie:

@Bean public AuthenticationEntryPoint loginUrlauthenticationEntryPoint () {vrátiť nové LoginUrlAuthenticationEntryPoint ("/ userLogin"); } @Bean public AuthenticationEntryPoint loginUrlauthenticationEntryPointWithWarning () {vrátiť nové LoginUrlAuthenticationEntryPoint ("/ userLoginWithWarning"); }

Hlavným bodom je, ako nastaviť tieto viaceré vstupné body - nie nevyhnutne podrobnosti implementácie každého z nich.

V takom prípade sú vstupné body obidva typu LoginUrlAuthenticationEntryPointa použite inú adresu URL prihlasovacej stránky: / userLogin pre jednoduchú prihlasovaciu stránku a / userLoginWithWarning pre prihlasovaciu stránku, ktorá tiež zobrazuje varovanie pri pokuse o prístup k / užívateľ / súkromné ​​adresy URL.

Táto konfigurácia bude tiež vyžadovať definovanie / userLogin a / userLoginWithWarning Mapovania MVC a dve stránky so štandardným prihlasovacím formulárom.

Pri overovaní formulára je veľmi dôležité pamätať na to, že každá adresa URL nevyhnutná na konfiguráciu, napríklad adresa URL na spracovanie prihlásenia, musí tiež zodpovedať / užívateľ / ** formát alebo byť inak nakonfigurovaný tak, aby bol prístupný.

Obe vyššie uvedené konfigurácie budú presmerované na a /403 URL, ak sa užívateľ bez príslušnej role pokúsi získať prístup k chránenej adrese URL.

Buďte opatrní, aby ste pre fazuľu používali jedinečné názvy, aj keď sú v rôznych statických triedach, inak jedno prepíše druhé.

3.3. Nový prvok HTTP, žiadny vstupný bod

Na záver definujeme tretiu konfiguráciu pre adresy URL formulára /hosť/** ktoré umožnia všetkým typom používateľov vrátane tých neautentizovaných:

@Configuration @Order (3) verejná statická trieda App3ConfigurationAdapter rozširuje WebSecurityConfigurerAdapter {protected void configure (HttpSecurity http) vyvolá výnimku {http.antMatcher ("/ guest / **"). AuthorizeRequests (). AnyRequest (). PermitAll (); }}

3.4. Konfigurácia XML

Pozrime sa na ekvivalentnú konfiguráciu XML pre všetky tri HttpSecurity v predchádzajúcej časti.

Podľa očakávania bude obsahovať tri samostatné súbory XML blokov.

Pre / admin / ** Adresy URL, ktoré konfigurácia XML použije vstupný bod-ref atribút http-basic element:

Je potrebné poznamenať, že ak sa používa konfigurácia XML, role musia mať formu ROLE_.

Konfigurácia pre / užívateľ / ** Adresy URL budú musieť byť rozdelené na dve http bloky v xml, pretože neexistuje žiadny priamy ekvivalent s defaultAuthenticationEntryPointFor () metóda.

Konfigurácia webových adries / user / general / ** je:

  // konfigurácia prihlásenia do formulára 

Pre / používateľ / súkromné ​​/ ** URL môžeme definovať podobnú konfiguráciu:

  // konfigurácia prihlásenia do formulára 

Pre /hosť/** URL, ktoré budeme mať http element:

Tu je tiež dôležité, aby aspoň jeden XML blok sa musí zhodovať so vzorom / **.

4. Prístup k chráneným adresám URL

4.1. Konfigurácia MVC

Vytvorme mapovania požiadaviek, ktoré zodpovedajú vzorom adries URL, ktoré sme zabezpečili:

@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") verejný reťazec getMultipleHttpLinksPage () {return "multipleHttpElems / multipleHttpLinks"; }}

The / multipleHttpLinks mapovanie vráti jednoduchú stránku HTML s odkazmi na chránené adresy URL:

Stránka správcu Stránka používateľa Súkromná stránka používateľa Stránka hosťa

Každá zo stránok HTML zodpovedajúcich chráneným adresám URL bude mať jednoduchý text a spätný odkaz:

Vitajte admin! Späť na odkazy

4.2. Inicializácia aplikácie

Náš príklad spustíme ako aplikáciu Spring Boot, takže si definujme triedu pomocou hlavnej metódy:

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

Ak chceme použiť konfiguráciu XML, musíme pridať aj @ImportResource ({„classpath *: spring-security-multiple-entry.xml“}) anotácia k našej hlavnej triede.

4.3. Testovanie konfigurácie zabezpečenia

Poďme nastaviť testovaciu triedu JUnit, ktorú môžeme použiť na testovanie našich chránených adries URL:

@RunWith (SpringRunner.class) @WebAppConfiguration @SpringBootTest (classes = MultipleEntryPointsApplication.class) verejná trieda MultipleEntryPointsTest {@Autowired private WebApplicationContext wac; @Autowired private FilterChainProxy springSecurityFilterChain; súkromné ​​MockMvc mockMvc; @Before public void setup () {this.mockMvc = MockMvcBuilders.webAppContextSetup (this.wac) .addFilter (springSecurityFilterChain) .build (); }}

Ďalej otestujme adresy URL pomocou admin používateľ.

Pri žiadosti o / admin / adminPage URL bez základného overenia HTTP, mali by sme očakávať, že dostaneme neoprávnený stavový kód a po pridaní overenia by mal byť stavový kód 200 v poriadku.

Pri pokuse o prístup k / user / userPage URL s administrátorským používateľom, mali by sme dostať stav 302 Zakázané:

@ Test public void whenTestAdminCredentials_thenOk () vyvolá výnimku {mockMvc.perform (get ("/ admin / myAdminPage")). AndExpect (status (). IsUnauthorized ()); mockMvc.perform (get ("/ admin / myAdminPage") .with (httpBasic ("admin", "adminPass"))). andExpect (status (). isOk ()); mockMvc.perform (get ("/ user / myUserPage") .with (user ("admin"). password ("adminPass"). roles ("ADMIN"))) .andExpect (status (). isForbidden ()); }

Vytvorme podobný test pomocou bežných prihlasovacích údajov používateľa na prístup k adresám URL:

@Test public void whenTestUserCredentials_thenOk () vyvolá výnimku {mockMvc.perform (get ("/ user / general / myUserPage")). AndExpect (status (). IsFound ()); mockMvc.perform (get ("/ user / general / myUserPage") .with (user ("user"). password ("userPass"). role ("USER"))). andExpect (status (). isOk () ); mockMvc.perform (get ("/ admin / myAdminPage") .with (user ("user"). heslo ("userPass"). role ("USER"))). andExpect (status (). isForbidden ()); }

V druhom teste vidíme, že chýbajúca autentifikácia formulára bude mať za následok stav 302 Nájdené namiesto neoprávneného, ​​pretože Spring Security presmeruje na prihlasovací formulár.

Nakoniec vytvorme test, v ktorom pristupujeme k / hosť / hosťStrana URL bude všetky tri typy autentifikácie a overí, či dostaneme stav 200 OK:

@Test public void givenAnyUser_whenGetGuestPage_thenOk () vyvolá výnimku {mockMvc.perform (get ("/ guest / myGuestPage")). AndExpect (status (). IsOk ()); mockMvc.perform (get ("/ guest / myGuestPage") .with (user ("user"). heslo ("userPass"). role ("USER"))). andExpect (status (). isOk ()); mockMvc.perform (get ("/ guest / myGuestPage") .with (httpBasic ("admin", "adminPass"))) .andExpect (status (). isOk ()); }

5. Záver

V tomto tutoriáli sme si ukázali, ako nakonfigurovať viac vstupných bodov pri použití Spring Security.

Celý zdrojový kód príkladov nájdete na GitHub. Ak chcete spustiť aplikáciu, odkomentujte MultipleEntryPointsApplicationštart-trieda značka v pom.xml a spustite príkaz mvn spring-boot: spustiť, potom prejde na / multipleHttpLinks URL.

Upozorňujeme, že pri použití základného overenia HTTP nie je možné sa odhlásiť, takže na odstránenie tohto overenia budete musieť prehliadač zavrieť a znovu otvoriť.

Na spustenie testu JUnit použite definovaný profil Maven entryPoints pomocou nasledujúceho príkazu:

mvn clean install -PentryPoints


$config[zx-auto] not found$config[zx-overlay] not found