i have configured spring security but still unable to send post request via angular:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.authenticationProvider(credentialsAuthenticationProvider)
.httpBasic()
.and()
.logout()
.and()
.cors().configurationSource(corsConfigurationSource)
.and()
.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
/* To allow Pre-flight [OPTIONS] request from browser */
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
}
my cors configuration source is as follow:
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
List<String> allowedOrigins = new LinkedList<>();
allowedOrigins.add("*");
List<String> allowedHeaders = new LinkedList<>();
allowedHeaders.add("*");
List<String> allowedMethods = new LinkedList<>();
allowedMethods.add("HEAD");
allowedMethods.add("GET");
allowedMethods.add("POST");
allowedMethods.add("PUT");
allowedMethods.add("DELETE");
allowedMethods.add("PATCH");
allowedMethods.add("OPTIONS");
configuration.setAllowedOrigins(allowedOrigins);
configuration.setAllowedMethods(allowedMethods);
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(allowedHeaders);
allowedHeaders.add("Authorization");
allowedHeaders.add("Content-Type");
allowedHeaders.add("x-xsrf-token");
allowedHeaders.add("xsrf-token");
allowedHeaders.add("Accept-language");
allowedHeaders.add("X-Requested-With");
configuration.setAllowedHeaders(allowedHeaders);
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
and i am using a root context : api/v1 in the case this might help.
on Angular side i have configured app.module.ts
imports: [
...
HttpClientModule,
HttpClientXsrfModule,
],
the problem occurs when i try a post request: here is a screenshot of the request and response:
GET Request returns 200 OK:
Post request returns 403 forbidden:
The bizzare thing is that there are 2 XSRF token which i guess is the source of the problem.
To solve the csrf problem between spring security and angular, you have to do that.
replace .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
with
csrf()
.ignoringAntMatchers ("/login","/logout")
.csrfTokenRepository (this.getCsrfTokenRepository());
}
private CsrfTokenRepository getCsrfTokenRepository() {
CookieCsrfTokenRepository tokenRepository =
CookieCsrfTokenRepository.withHttpOnlyFalse();
tokenRepository.setCookiePath("/");
return tokenRepository;
}
The default angular csrf interceptor does not always work. So you have to implement your own interceptor.
import {Injectable, Inject} from '@angular/core';
import {HttpInterceptor, HttpXsrfTokenExtractor, HttpRequest, HttpHandler,
HttpEvent} from '@angular/common/http';
import {Observable} from "rxjs";
@Injectable()
export class HttpXsrfInterceptor implements HttpInterceptor {
constructor(private tokenExtractor: HttpXsrfTokenExtractor) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let requestMethod: string = req.method;
requestMethod = requestMethod.toLowerCase();
if (requestMethod && (requestMethod === 'post' || requestMethod === 'delete' || requestMethod === 'put')) {
const headerName = 'X-XSRF-TOKEN';
let token = this.tokenExtractor.getToken() as string;
if (token !== null && !req.headers.has(headerName)) {
req = req.clone({headers: req.headers.set(headerName, token)});
}
}
return next.handle(req);
}
}
And finally add it in your providers (app.module.ts)
providers: [{ provide: HTTP_INTERCEPTORS, useClass: HttpXsrfInterceptor, multi: true }]
Think about putting in your imports.
HttpClientXsrfModule.withOptions({
cookieName: 'XSRF-TOKEN',
headerName: 'X-CSRF-TOKEN'
}),
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.