401's repareren met CORS-preflights en Spring Security

1. Overzicht

In deze korte tutorial gaan we leren hoe we de fout "Reactie voor preflight heeft ongeldige HTTP-statuscode 401" kunnen oplossen, die kan optreden in applicaties die cross-origin communicatie ondersteunen en Spring Security gebruiken.

Eerst zullen we zien wat cross-origin-verzoeken zijn, en dan zullen we een problematisch voorbeeld oplossen.

2. Cross-Origin-verzoeken

Cross-origin-verzoeken zijn, kort gezegd, HTTP-verzoeken waarbij de oorsprong en het doel van het verzoek verschillen. Dit is bijvoorbeeld het geval wanneer een webapplicatie vanuit het ene domein wordt bediend en de browser een AJAX-verzoek verstuurt naar een server in een ander domein.

Om cross-origin-verzoeken te beheren, moet de server een bepaald mechanisme inschakelen dat bekend staat als CORS of Cross-Origin Resource Sharing.

De eerste stap in CORS is een OPTIES verzoek om te bepalen of het doel van het verzoek het ondersteunt. Dit wordt een pre-flight request genoemd.

De server kan vervolgens reageren op het pre-flight-verzoek met een verzameling headers:

  • Access-Control-Allow-Origin: Bepaalt welke bronnen toegang hebben tot de bron. Een ‘* 'staat voor elke oorsprong
  • Access-Control-Allow-Methods: Geeft de toegestane HTTP-methoden voor cross-origin-verzoeken aan
  • Access-Control-Allow-Headers: Geeft de toegestane aanvraagheaders aan voor verzoeken van verschillende oorsprong
  • Toegangscontrole-Max-Leeftijd: Definieert de vervaltijd van het resultaat van het in de cache opgeslagen preflight-verzoek

Dus als het pre-flight-verzoek niet voldoet aan de voorwaarden die zijn bepaald op basis van deze responsheaders, genereert het daadwerkelijke follow-up-verzoek fouten met betrekking tot het cross-origin-verzoek.

Het is gemakkelijk om CORS-ondersteuning toe te voegen aan onze Spring-powered service, maar als deze onjuist is geconfigureerd, zal deze pre-flight-aanvraag altijd mislukken met een 401.

3. Een voor CORS ingeschakelde REST API maken

Om het probleem te simuleren, maken we eerst een eenvoudige REST API die cross-origin-verzoeken ondersteunt:

@RestController @CrossOrigin ("// localhost: 4200") openbare klasse ResourceController {@GetMapping ("/ gebruiker") openbare tekenreeksgebruiker (Principal principal) {return principal.getName (); }}

De @CrossOrigin annotatie zorgt ervoor dat onze API's alleen toegankelijk zijn vanaf de oorsprong die in het argument wordt vermeld.

4. Beveiliging van onze REST API

Laten we nu onze REST API beveiligen met Spring Security:

@EnableWebSecurity openbare klasse WebSecurityConfig breidt WebSecurityConfigurerAdapter uit {@Override beschermde ongeldige configuratie (HttpSecurity http) gooit Uitzondering {http .authorizeRequests () .anyRequest (). Geverifieerd (). En () .httpBasic (); }}

In deze configuratieklasse hebben we autorisatie afgedwongen voor alle inkomende verzoeken. Als gevolg hiervan zal het alle verzoeken weigeren zonder een geldig autorisatietoken.

5. Een verzoek indienen vóór de vlucht

Nu we onze REST API hebben gemaakt, kunnen we een pre-flight-aanvraag proberen met krullen:

curl -v -H "Access-Control-Request-Method: GET" -H "Origin: // localhost: 4200" -X OPTIONS // localhost: 8080 / user ... <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 <Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH ...

Aan de uitvoer van deze opdracht kunnen we dat zien het verzoek werd afgewezen met een 401.

Omdat dit een krullen commando, zien we de fout "Reactie voor preflight heeft ongeldige HTTP-statuscode 401" niet in de uitvoer.

Maar we kunnen deze exacte fout reproduceren door een front-end-applicatie te maken die onze REST API van een ander domein gebruikt en deze in een browser uit te voeren.

6. De oplossing

We hebben de preflight-verzoeken niet expliciet uitgesloten van autorisatie in onze Spring Security-configuratie. Onthoud dat Spring Security beveiligt alle eindpunten standaard.

Als resultaat, onze API verwacht ook een autorisatietoken in het OPTIONS-verzoek.

Spring biedt een kant-en-klare oplossing om OPTIONS-verzoeken uit te sluiten van autorisatiecontroles:

@EnableWebSecurity openbare klasse WebSecurityConfig breidt WebSecurityConfigurerAdapter uit {@Override protected void configure (HttpSecurity http) gooit uitzondering {// ... http.cors (); }}

De cors () methode voegt het door Spring geleverde CorsFilter naar de applicatiecontext die op zijn beurt de autorisatiecontroles voor OPTIONS-verzoeken omzeilt.

Nu kunnen we onze applicatie opnieuw testen en zien dat deze werkt.

7. Conclusie

In dit korte artikel hebben we geleerd hoe we de fout "Reactie voor preflight heeft ongeldige HTTP-statuscode 401", die is gekoppeld aan Spring Security en cross-origin-verzoeken, kunnen oplossen.

Merk op dat, in het voorbeeld, de client en de API op verschillende domeinen of poorten moeten draaien om het probleem opnieuw te creëren. We kunnen bijvoorbeeld de standaard hostnaam toewijzen aan de client en het IP-adres van de machine aan onze REST API wanneer deze op een lokale computer wordt uitgevoerd.

Zoals altijd is het voorbeeld dat in deze tutorial wordt getoond, te vinden op Github.


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