Veiledning til AuthenticationManagerResolver in Spring Security

1. Introduksjon

I denne opplæringen introduserer vi AuthenticationManagerResolver og vis deretter hvordan du bruker den til grunnleggende og OAuth2-autentiseringsflyter.

2. Hva er AuthenticationManager?

Enkelt sagt, den AuthenticationManager er hovedstrategigrensesnittet for autentisering.

Hvis rektor for inngangsautentisering er gyldig og bekreftet, AuthenticationManager # authenticate returnerer en Godkjenning eksempel med autentisert flagg satt til ekte. Hvis ikke rektor ikke er gyldig, vil den kaste et AuthenticationException. For den siste saken kommer den tilbake null hvis den ikke kan bestemme.

ProviderManager er standardimplementeringen av AuthenticationManager. Den delegerer godkjenningsprosessen til en liste over AuthenticationProvider tilfeller.

Vi kan sette opp globalt eller lokalt AuthenticationManager hvis vi utvider WebSecurityConfigurerAdapter. For en lokal AuthenticationManager, kunne vi overstyre konfigurer (AuthenticationManagerBuilder).

AuthenticationManagerBuilder er en hjelperklasse som letter oppsettet av UserDetailService, AuthenticationProvider, og andre avhengigheter for å bygge en AuthenticationManager.

For en global AuthenticationManager, bør vi definere en AuthenticationManager som en bønne.

3. Hvorfor AuthenticationManagerResolver?

AuthenticationManagerResolver lar våren velge en AuthenticationManager per kontekst. Det er en ny funksjon lagt til Spring Security i versjon 5.2.0:

offentlig grensesnitt AuthenticationManagerResolver {AuthenticationManager løse (C-kontekst); }

AuthenticationManagerResolver # løse kan returnere en forekomst av AuthenticationManager basert på en generisk kontekst. Med andre ord kan vi sette en klasse som kontekst hvis vi vil løse AuthenticationManager ifølge det.

Spring Security har integrert AuthenticationManagerResolver i autentiseringsflyten med HttpServletRequest og ServerWebExchange som kontekst.

4. Bruksscenario

La oss se hvordan du bruker AuthenticationManagerResolver i praksis.

Anta for eksempel et system som har to brukergrupper: ansatte og kunder. Disse to gruppene har spesifikk autentiseringslogikk og har separate datalagre. Dessuten har brukere i en av disse gruppene bare lov til å ringe sine relaterte URL-er.

5. Hvordan gjør det AuthenticationManagerResolver Arbeid?

Vi kan bruke AuthenticationManagerResolver uansett hvor vi trenger å velge en AuthenticationManager dynamisk, men i denne opplæringen er vi interessert i å bruke den i innebygde autentiseringsflyter.

La oss først sette opp en AuthenticationManagerResolver, bruk den deretter til grunnleggende og OAuth2-autentisering.

5.1. Setter opp AuthenticationManagerResolver

La oss starte med å lage en klasse for sikkerhetskonfigurasjon. Vi burde utvide WebSecurityConfigurerAdapter:

@Configuration offentlig klasse CustomWebSecurityConfigurer utvider WebSecurityConfigurerAdapter {// ...}

La oss deretter legge til en metode som returnerer AuthenticationManager for kunder:

AuthenticationManager-kunderAuthenticationManager () {return authentication -> {if (isCustomer (authentication)) {return new UsernamePasswordAuthenticationToken (/ * credentials * /); } kast nytt brukernavnNotFoundException (/ * hovednavn * /); }; }

De AuthenticationManager for ansatte er logisk sett det samme, bare vi erstatter erKunde med er medarbeider:

offentlige AuthenticationManager-medarbeidereAuthenticationManager () {return authentication -> {if (isEmployee (authentication)) {return new UsernamePasswordAuthenticationToken (/ * credentials * /); } kast nytt brukernavnNotFoundException (/ * hovednavn * /); }; }

Til slutt, la oss legge til en AuthenticationManagerResolver som løser seg i henhold til URLen til forespørselen:

AuthenticationManagerResolver resolver () {return request -> {if (request.getPathInfo (). StartsWith ("/ employee")) {return workersAuthenticationManager (); } returnere kunderAuthenticationManager (); }; }

5.2. For grunnleggende godkjenning

Vi kan bruke AuthenticationFilter for å dynamisk løse AuthenticationManager per forespørsel. AuthenticationFilter ble lagt til Spring Security i versjon 5.2.

Hvis vi legger det til i sikkerhetsfilterkjeden vår, sjekker den først om den kan trekke ut noe godkjenningsobjekt eller ikke. Hvis ja, så spør den AuthenticationManagerResolver for en passende AuthenticationManager og fortsetter flyten.

La oss først legge til en metode i vår CustomWebSecurityConfigurer å lage en AuthenticationFilter:

private AuthenticationFilter authenticationFilter () {AuthenticationFilter filter = new AuthenticationFilter (resolver (), authenticationConverter ()); filter.setSuccessHandler ((forespørsel, svar, godkjenning) -> {}); returfilter; }

Årsaken til å sette AuthenticationFilter # suksessHandler med no-op SuccessHandler er å forhindre standard oppførsel av omdirigering etter vellykket autentisering.

Deretter kan vi legge til dette filteret i sikkerhetsfilterkjeden vår ved å overstyre WebSecurityConfigurerAdapter # configure (HttpSecurity) i vår CustomWebSecurityConfigurer:

@ Override-beskyttet tomkonfigurasjon (HttpSecurity http) kaster unntak {http.addFilterBefore (authenticationFilter (), BasicAuthenticationFilter.class); }

5.3. For OAuth2-godkjenning

BearerTokenAuthenticationFilter er ansvarlig for OAuth2-autentisering. De BearerTokenAuthenticationFilter # doFilterInternal metoden sjekker for en BearerTokenAuthenticationToken i forespørselen, og hvis den er tilgjengelig, løser den det aktuelle AuthenticationManager for å autentisere tokenet.

OAuth2ResourceServerConfigurer brukes til å sette opp BearerTokenAuthenticationFilter.

Så vi kan sette opp AuthenticationManagerResolver for vår ressursserver i vår CustomWebSecurityConfigurer ved å overstyre WebSecurityConfigurerAdapter # configure (HttpSecurity):

@ Override beskyttet ugyldig konfigurering (HttpSecurity http) kaster unntak {http .oauth2ResourceServer () .authenticationManagerResolver (resolver ()); }

6. Løs AuthenticationManager i reaktive applikasjoner

For en reaktiv webapplikasjon kan vi fortsatt ha nytte av konseptet med å løse AuthenticationManager i henhold til konteksten. Men her har vi det ReaktivAuthenticationManagerResolver i stedet:

@FunctionalInterface offentlig grensesnitt ReactiveAuthenticationManagerResolver {Mono resolve (C context); }

Det returnerer a Mono av ReactiveAuthenticationManager. ReactiveAuthenticationManager er det reaktive ekvivalent med AuthenticationManager, derav dens autentisere metoden returnerer Mono.

6.1. Setter opp ReaktivAuthenticationManagerResolver

La oss starte med å lage en klasse for sikkerhetskonfigurasjon:

@EnableWebFluxSecurity @EnableReactiveMethodSecurity offentlig klasse CustomWebSecurityConfig {// ...}

Deretter la oss definere ReactiveAuthenticationManager for kunder i denne klassen:

ReactiveAuthenticationManager customersAuthenticationManager () {return authentication -> customer (authentication) .switchIfEmpty (Mono.error (new UsernameNotFoundException (/ * principal name * /))) .map (b -> new UsernamePasswordAuthenticationToken (/ * credentials * /); } 

Og etter det vil vi definere ReactiveAuthenticationManager for ansatte:

offentlig ReactiveAuthenticationManager-medarbeidereAuthenticationManager () {returautentisering -> ansatt (autentisering) .switchIfEmpty (Mono.error (nytt brukernavnNotFoundException (/ * hovednavn * /))). kart (b -> nytt brukernavnPassordAuthenticationToken (/ * legitimasjon * /); }

Til slutt satte vi opp en ReaktivAuthenticationManagerResolver basert på vårt scenario:

ReactiveAuthenticationManagerResolver resolver () {return exchange -> {if (match (exchange.getRequest (), "/ employee")) {return Mono.just (workersAuthenticationManager ()); } returner Mono.just (customersAuthenticationManager ()); }; }

6.2. For grunnleggende godkjenning

I en reaktiv webapplikasjon kan vi bruke AuthenticationWebFilter for autentisering. Den autentiserer forespørselen og fyller sikkerhetskonteksten.

AuthenticationWebFilter sjekker først om forespørselen stemmer overens. Etter det, hvis det er et autentiseringsobjekt i forespørselen, blir det passende ReactiveAuthenticationManager for forespørselen fra ReaktivAuthenticationManagerResolver og fortsetter autentiseringsflyten.

Derfor kan vi sette opp våre tilpassede AuthenticationWebFilter i vår sikkerhetskonfigurasjon:

@Bean public SecurityWebFilterChain securityWebFilterChain (ServerHttpSecurity http) {return http .authorizeExchange () .pathMatchers ("/ **") .authenticated () .and () .httpBasic () .disable () .addFilterAfter (new AuthenticationWebFilter ), SecurityWebFiltersOrder.REACTOR_CONTEXT) .build (); }

Først deaktiverer vi ServerHttpSecurity # httpBasic for å forhindre normal autentiseringsflyt, erstatt den deretter manuelt med en AuthenticationWebFilter, sender inn vår tilpassede resolver.

6.3. For OAuth2-godkjenning

Vi kan konfigurere ReaktivAuthenticationManagerResolver med ServerHttpSecurity # oauth2ResourceServer. ServerHttpSecurity # build legger til en forekomst av AuthenticationWebFilter med vår resolver til kjeden av sikkerhetsfiltre.

Så la oss sette vårt AuthenticationManagerResolver for OAuth2-godkjenningsfilter i vår sikkerhetskonfigurasjon:

@Bean public SecurityWebFilterChain securityWebFilterChain (ServerHttpSecurity http) {return http // ... .and () .oauth2ResourceServer () .authenticationManagerResolver (resolver ()) .and () // ...; }

7. Konklusjon

I denne artikkelen har vi brukt AuthenticationManagerResolver for grunnleggende og OAuth2-autentisering i et enkelt scenario.

Og vi har også utforsket bruken av ReaktivAuthenticationManagerResolver i reaktive vårapplikasjoner for både Basic- og OAuth2-autentisering.

Som alltid er kildekoden tilgjengelig på GitHub. Vårt reaktive eksempel er også tilgjengelig på GitHub.


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