I have a Spring Boot backend with security enabled, and I'm trying to POST request on the http://localhost:4200/snippetcollection endpoint.
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
// CORS configuration
// CSRF configuration
// route security w/ role configurations
http.cors().configurationSource(new CorsConfigurationSource() {
@Override
public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(Collections.singletonList("http://localhost:4200"));
config.setAllowedMethods(Collections.singletonList("*"));
config.setAllowCredentials(true);
config.setAllowedHeaders(Collections.singletonList("*"));
config.setMaxAge(3600L);
return config;
}
}).and().csrf().ignoringAntMatchers("/register", "/snippetcollection")
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and().authorizeRequests()
.antMatchers("/snippetcollection").hasAnyRole(Role.FREE_USER.name(), Role.PRO_USER.name())
.antMatchers("/dashboard").hasAnyRole(Role.FREE_USER.name(), Role.PRO_USER.name())
.antMatchers("/profile").hasAnyRole(Role.FREE_USER.name(), Role.PRO_USER.name())
.antMatchers("/tags").hasAnyRole(Role.FREE_USER.name(), Role.PRO_USER.name())
.antMatchers("/shared").hasRole(Role.PRO_USER.name())
.antMatchers("/settings").hasAnyRole(Role.FREE_USER.name(), Role.PRO_USER.name())
.antMatchers("/user").authenticated()
.antMatchers("/home", "/documentation", "/pricing", "/register", "/share", "/login").permitAll()
.and().httpBasic()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
return http.build();
}
// bcrypt encoder
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
In Postman, I have set the Authorization to Basic Auth with my credentials and I'm getting 201 CREATED SUCCESS response from the http://localhost:4200/snippetcollection endpoint. But In Angular code I'm getting a 401 status code & error. POSTMAN SCREENSHOT AND POSTMAN HEADERS SCREENSHOT
Angular code
HTTP interceptor
@Injectable()
export class AjaxhttpInterceptor implements HttpInterceptor {
// initialize a user model obj
user = new User();
// inject the router obj
constructor(private router: Router) {}
// override the intercept method
intercept(req: HttpRequest<any>, next: HttpHandler) {
// this http header is used to add authorization details
let httpHeaders = new HttpHeaders();
// map userdetails to user model if it already exists in the session storage
if (sessionStorage.getItem('userdetails')) {
this.user = JSON.parse(sessionStorage.getItem('userdetails')!);
}
// append when user is trying to login
if (this.user && this.user.password && this.user.email) {
httpHeaders = httpHeaders.append(
'Authorization',
'Basic ' + window.btoa(this.user.email + ':' + this.user.password)
);
}
let xsrf = sessionStorage.getItem('XSRF-TOKEN');
if (xsrf) {
httpHeaders = httpHeaders.append('X-XSRF-TOKEN', xsrf);
}
httpHeaders = httpHeaders.append('X-Requested-With', 'XMLHttpRequest');
const xhr = req.clone({
headers: httpHeaders,
});
return next.handle(xhr).pipe(
tap((err: any) => {
if (err instanceof HttpErrorResponse) {
if (err.status !== 401) {
return;
}
// if success, navigate to user dashboard
this.router.navigate(['/dashboard']);
}
})
);
}
}
Service
export class DashboardService {
constructor(private http: HttpClient) {}
createSnippetCollection(snippetcollection: SnippetCollection) {
return this.http.post(
environment.rooturl + '/snippetcollection',
snippetcollection,
{ observe: 'response', withCredentials: true }
);
}
}
Some component using the Service
this.dashboardService
.createSnippetCollection({
title: 'noasdsadasde export link',
description: 'Cerasdasdvus Lorem ipsom dolor sadasdamet',
programmingLanguage: 'nasdasdde',
})
.subscribe((responseData) => {
console.log(responseData);
});