I am new to Spring Boot and Angular and struggling with the CORS issue.
I want to implement a global CORS filter and tried implementing CorsFilter, WebMvcConfigurer and also tried with WebMvcConfigurerAdapter class but none of the methods seem to be working. I know I'm missing something but can't figure out what. If someone could please find a solution in my code, it would be great help.
I also have implemented Basic Auth and added that code if that's any help.
Here's my code.
Angular API Call
api.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class ApiService {
constructor(private httpClient: HttpClient) { }
userLogin(username: String, password: String) {
let postBody = {
"username" : username,
"password" : password
};
let httpOptions = {
headers : new HttpHeaders({
"Content-Type" : "application/json",
"Authorization" : "Basic " + btoa('myUsername:myPassword')
})
}
return this.httpClient.post("http://localhost:8080/userLogin", postBody, httpOptions);
}
}
Here's my API code.
MainApp.java
@SpringBootApplication
public class MainApp extends SpringBootServletInitializer {
public static void main(String... str) {
SpringApplication.run(MainApp.class, str);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(MainApp.class);
}
}
Config.java
@Configuration
public class Config {
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowCredentials(true);
configuration.setAllowedOrigins(Collections.singletonList("*"));
configuration.setAllowedHeaders(Arrays.asList("Origin", "Content-Type", "Accept"));
configuration.setAllowedMethods(Arrays.asList("POST"));
source.registerCorsConfiguration("/**", configuration);
return new CorsFilter(source);
}
}
NotebookController.java
@RestController
public class NotebookController {
@Autowired
IUsersRepo usersRepo;
@Autowired
INotesRepo notesRepo;
@PostMapping("userLogin")
@ResponseBody
public ResponseEntity<String> userLogin(@RequestParam("username") String username, @RequestParam("password") String password) {
ObjectWriter objectWriter = new ObjectMapper().writer().withDefaultPrettyPrinter();
List<Users> usersList = usersRepo.findByUsernameEqualsAndPasswordEquals(username, password);
boolean userVerified = usersList.size() > 0 ? true : false;
HashMap<String, Boolean> outputMap = new HashMap<>();
outputMap.put("authenticated", userVerified);
String outputJson = "";
try {
outputJson = objectWriter.writeValueAsString(outputMap);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
outputJson = outputJson.toString();
ResponseEntity<String> response = new ResponseEntity<String>(outputJson, HttpStatus.OK);
return response;
}
}
Authentication.java
@Configuration
@EnableWebSecurity
public class Authentication extends WebSecurityConfigurerAdapter {
@Autowired
AuthenticationEntryPoint authEntryPoint;
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.cors().and().csrf().disable();
//Authorise all incoming requests
http.authorizeRequests().and().httpBasic();
http.authorizeRequests().anyRequest().authenticated();
//Use AuthenticationEntryPoint to authorise username/password
http.httpBasic().authenticationEntryPoint(authEntryPoint);
}
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowCredentials(true);
configuration.setAllowedOrigins(Collections.singletonList("*"));
configuration.setAllowedHeaders(Arrays.asList("Origin", "Content-Type", "Accept"));
configuration.setAllowedMethods(Arrays.asList("POST"));
source.registerCorsConfiguration("/**", configuration);
return new CorsFilter(source);
}
@Bean
public BCryptPasswordEncoder getEncoder() {
return new BCryptPasswordEncoder();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
String username = "myUsername";
String password = "myPassword";
InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> mngConfig = authenticationManagerBuilder.inMemoryAuthentication();
mngConfig.withUser(username).password(password).roles("USER");
}
}
AuthEntryPoint.java
@Component
public class AuthEntryPoint extends BasicAuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
super.commence(request, response, authException);
response.addHeader("WWW-Authenticate", "Basic realm=" + getRealmName());
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
PrintWriter writer = response.getWriter();
writer.println("HTTP Status 401: Unauthorised | " + authException.getMessage());
}
@Override
public void afterPropertiesSet() throws Exception {
setRealmName("Online Notebook");
super.afterPropertiesSet();
}
}
Please see the browser console as well.