Meerdere authenticatieleveranciers in Spring Security

1. Overzicht

In dit korte artikel gaan we ons concentreren op het gebruik van meerdere mechanismen om gebruikers in Spring Security te authenticeren.

We doen dat door meerdere authenticatieleveranciers te configureren.

2. Authenticatieproviders

Een AuthenticationProvider is een abstractie voor het ophalen van gebruikersinformatie uit een specifieke repository (zoals een database, LDAP, aangepaste externe bron, enz.). Het gebruikt de opgehaalde gebruikersinformatie om de verstrekte inloggegevens te valideren.

Simpel gezegd, wanneer meerdere authenticatieproviders zijn gedefinieerd, worden de providers ondervraagd in de volgorde waarin ze zijn aangegeven.

Voor een snelle demonstratie configureren we twee authenticatieleveranciers: een aangepaste authenticatieleverancier en een in-memory authenticatieprovider.

3. Maven afhankelijkheden

Laten we eerst de nodige Spring Security-afhankelijkheden toevoegen aan onze webapplicatie:

 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-security 

En, zonder Spring Boot:

 org.springframework.security spring-security-web 5.2.2.RELEASE org.springframework.security spring-security-core 5.2.2.RELEASE org.springframework.security spring-security-config 5.2.2.RELEASE 

De nieuwste versie van deze afhankelijkheden is te vinden op spring-security-web, spring-security-core en spring-security-config.

4. Aangepaste authenticatieleverancier

Laten we nu een aangepaste authenticatieleverancier maken door het AuthneticationProvider koppel.

We gaan het authenticeren methode - die de authenticatie probeert. De input Authenticatie object bevat de gebruikersnaam en wachtwoordreferenties die door de gebruiker zijn verstrekt.

De authenticeren methode retourneert een volledig gevuld Authenticatie object als de authenticatie is gelukt. Als de authenticatie mislukt, genereert het een uitzondering van het type AuthenticationException:

@Component public class CustomAuthenticationProvider implementeert AuthenticationProvider {@Override public Authentication authenticate (Authentication auth) genereert AuthenticationException {String gebruikersnaam = auth.getName (); String wachtwoord = auth.getCredentials () .toString (); if ("externaluser" .equals (gebruikersnaam) && "pass" .equals (wachtwoord)) {retourneer nieuwe UsernamePasswordAuthenticationToken (gebruikersnaam, wachtwoord, Collections.emptyList ()); } else {throw new BadCredentialsException ("Externe systeemauthenticatie mislukt"); }} @Override openbare booleaanse ondersteuning (Klasse auth) {retourneer auth.equals (UsernamePasswordAuthenticationToken.class); }}

Dit is natuurlijk een eenvoudige implementatie in het kader van ons voorbeeld hier.

5. Meerdere authenticatieleveranciers configureren

Laten we nu het CustomAuthenticationProvider en een in-memory authenticatieprovider voor onze Spring Security-configuratie.

5.1. Java-configuratie

Laten we in onze configuratieklasse nu de authenticatieleveranciers maken en toevoegen met behulp van de AuthenticationManagerBuilder.

Eerst de CustomAuthenticationProvider en vervolgens een in-memory authenticatieprovider door gebruik te maken van inMemoryAuthentication ().

We zorgen er ook voor dat toegang tot het URL-patroon "/ api / **”Moet worden geverifieerd:

@EnableWebSecurity openbare klasse MultipleAuthProvidersSecurityConfig breidt WebSecurityConfigurerAdapter uit {@Autowired CustomAuthenticationProvider customAuthProvider; @Override public void configure (AuthenticationManagerBuilder auth) genereert Uitzondering {auth.authenticationProvider (customAuthProvider); auth.inMemoryAuthentication () .withUser ("memuser") .password (encoder (). encode ("pass")) .roles ("USER"); } @Override protected void configure (HttpSecurity http) genereert uitzondering {http.httpBasic () .and () .authorizeRequests () .antMatchers ("/ api / **") .authenticated (); } @Bean public PasswordEncoder passwordEncoder () {retourneer nieuwe BCryptPasswordEncoder (); }}

5.2. XML-configuratie

Als alternatief, als we XML-configuratie willen gebruiken in plaats van Java-configuratie:

6. De applicatie

Laten we vervolgens een eenvoudig REST-eindpunt maken dat wordt beveiligd door onze twee authenticatieleveranciers.

Om toegang te krijgen tot dit eindpunt, moeten een geldige gebruikersnaam en wachtwoord worden opgegeven. Onze authenticatieleveranciers valideren de inloggegevens en bepalen of toegang wordt toegestaan ​​of niet:

@RestController openbare klasse MultipleAuthController {@GetMapping ("/ api / ping") openbare String getPing () {return "OK"; }}

7. Testen

Laten we tot slot nu de toegang tot onze beveiligde applicatie testen. Toegang is alleen toegestaan ​​als er geldige inloggegevens worden verstrekt:

@Autowired privé TestRestTemplate restTemplate; @Test openbare ongeldig gegevenMemUsers_whenGetPingWithValidUser_thenOk () {ResponseEntity resultaat = makeRestCallToGetPing ("memuser", "pass"); assertThat (result.getStatusCodeValue ()). isEqualTo (200); assertThat (result.getBody ()). isEqualTo ("OK"); } @Test openbare ongeldig gegevenExternalUsers_whenGetPingWithValidUser_thenOK () {ResponseEntity resultaat = makeRestCallToGetPing ("externaluser", "pass"); assertThat (result.getStatusCodeValue ()). isEqualTo (200); assertThat (result.getBody ()). isEqualTo ("OK"); } @Test openbare leegte gegevenAuthProviders_whenGetPingWithNoCred_then401 () {ResponseEntity resultaat = makeRestCallToGetPing (); assertThat (result.getStatusCodeValue ()). isEqualTo (401); } @Test openbare ongeldige gegevenAuthProviders_whenGetPingWithBadCred_then401 () {ResponseEntity resultaat = makeRestCallToGetPing ("gebruiker", "bad_password"); assertThat (result.getStatusCodeValue ()). isEqualTo (401); } private ResponseEntity makeRestCallToGetPing (String gebruikersnaam, String wachtwoord) {return restTemplate.withBasicAuth (gebruikersnaam, wachtwoord) .getForEntity ("/ api / ping", String.class, Collections.emptyMap ()); } private ResponseEntity makeRestCallToGetPing () {return restTemplate .getForEntity ("/ api / ping", String.class, Collections.emptyMap ()); }

8. Conclusie

In deze korte tutorial hebben we gezien hoe meerdere authenticatieleveranciers kunnen worden geconfigureerd in Spring Security. We hebben een eenvoudige applicatie beveiligd met behulp van een aangepaste authenticatieleverancier en een in-memory authenticatieprovider.

En we hebben ook tests geschreven om te verifiëren dat de toegang tot onze applicatie inloggegevens vereist die kunnen worden gevalideerd door ten minste een van onze authenticatieleveranciers.

Zoals altijd is de volledige broncode van de implementatie te vinden op GitHub.


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