Flere indgangspunkter i forårssikkerhed

1. Oversigt

I denne hurtige vejledning skal vi se på, hvordan man gør det definer flere indgangspunkter i en Spring Security-applikation.

Dette indebærer primært at definere flere http blokerer i en XML-konfigurationsfil eller flere HttpSikkerhed tilfælde ved at udvide WebSecurityConfigurerAdapter klasse flere gange.

2. Maven-afhængigheder

Til udvikling har vi brug for følgende afhængigheder:

 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 

De nyeste versioner af spring-boot-starter-security, spring-boot-starter-web, spring-boot-starter-thymeleaf, spring-boot-starter-test, spring-security-test kan downloades fra Maven Central.

3. Flere indgangspunkter

3.1. Flere indgangspunkter med flere HTTP-elementer

Lad os definere den vigtigste konfigurationsklasse, der indeholder en brugerkilde:

@Configuration @EnableWebSecurity public class MultipleEntryPointsSecurityConfig {@Bean public UserDetailsService userDetailsService () kaster undtagelse {InMemoryUserDetailsManager manager = ny InMemoryUserDetailsManager (); manager.createUser (User .withUsername ("user") .password (encoder (). encode ("userPass")) .roles ("USER"). build ()); manager.createUser (User .withUsername ("admin") .password (encoder (). encode ("adminPass")) .roles ("ADMIN"). build ()); returleder; } @Bean public PasswordEncoder encoder () {returner ny BCryptPasswordEncoder (); }}

Lad os nu se på hvordan vi kan definere flere indgangspunkter i vores sikkerhedskonfiguration.

Vi skal bruge et eksempel drevet af grundlæggende godkendelse her, og vi vil gøre god brug af det faktum, at Spring Security understøtter definitionen af ​​flere HTTP-elementer i vores konfigurationer.

Når du bruger Java-konfiguration, er måden at definere flere sikkerhedsområder at have flere @Konfiguration klasser, der udvider WebSecurityConfigurerAdapter baseklasse - hver med sin egen sikkerhedskonfiguration. Disse klasser kan være statiske og placeres inde i hovedkonfigurationen.

Den vigtigste motivation for at have flere indgangspunkter i en applikation er, hvis der er forskellige typer brugere, der kan få adgang til forskellige dele af applikationen.

Lad os definere en konfiguration med tre indgangspunkter, hver med forskellige tilladelser og godkendelsestilstande:

  • en til administrative brugere, der bruger HTTP Basic Authentication
  • en til almindelige brugere, der bruger formulargodkendelse
  • og en til gæstebrugere, der ikke kræver godkendelse

Indgangsstedet defineret for administrative brugere sikrer URL-adresser til formularen / admin / ** for kun at tillade brugere med rollen ADMIN og kræver HTTP Basic Authentication med et indgangspunkt af typen BasicAuthenticationEntryPoint der indstilles ved hjælp af godkendelseEntryPoint () metode:

@Configuration @Order (1) offentlig statisk klasse App1ConfigurationAdapter udvider WebSecurityConfigurerAdapter {@Override beskyttet ugyldig konfiguration (HttpSecurity http) kaster Undtagelse {http.antMatcher ("/ admin / **") .authorizeRequests (). AnyRequest (). HasRole (" ADMIN "). Og (). HttpBasic (). AuthenticationEntryPoint (authenticationEntryPoint ()); } @Bean public AuthenticationEntryPoint authenticationEntryPoint () {BasicAuthenticationEntryPoint entryPoint = new BasicAuthenticationEntryPoint (); entryPoint.setRealmName ("admin realm"); returner entrypoint; }}

Det @Bestille annotation på hver statiske klasse angiver den rækkefølge, hvori konfigurationerne anses for at finde en, der matcher den ønskede URL. Det bestille værdien for hver klasse skal være unik.

Bønnen af ​​typen BasicAuthenticationEntryPoint kræver ejendommen rigtige navn være indstillet.

3.2. Flere indgangspunkter, samme HTTP-element

Lad os derefter definere konfigurationen til URL'erne i formularen /bruger/** der kan tilgås af almindelige brugere med en USER-rolle ved hjælp af formgodkendelse:

