Å fikse 401s med CORS Preflights og Spring Security

1. Oversikt

I denne korte opplæringen skal vi lære hvordan vi kan løse feilen "Svar for preflight har ugyldig HTTP-statuskode 401", som kan forekomme i applikasjoner som støtter kommunikasjon med opprinnelse og bruker Spring Security.

Først ser vi hva forespørsler om opprinnelse er, og så fikser vi et problematisk eksempel.

2. Kryssopprinnelsesforespørsler

Cross-origin forespørsler, kort sagt, er HTTP-forespørsler der opprinnelsen og målet for forespørselen er forskjellig. Dette er for eksempel tilfelle når en webapplikasjon serveres fra ett domene og nettleseren sender en AJAX-forespørsel til en server i et annet domene.

For å administrere kryssopprinnelsesforespørsler, må serveren aktivere en bestemt mekanisme kjent som CORS eller Cross-Origin Resource Sharing.

Det første trinnet i CORS er et ALTERNATIVER forespørsel om å avgjøre om målet for forespørselen støtter det. Dette kalles en forespørsel før flyet.

Serveren kan deretter svare på forespørselen før flyet med en samling overskrifter:

  • Tilgangskontroll-Tillat opprinnelse: Definerer hvilke opprinnelser som kan ha tilgang til ressursen. En ‘*’ representerer hvilken som helst opprinnelse
  • Tilgangskontroll-Tillat-metoder: Indikerer de tillatte HTTP-metodene for forespørsler om opprinnelse
  • Access-Control-Allow-Headers: Indikerer tillatte overskrifter for forespørsel
  • Access-Control-Max-Age: Definerer utløpstiden for resultatet av den hurtigbufrede preflight-forespørselen

Så hvis forespørselen før flyet ikke oppfyller vilkårene som er bestemt fra disse svaroverskriftene, vil den faktiske oppfølgingsforespørselen kaste feil relatert til forespørselen om opprinnelse.

Det er enkelt å legge til CORS-støtte i vår vårdrevne tjeneste, men hvis den er konfigurert feil, vil denne forespørselen før flyet alltid mislykkes med en 401.

3. Opprette et CORS-aktivert REST API

For å simulere problemet, la oss først lage en enkel REST API som støtter forespørsler om opprinnelse:

@RestController @CrossOrigin ("// localhost: 4200") public class ResourceController {@GetMapping ("/ user") public String user (Principal principal) {return principal.getName (); }}

De @CrossOrigin merknader sørger for at API-ene våre bare er tilgjengelige fra opprinnelsen som er nevnt i argumentet.

4. Sikre REST API

La oss nå sikre vår REST API med Spring Security:

@EnableWebSecurity offentlig klasse WebSecurityConfig utvider WebSecurityConfigurerAdapter {@Override-beskyttet ugyldig konfigurering (HttpSecurity http) kaster Unntak {http .authorizeRequests () .anyRequest (). Autentisert (). Og () .httpBasic (); }}

I denne konfigurasjonsklassen har vi håndhevet autorisasjon til alle innkommende forespørsler. Som et resultat vil den avvise alle forespørsler uten gyldig autorisasjonstoken.

5. Lage en forespørsel før flyreisen

Nå som vi har opprettet REST API, la oss prøve en forespørsel før flyet med krølle:

curl -v -H "Access-Control-Request-Method: GET" -H "Opprinnelse: // localhost: 4200" -X ALTERNATIVER // localhost: 8080 / bruker ... <HTTP / 1.1 401 ... <WWW -Authenticate: Basic realm = "Realm" ... <Vary: Origin <Vary: Access-Control-Request-Method <Vary: Access-Control-Request-Headers <Access-Control-Allow-Origin: // localhost: 4200 <Access-Control-Allow-Methods: POST <Access-Control-Allow-Credentials: true <Tillat: GET, HEAD, POST, PUT, DELETE, TRACE, ALTERNATIV, PATCH ...

Fra utgangen av denne kommandoen kan vi se det forespørselen ble avslått med en 401.

Siden dette er en krølle kommando, vil vi ikke se feilen “Svar for preflight har ugyldig HTTP-statuskode 401” i utdataene.

Men vi kan reprodusere denne nøyaktige feilen ved å lage et frontend-program som bruker REST API fra et annet domene og kjører det i en nettleser.

6. Løsningen

Vi har ikke eksplisitt ekskludert preflight-forespørslene fra autorisasjon i vår Security-konfigurasjon. Husk at vårsikkerhet er sikret alle endepunkter som standard.

Som et resultat, API-et vårt forventer også et autorisasjonstoken i OPTIONS-forespørselen.

Spring tilbyr en ut av boksen løsning for å ekskludere OPTIONS-forespørsler fra autorisasjonskontroller:

@EnableWebSecurity offentlig klasse WebSecurityConfig utvider WebSecurityConfigurerAdapter {@ Override-beskyttet ugyldig konfigurering (HttpSecurity http) kaster unntak {// ... http.cors (); }}

De cors () metoden vil legge til våren CorsFilter til applikasjonskonteksten som i sin tur omgår autorisasjonskontrollene for OPTIONS-forespørsler.

Nå kan vi teste søknaden vår på nytt og se at den fungerer.

7. Konklusjon

I denne korte artikkelen har vi lært hvordan vi løser feilen "Svar for preflight har ugyldig HTTP-statuskode 401" som er knyttet til Spring Security og kryssopprinnelsesforespørsler.

Merk at klienten og API-et, med eksemplet, skal kjøre på forskjellige domener eller porter for å gjenskape problemet. For eksempel kan vi kartlegge standard vertsnavn til klienten og maskinens IP-adresse til REST API når vi kjører på en lokal maskin.

Som alltid kan eksemplet som vises i denne opplæringen finnes på Github.


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