How do I configure CORS globally in Spring Boot? - spring

I am trying to configure CORS globally in Spring using the following code:
#Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
#Override
protected void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedOrigins("*")
.allowedHeaders("*")
.allowCredentials(false);
}
}
However, I am being blocked when I make a call from http://localhost:3000
Message:
'Access to fetch at 'http://localhost:8081/api/assignments' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.'
Any suggestion would be great. Thanks.

This is what resolved my CORS issue:
#Configuration
public class WebMvcConfig
{
#Bean
public WebMvcConfigurer corsConfigurer()
{
return new WebMvcConfigurer() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("http://localhost:3000");
}
};
}
}
And an important step if you are using Spring security is the following:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors()
.and()......

Related

Why I get cors error when submitting a request to secured resource in spring boot?

I have implemented spring security in my app using jwt token, I have the following configuration in spring security:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(
prePostEnabled = true)
public class MSSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
UserDetailsService userDetailsService;
#Autowired
private AuthEntryPointJwt unauthorizedHandler;
#Bean
public AuthTokenFilter authenticationJwtTokenFilter() {
return new AuthTokenFilter();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/companies/UnAuth/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.antMatchers("/companies/Auth/**").authenticated()
.antMatchers("/companies/Auth/Update").authenticated()
.antMatchers("/companies/Auth/Delete").authenticated();
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}
I have the following cors annotation on the relevant controller:
#CrossOrigin(origins = "http://localhost:4200", maxAge = 3600)
#RestController
#RequestMapping("/companies")
#Slf4j
public class CompanyController {
I tried to add the following to the http interceptor in angular:
authReq.headers.set("Access-Control-Allow-Origin", "http://localhost:4200");
authReq.headers.set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
When submitting the request from Angular 9 app I can't pass the security and I get cors error:
`Access to XMLHttpRequest at 'http://localhost:9001/companies/Auth/Update' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resourc`e.
The request doesn't contain the 'Access-Control-Allow-Origin' header, you should add it in the headers, it allows remote computers to access the content you send via REST.
If you want to allow all remote hosts to access your api content you should add it like so:
Access-Control-Allow-Origin: *
Your can also specify a specific host:
Access-Control-Allow-Origin: http://example.com
You should modify your dependencies in the pom.xml file and allow CORS headers, appart from the Access-Control-Allow-Origin headers there are a few more that you will need to add to the request, seek more info here:
https://spring.io/blog/2015/06/08/cors-support-in-spring-framework

trouble connecting Angular 10 with Spring security to use custom login page

I have been working on a web application using Spring boot and spring security with frontend controlled by angular 10. I have implemented backend for security and created a login page also. But, on running on local host it is throwing an error
blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I have been banging my head all day long to resolve this error but could not find the solution.
I have attached my code below for reference
Controller
#RestController
#RequestMapping("/user")
public class UserController {
#Autowired
AuthenticationManager authenticationManager;
#PostMapping("/login")
public boolean login(#RequestBody loginDetails data) {
try {
String username = data.getUsername();
System.out.println("Checking...");
System.out.println(data.getUsername());
System.out.println(data.getPassword());
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, data.getPassword()));
// String token = jwtTokenProvider.createToken(username,
// this.users.findByEmail(username).getRoles());
System.out.println("abcdefg");
Map<Object, Object> model = new HashMap<>();
model.put("username", username);
// model.put("token", token);
/* return true; */
} catch (AuthenticationException e) {
/*
* throw new BadCredentialsException("Invalid email/password supplied");
*/
return false;
}
return true;
}
WebSecurityConfiguration
#EnableWebSecurity
#Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Qualifier("userDetailsService")
#Autowired
private UserDetailsService userDetailsService;
#Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/user/save","/user/login",
"/admin/**").permitAll().anyRequest().authenticated().and().csrf()
.disable().formLogin().permitAll().and().logout().permitAll();
http.cors();
}
#Bean
public AuthenticationManager customAuthenticationManager() throws Exception {
return authenticationManager();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
}
AngularRequestcode
public doLogin(){
this.userLogin.username=this.loginForm.get("username").value;
this.userLogin.password=this.loginForm.get("password").value;
console.log(this.userLogin);
return this.http.post<any>("http://localhost:8080/user/login",this.userLogin).subscribe((response) => {
if (response.status === 200) {
console.log('login successfully');
} else {
console.log('galat');
}
}
);
}
First of all, try change to:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().cors().and()
.authorizeRequests().antMatchers("/user/save", "/user/login",
"/admin/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().permitAll()
.and().logout().permitAll();
}
CORS it's browser check if you have response with: Access-Control-Allow-Origin: http://localhost:4200 or no: No 'Access-Control-Allow-Origin' header is present on the requested resource.;
Change http://localhost:4200 to your front-end url;
And add to your WebSecurityConfig:
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:4200")
.allowedMethods("*");
}
and: implements WebMvcConfigurer
Response without error:
Response with error. No Access-Control-Allow-Origin:

Access to XMLHttpRequest at '' () from origin '' has been blocked by CORS policy:No 'Access-Control-Allow-Origin' header is present

I am getting the below issue while logging out from openid connect.
"Access to XMLHttpRequest at '' (redirected from '') from origin
'http://localhost:8080' has been blocked by CORS policy: No
'Access-Control-Allow-Origin' header is present on the requested
resource."
and the Network call is showing "cancelled" status.
Here is code
SecurityConfig.java
#Override
protected void configure(HttpSecurity http) throws Exception {
LOG.info("in configure httpsecurity");
http.csrf().disable().cors().and()
.addFilterAfter(new OAuth2ClientContextFilter(), AbstractPreAuthenticatedProcessingFilter.class)
.addFilterAfter(myFilter(), OAuth2ClientContextFilter.class)
.httpBasic().authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint(openIdConfig.getEntrypoint()))
.and()
.authorizeRequests()
.antMatchers(openIdConfig.getEntrypoint()).permitAll()
.anyRequest().authenticated()
.and().logout()//.clearAuthentication(true)
.logoutUrl(openIdConfig.getLogoffURL()+openIdConfig.getRedirectUri()).permitAll()
.invalidateHttpSession(true)
.deleteCookies(OpenIDConstants.SESSION_TOKEN, OpenIDConstants.USERNAME,
OpenIDConstants.JSESSIONID)
.logoutSuccessHandler(logoutSuccessHandler())
.logoutSuccessUrl(openIdConfig.getRedirectUri());
;
LOG.info("in configure httpsecurity end");
// #formatter:on
}
You probably did enable CORS on security level, but not on the web level.
To enable CORS on web level, you can do it at method level, class level or for the entire application.
Method level
#CrossOrigin(origins = "http://example.com")
#GetMapping(path="/")
public String homeInit(Model model) {
return "home";
}
Class level
#CrossOrigin(origins = "*", allowedHeaders = "*")
#Controller
public class HomeController
{
#GetMapping(path="/")
public String homeInit(Model model) {
return "home";
}
}
Global
#Configuration
#EnableWebMvc
public class CorsConfiguration extends WebMvcConfigurerAdapter
{
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("GET", "POST");
}
}
or, for a Spring Boot application, the recommended way:
#Configuration
public class CorsConfiguration
{
#Bean
public WebMvcConfigurer corsConfigurer()
{
return new WebMvcConfigurerAdapter() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
};
}
}

"addCorsMapping" blocking Swagger UI