@Configuration @Order (2) offentlig statisk klasse App2ConfigurationAdapter udvider WebSecurityConfigurerAdapter {beskyttet ugyldig konfiguration (HttpSecurity http) kaster undtagelse {http.antMatcher ("/ user / **") .authorizeRequests (). AnyRequest (). HasRole ("USER" ) .and () // formLogin-konfiguration .og () .exceptionHandling () .defaultAuthenticationEntryPointFor (loginUrlauthenticationEntryPointWithWarning (), ny AntPathRequestMatcher ("/ bruger / privat / **")). defaultAuthenticationEntryPointFor (loginUrnt bruger / generel / ** ")); }}

Som vi kan se, er en anden måde at definere indgangspunkter ud over metoden authenticationEntryPoint () at bruge defaultAuthenticationEntryPointFor () metode. Dette kan definere flere indgangspunkter, der matcher forskellige betingelser baseret på en RequestMatcher objekt.

Det RequestMatcher interface har implementeringer baseret på forskellige typer betingelser, såsom matchende sti, medietype eller regexp. I vores eksempel har vi brugt AntPathRequestMatch til at indstille to forskellige indgangspunkter for URL'erne til formularerne / bruger / privat / ** og / bruger / generelt / **.

Dernæst skal vi definere indgangspunkterne i den samme statiske konfigurationsklasse:

@Bean offentlig AuthenticationEntryPoint loginUrlauthenticationEntryPoint () {returner ny LoginUrlAuthenticationEntryPoint ("/ userLogin"); } @Bean offentlig AuthenticationEntryPoint loginUrlauthenticationEntryPointWithWarning () {returner nyt LoginUrlAuthenticationEntryPoint ("/ userLoginWithWarning"); }

Hovedpunktet her er, hvordan man opsætter disse flere indgangspunkter - ikke nødvendigvis implementeringsoplysningerne for hver enkelt.

I dette tilfælde er indgangspunkterne begge af typen LoginUrlAuthenticationEntryPoint, og brug en anden URL til login-siden: / userLogin for en enkel login-side og / userLoginWithWarning for en login-side, der også viser en advarsel, når du forsøger at få adgang til /bruger/ private webadresser.

Denne konfiguration skal også definere / userLogin og / userLoginWithWarning MVC-kortlægninger og to sider med en standard loginformular.

Til formulargodkendelse er det meget vigtigt at huske, at enhver URL, der er nødvendig for konfigurationen, såsom URL til loginbehandling, også skal følge /bruger/** format eller på anden måde være konfigureret til at være tilgængelig.

Begge ovenstående konfigurationer omdirigeres til a /403 URL, hvis en bruger uden den rette rolle forsøger at få adgang til en beskyttet URL.

Pas på at bruge unikke navne på bønnerne, selvom de er i forskellige statiske klasser, ellers tilsidesætter den ene den anden.

3.3. Nyt HTTP-element, intet indgangspunkt

Lad os endelig definere den tredje konfiguration for URL'erne i formularen /gæst/** der tillader alle typer brugere, inklusive uautoriserede:

@Configuration @ Order (3) offentlig statisk klasse App3ConfigurationAdapter udvider WebSecurityConfigurerAdapter {beskyttet ugyldig konfiguration (HttpSecurity http) kaster undtagelse {http.antMatcher ("/ gæst / **"). AuthorizeRequests (). AnyRequest (). PermitAll (); }}

3.4. XML-konfiguration

Lad os se på den tilsvarende XML-konfiguration for de tre HttpSikkerhed forekomster i det forrige afsnit.

Som forventet vil dette indeholde tre separate XML blokke.

Til / admin / ** URL'er, som XML-konfigurationen bruger indgangs-ref attribut for http-basic element:

Bemærk her, at hvis du bruger XML-konfiguration, skal rollerne have formen ROL_.

Konfigurationen til /bruger/** URL'er skal opdeles i to http blokke i xml, fordi der ikke er nogen direkte ækvivalent med defaultAuthenticationEntryPointFor () metode.

Konfigurationen for URL'er / bruger / generel / ** er:

  // konfiguration af form-login 

Til / bruger / privat / ** URL'er, vi kan definere en lignende konfiguration:

  // konfiguration af form-login 

Til /gæst/** Webadresser, vi har http element:

Her er også vigtigt, at mindst en XML blokken skal matche / ** mønsteret.

4. Adgang til beskyttede webadresser

4.1. MVC-konfiguration

Lad os oprette anmodningstilknytninger, der matcher de URL-mønstre, vi har sikret:

@Controller offentlig klasse PagesController {@GetMapping ("/ admin / myAdminPage") offentlig streng getAdminPage () {returner "multipleHttpElems / myAdminPage"; } @GetMapping ("/ user / general / myUserPage") offentlig streng getUserPage () {returner "multipleHttpElems / myUserPage"; } @GetMapping ("/ bruger / privat / myPrivateUserPage") offentlig String getPrivateUserPage () {returner "multipleHttpElems / myPrivateUserPage"; } @GetMapping ("/ gæst / myGuestPage") offentlig streng getGuestPage () {returner "multipleHttpElems / myGuestPage"; } @GetMapping ("/ multipleHttpLinks") offentlig streng getMultipleHttpLinksPage () {returner "multipleHttpElems / multipleHttpLinks"; }}

Det / multipleHttpLinks mapping returnerer en simpel HTML-side med links til de beskyttede URL'er:

Administratorside Brugerside Privat brugerside Gæsteside

Hver af de HTML-sider, der svarer til de beskyttede webadresser, har en simpel tekst og et backlink:

Velkommen admin! Tilbage til links

4.2. Initialisering af applikationen

Vi kører vores eksempel som en Spring Boot-applikation, så lad os definere en klasse med hovedmetoden:

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

Hvis vi vil bruge XML-konfigurationen, skal vi også tilføje @ImportResource ({“classpath *: spring-security-multiple-entry.xml”}) kommentar til vores hovedklasse.

4.3. Test af sikkerhedskonfigurationen

Lad os oprette en JUnit-testklasse, som vi kan bruge til at teste vores beskyttede webadresser:

@RunWith (SpringRunner.class) @WebAppConfiguration @SpringBootTest (klasser = MultipleEntryPointsApplication.class) offentlig klasse MultipleEntryPointsTest {@Autowired privat WebApplicationContext wac; @Autowired privat FilterChainProxy springSecurityFilterChain; private MockMvc mockMvc; @Før offentlig ugyldig opsætning () {this.mockMvc = MockMvcBuilders.webAppContextSetup (this.wac) .addFilter (springSecurityFilterChain) .build (); }}

Lad os derefter teste webadresserne ved hjælp af admin bruger.

Når man anmoder om / admin / adminPage URL uden en HTTP-grundlæggende godkendelse, vi skal forvente at modtage en uautoriseret statuskode, og efter tilføjelse af godkendelsen skal statuskoden være 200 OK.

Hvis du forsøger at få adgang til / bruger / brugerside URL med administratorbrugeren, vi skal modtage status 302 Forbidden:

@Test offentlig ugyldig når TestAdminCredentials_thenOk () kaster Undtagelse {mockMvc.perform (get ("/ admin / myAdminPage")). Og Forvent (status (). Er Uautoriseret ()); mockMvc.perform (get ("/ admin / myAdminPage") .med (httpBasic ("admin", "adminPass"))). og Forvent (status (). isOk ()); mockMvc.perform (get ("/ user / myUserPage") .med (user ("admin"). password ("adminPass") .roller ("ADMIN"))). og Expect (status (). isForbidden ()); }

Lad os oprette en lignende test ved hjælp af de almindelige brugeroplysninger for at få adgang til URL'erne:

@Test offentlig ugyldig når TestUserCredentials_thenOk () kaster undtagelse {mockMvc.perform (get ("/ user / general / myUserPage")). Og Expect (status (). IsFound ()); mockMvc.perform (get ("/ user / general / myUserPage") .med (user ("user"). password ("userPass") .roller ("USER"))). og Expect (status (). isOk () ); mockMvc.perform (get ("/ admin / myAdminPage") .med (user ("user"). password ("userPass") .roller ("USER"))). og Expect (status (). isForbidden ()); }

I den anden test kan vi se, at manglende formgodkendelse vil resultere i status 302 fundet i stedet for uautoriseret, da Spring Security omdirigerer til loginformularen.

Lad os endelig oprette en test, hvor vi får adgang til / gæst / gæstSide URL vil alle tre typer godkendelse og bekræfte, at vi modtager en status på 200 OK:

@Test offentlig ugyldighed givenAnyUser_whenGetGuestPage_thenOk () kaster undtagelse {mockMvc.perform (get ("/ guest / myGuestPage")). Og Expect (status (). IsOk ()); mockMvc.perform (get ("/ gæst / myGuestPage") .med (bruger ("bruger"). adgangskode ("userPass"). roller ("BRUGER"))). og Forvent (status (). isOk ()); mockMvc.perform (get ("/ guest / myGuestPage") .med (httpBasic ("admin", "adminPass"))). og Expect (status (). isOk ()); }

5. Konklusion

I denne vejledning har vi demonstreret, hvordan du konfigurerer flere indgangspunkter, når du bruger Spring Security.

Den komplette kildekode til eksemplerne kan findes på GitHub. Fjern kommentar for at køre applikationen MultipleEntryPointsApplicationstartklasse tag i pom.xml og kør kommandoen mvn spring-boot: løb, åbner derefter / multipleHttpLinks URL.

Bemærk, at det ikke er muligt at logge ud, når du bruger HTTP Basic Authentication, så du bliver nødt til at lukke og genåbne browseren for at fjerne denne godkendelse.

Brug den definerede Maven-profil til at køre JUnit-testen entryPoints med følgende kommando:

mvn ren installation -PentryPoints


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