I'm working on a Spring application and I have some troubles with Swagger and Spring Security.
I had to add a specific configuration to allow almost every access (CORS) and it worked well so far, but somehow it is blocking Swagger....
This is my SwaggerConfiguration.java
#Configuration
#EnableSwagger2
#SwaggerDefinition(
info = #Info(
description = "Web Service",
version = "V0.0.1",
title = "Web Service",
contact = #Contact(
name = "Me",
email = "dev#me.com",
url = "https://www.me.com/"
)
),
consumes = {"application/json"},
produces = {"application/json"},
schemes = {SwaggerDefinition.Scheme.HTTP, SwaggerDefinition.Scheme.HTTPS}
)
public class SwaggerConfiguration {
/** List of Swagger endpoints (used by {#code WebSecurityConfig}) */
static final String[] SWAGGER_ENDPOINTS = {
"/v2/api-docs",
"/swagger-resources",
"/swagger-resources/**",
"/configuration/ui",
"/configuration/security",
"/swagger-ui.html",
"/webjars/**"
};
#Bean
public Docket swaggerSpringMvcPlugin() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("admin-api")
.select()
.paths(paths()) // and by paths
.build();
}
private Predicate<String> paths() {
return or(
regex("/admin.*"),
regex("/issuer.*"),
regex("/validator.*"),
regex("/data.*"));
}
}
And this is my WebSecurityConfig.java :
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private JwtTokenDecoder jwtTokenDecoder;
#Bean
// Mandatory to be able to have % in URL
// FIXME Set it only for dev environment
public HttpFirewall allowUrlEncodedPercentHttpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowUrlEncodedPercent(true);
firewall.setAllowUrlEncodedSlash(true);
return firewall;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.httpBasic().disable()
.formLogin().disable()
.logout().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// Install the JWT authentication filter
http.addFilterBefore(new JwtAuthenticationFilter(jwtTokenDecoder), BasicAuthenticationFilter.class);
// Authorize only authenticated requests
http.authorizeRequests()
.anyRequest().authenticated();
http.cors();
}
#Override
public void configure(WebSecurity web) {
// Allow access to /admin/login without authentication
web.ignoring().mvcMatchers("/admin/login", "/admin/validate", "/campaigns", "/data/**", "/issuer/**", "/validator/**");
web.ignoring().antMatchers(SwaggerConfiguration.SWAGGER_ENDPOINTS);
web.httpFirewall(allowUrlEncodedPercentHttpFirewall());
}
}
Finally, I have a WebConfig.java used to set CORS authorizations.
Here it is :
#Configuration
#EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "PATCH", "DELETE");
}
}
Very simple. It should authorize almost any access.
When I remove it, Swagger is available from URL localhost:8080/swagger-ui.html (but not my webservices...)
When I put it back, it is blocked, with a 403 error (forbidden)
Any idea of what I am missing ?
So the solution was to add some configuration in WebConfig
I have added this implementation
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry
.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}

CORS problems with Spring Security and Websocket

I am developing an Ionic app based on a Spring backend.
I implemented Spring Security with JWT authentication. My app will have a chat room where users can talk each other in private or public chat. So, I am implementing a WebSocket system in order to get all updates in real time.
This is my Security Configuration:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
#Autowired
private UserDetailsService userDetailsService;
private AuthenticationManager authenticationManager;
#Autowired
public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder
.userDetailsService(this.userDetailsService)
.passwordEncoder(passwordEncoder());
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public JwtAuthenticationTokenFilter authenticationTokenFilterBean() throws Exception {
return new JwtAuthenticationTokenFilter();
}
// configurazione Cors per poter consumare le api restful con richieste ajax
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.addAllowedOrigin("*");
configuration.setAllowedMethods(Arrays.asList("POST, PUT, GET, OPTIONS, DELETE"));
configuration.addAllowedHeader("*");
configuration.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.csrf().disable()
.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class)
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().cors().and()
.authorizeRequests()
.antMatchers(
HttpMethod.GET,
"/",
"/*.html",
"/favicon.ico",
"/**/*.html",
"/**/*.css",
"/**/*.js",
"/image/**").permitAll()
.antMatchers("/socket/**").permitAll()
.antMatchers("/public/**").permitAll().and()
.authorizeRequests().anyRequest().authenticated().and();
httpSecurity.headers().cacheControl();
}
#Bean
public AuthenticationManager customAuthenticationManager() throws Exception {
return authenticationManager();
}
}
This is my WebSocket configuration:
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfiguration extends AbstractWebSocketMessageBrokerConfigurer{
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/socket")
.setAllowedOrigins("*")
.withSockJS();
}
#Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/chat")
.enableSimpleBroker("/subscribe");
}
}
In this condition, I am currently facing this error:
Access to XMLHttpRequest at
'http://localhost:8080/SpringApp/socket/info?t=1547732425329' from
origin 'http://localhost:8100' has been blocked by CORS policy: The
value of the 'Access-Control-Allow-Origin' header in the response must
not be the wildcard '*' when the request's credentials mode is
'include'. The credentials mode of requests initiated by the
XMLHttpRequest is controlled by the withCredentials attribute.
Each call is working (i am perfectly authorized with jwt) but the WebSocket can't work.
So, I tried to simply remove the .cors() in configure method in my security configuration class. This lead me to an opposite problem:
error in chrome
Indeed, now WebSocket works perfectly, instead each api call gives me 401.
What's the correct way to resolve this problem?
Thank you
Yeah, I got the same error when I was working in a related issue in one of my projects. The solution was that I had to set the allowed-origin header value to the URL of my application. The wildcard value (*) is not allowed if you send credentials.

Resources