How deactivate CORS in a Spring Boot API (Version 2.2.6) - spring

I am currently working on a React Front-End with an already existing Spring Boot Backend.
When developing locally i ran into the typicall CORS Error:
Access to fetch at 'http://localhost:8180/api/data/firms' from
origin 'https://localhost:8087' 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.
runtime.js:98 GET http://localhost:8180/api/data/firms net::ERR_FAILED
I already tried most of the solutions mentioned in this post however nothing really helped. By adding one of these snippets
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().configurationSource(request -> new CorsConfiguration().applyPermitDefaultValues());
}
#Bean
public FilterRegistrationBean<CorsFilter> corsFilterRegistrationBean() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
}
or creating a CorsFilter the CORS Error was gone but now the API always returned a HTTP 500 Error.
Does anyone know a solution for my problem?

You can add this in your controller class.
#CrossOrigin(origins = "${cross.origin}")
#RestController
application.properties
cross.origin=https://localhost:8087

I've added new answer for Spring Boot.
Additionally, if you are using create-react-app, you will avoid CORS problem to set up proxy.
(In this case, it is not required to change Spring Boot settings.)
package.json:
"proxy": "http://localhost:8180",

Related

Spring Auth Server 1.0.0 (w/ Spring Boot 3.0.0) CORS configuration not working for .well_known endpoints

I am trying to use the Spring Boot Auth Server sample code with a ReactJS frontend that will be hosted as a separate service. However, I am getting the following error.
localhost/:1 Access to fetch at 'https://8f5d3990e976.ngrok.io/.well-known/openid-configuration' from origin 'http://localhost:3000' has been blocked by CORS policy: 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.
I'm trying to configure CORS mentioned in this comment.
https://github.com/spring-projects/spring-authorization-server/issues/110#issuecomment-707964588
The class WebSecurityConfigurerAdapter was deprecated and removed so I added it a little differently.
#Bean
#Order(Ordered.HIGHEST_PRECEDENCE)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("http://localhost:3000");
config.addAllowedHeader("*");
config.addAllowedMethod("GET");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/oauth2/**", config);
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
http.cors().configurationSource(source);
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
.oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0
// #formatter:off
http
.exceptionHandling(exceptions ->
exceptions.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"))
)
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
// #formatter:on
return http.build();
}
Note: The reason I added the source with a local variable is I got this IDE error
If anyone would be able to help with this I would greatly appreciate it. Cheers.

Migrating Springdoc from Springfox [duplicate]

This question already has an answer here:
How can I bypass authentication for Swagger-UI?
(1 answer)
Closed last month.
I am working on a legacy project (still uses Spring Boot 1.5).
Our team tasked with upgrading the project and one of the task is update Springfox to Springdoc.
I have change all annotations and I think it works because I can get the YAML or JSON file using /v3/api-docs URL.
One think that I cannot access is the Swagger UI. In the application.yml, I have added this:
springdoc:
api-docs:
resolve-schema-properties: true
swagger-ui:
use-root-path: true
validatorUrl: none
path: /swagger-ui
operationsSorter: alpha
tagsSorter: alpha
docExpansion: none
But everytime I access /swagger-ui/index.html or /swagger-ui.html, it seems it got error due to security or filter chain. There is security dependency in the project. I am newbie here so any suggestion what I can check. How to debug this?
You need to allow unauthenticated access to the Swagger resources in your Spring Security config. The following worked for me:
#Configuration
#EnableWebSecurity
class WebSecurityConfiguration {
private static final String[] SWAGGER_PATHS = {"/swagger-ui.html", "/v3/api-docs/**", "/swagger-ui/**", "/webjars/swagger-ui/**"};
private final UserRegistrationFilter authenticationTokenFilter;
#Bean
SecurityFilterChain filterChain(final HttpSecurity http) throws Exception {
return http
// Configure access rules
.authorizeHttpRequests(authorize -> authorize
.antMatchers(SWAGGER_PATHS).permitAll()
.anyRequest().authenticated())
// All your other config
.build();
}
}

Why the spring-cloud with the gatway ignore the cors property defined in application.properties?

I'm trying to build a microservices spring-boot application using spring-cloud and spring-gateway. In my application there is a api-gateway application that handle all the request and later will dispatch those request to the right microservice.
For the front-end I'm using angular and for test the endpoints I'm using postman. At the moment I'm having a CORS problem. I've configured the api-gateway in this way:
spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping=true
spring.cloud.gateway.globalcors.corsConfigurations.[/**].allowedOrigins=*
spring.cloud.gateway.globalcors.corsConfigurations.[/**].allowedHeaders=*
spring.cloud.gateway.globalcors.corsConfigurations.[/**].allowedMethods=*
According to the documentation it should be enough to allow a client to make a request without problem.
Also I've configured all the gateway route in this way...
spring.cloud.gateway.routes[8].id=entity-service
spring.cloud.gateway.routes[8].uri=lb://entity-service
spring.cloud.gateway.routes[8].predicates[0]=Path=/api/entity/hello
My security config also is the one below
#Configuration
#EnableWebFluxSecurity
public class SecurityConfig {
#Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity serverHttpSecurity) {
serverHttpSecurity
.authorizeExchange(exchange ->
exchange.pathMatchers("/eureka/**")
.permitAll()
.anyExchange()
.authenticated())
.cors()
.and()
.csrf()
.disable()
.oauth2ResourceServer(ServerHttpSecurity.OAuth2ResourceServerSpec::jwt);
return serverHttpSecurity.build();
}
}
Said that, if for instance I make a request with postman to the path /api/entity/hello I get the correct response. If I'm using the angular client and try to access an end-point , first an OPTIONS preflight request is made and return:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8080/api/entity/hello. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 401.
then the GET request for the ..../hello path is made and the result is the same.
I am using spring-boot 2.7.3 and the latest spring-boot-cloud and gateway package.
Do you have any idea how to fix this? Any help will be appreciated.
Thanks to all
Try adding CorsConfigurationSource bean to your config class.
#Bean
public CorsConfigurationSource corsConfigurationSource(GlobalCorsProperties globalCorsProperties) {
var source = new UrlBasedCorsConfigurationSource();
globalCorsProperties.getCorsConfigurations().forEach(source::registerCorsConfiguration);
return source;
}

403 Forbidden Using Springboot When Hitting Okta Userinfo endpoint

I'm trying to set up Okta as a sign on for a set of subpaths in my spring boot app.
I'm configuring the auth resource details with:
#Bean(name = "oktaOAuthClient")
public AuthorizationCodeResourceDetails oktaOAuthAdminClient(#Qualifier("oktaAdminConfiguration") OktaConfigurationProperties oktaAdminCongfig,
ICredentialsApi credentialsApi) {
String redirectUrl = UriComponentsBuilder.fromUriString("http://localhost:8091/")
.path(ConfigurationRequestPaths.ADMINISTRATION_LANDING)
.build(false)
.toUriString();
AuthorizationCodeResourceDetails client = new AuthorizationCodeResourceDetails();
client.setClientId(oktaAdminCongfig.getClientId());
client.setClientSecret(oktaAdminCongfig.getClientSecret());
client.setAccessTokenUri(oktaAdminCongfig.getAccessTokenUri());
client.setUserAuthorizationUri(oktaAdminCongfig.getUserAuthorizationUri());
client.setClientAuthenticationScheme(AuthenticationScheme.header);
client.setPreEstablishedRedirectUri(redirectUrl);
client.setScope(OKTA_SCOPES);
client.setUseCurrentUri(false);
client.setScope(OKTA_SCOPES);
return client;
}
These and other settings are found from the application.properties manually and are set as:
okta.admin.clientId={id}
okta.admin.clientSecret={secret}
okta.admin.accessTokenUri=https://dev-{value}.okta.com/oauth2/default/v1/token
okta.admin.userAuthorizationUri=https://dev-{value}.okta.com/oauth2/default/v1/authorize
okta.admin.issuer=https://dev-{value}.okta.com/oauth2/default
okta.admin.userInfoUrl=https://dev-{value}.okta.com/oauth2/default/v1/userinfo
Then I've made a filter with (Note, is the clientId set in the UserTokenInfoServices meant to be the client id from the okta client id/client secret?):
#Bean(name = "oktaFilter")
public Filter oktaFilter(#Qualifier("oktaOAuthClient") AuthorizationCodeResourceDetails oktaOAuthClient,
#Qualifier("oktaOAuthResource") ResourceServerProperties resource,
#Qualifier("oktaOAuthRestTemplate") OAuth2RestTemplate oktaOAuthRestTemplate) {
ExceptionMappingAuthenticationFailureHandler failureHandler = new ExceptionMappingAuthenticationFailureHandler();
failureHandler.setDefaultFailureUrl("/");
OAuth2ClientAuthenticationProcessingFilter filter = new OAuth2ClientAuthenticationProcessingFilter(ConfigurationRequestPaths.ADMINISTRATION_LANDING);
UserInfoTokenServices tokenServices = new UserInfoTokenServices(resource.getUserInfoUri(), oktaOAuthClient.getClientId());
tokenServices.setRestTemplate(oktaOAuthRestTemplate);
filter.setRestTemplate(oktaOAuthRestTemplate);
filter.setTokenServices(tokenServices);
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setUseReferer(true);
filter.setAuthenticationSuccessHandler(successHandler);
filter.setAuthenticationFailureHandler(failureHandler);
return filter;
}
Finally I've set up the WebSecurityConfigurerAdapter with the following:
http.antMatcher("/config/**")
.authorizeRequests()
.antMatchers("/config")
.permitAll()
.anyRequest().authenticated().and()
.exceptionHandling()
.authenticationEntryPoint(oktaLoginHandler)SimpleUrlAuthenticationSuccessHandler(ConfigurationRequestPaths.ADMINISTRATION_LANDING))
.and()
.logout().addLogoutHandler(oktaLogoutHandler).logoutSuccessUrl(externalAccessUrl).permitAll().and()
.addFilterBefore(oktaFilter, BasicAuthenticationFilter.class);
}
The redirect for the subpath works correctly and goes to a sign in page, but I get an error after signing in that warns:
org.springframework.security.authentication.BadCredentialsException: Could not obtain user details from token...Caused by: org.springframework.security.oauth2.common.exceptions.InvalidTokenException:
I believe this likely has to do with getting a 403 when hitting the okta userinfo endpoint:
Request is to process authentication
Retrieving token from https://dev-{value}.okta.com/oauth2/default/v1/token
Encoding and sending form: {grant_type=[authorization_code], code=[{code}], redirect_uri=[http://localhost:8091/config], client_id=[{id}], client_secret=[{secret}]}
HTTP GET https://dev-{value}.okta.com/oauth2/default/v1/userinfo
Accept=[application/json, application/*+json]
Response 403
I've also tried the okta starter but it seems to break when used with another oauth login to github for another set of subpaths in the application. The spring version I'm using doesn't include the .oauthLogin() and other settings for httpsecurity that I've seen some guides on.
edit: Adding my spring dependency list for more clarification:
org.springframework:spring-beans:5.1.20.RELEASE
org.springframework:spring-context:5.1.20.RELEASE
org.springframework:spring-jdbc:5.1.20.RELEASE
org.springframework:spring-tx:5.1.20.RELEASE
org.springframework:spring-web:5.1.20.RELEASE
org.springframework:spring-webmvc:5.1.20.RELEASE
org.springframework:spring-test:5.1.20.RELEASE
org.springframework.boot:spring-boot-actuator:2.1.18.RELEASE
org.springframework.boot:spring-boot-autoconfigure:2.1.18.RELEASE
org.springframework.boot:spring-boot-configuration-processor:2.1.18.RELEASE
org.springframework.boot:spring-boot-starter:2.1.18.RELEASE
org.springframework.boot:spring-boot-starter-actuator:2.1.18.RELEASE
org.springframework.boot:spring-boot-starter-security:2.1.18.RELEASE
org.springframework.boot:spring-boot-starter-thymeleaf:2.1.18.RELEASE
org.springframework.boot:spring-boot-starter-web:2.1.18.RELEASE
org.springframework.boot:spring-boot-starter-test:2.1.18.RELEASE
org.springframework.retry:spring-retry:1.3.1
org.springframework.security:spring-security-config:5.1.13.RELEASE
org.springframework.security:spring-security-core:5.1.13.RELEASE
org.springframework.security:spring-security-ldap:5.1.13.RELEASE
org.springframework.security:spring-security-web:5.1.13.RELEASE
org.springframework.security.oauth:spring-security-oauth2:2.3.8.RELEASE
org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.1.18.RELEASE
It sounds like you might be using the older Spring Security OAuth project:
spring-security-oauth?
This project has been deprecated. The newer Spring Security OAuth2 modules are great, and they are now first-class citizens, in Spring Security (they live in the official project now). Along with this Spring Boot 1.x is EoL, and is no longer getting patches and security updates.
Most of the guides you are seeing likely reference the newer libraries (e.g. things like .oauthLogin()).
Sorry for the typical StackOverflow answer of "don't do X", but here is what I would recommend:
Update your Spring Boot version
Migrate the newer OAuth libraries
Then add your new logic (this should be much easier after updating)
If you are already on Spring Boot 2 and the newer OAuth lib, let me know, and we can try to figure out why you don't have the newer HttpSecurity methods.

CORS Issue during preflight browser request [duplicate]

This question already has an answer here:
Spring Boot CORS with HTTPS failing
(1 answer)
Closed 2 years ago.
While trying to connect to my Rest APIs via Angular, I am running into what seems to be a fairly straight forward CORS issue:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://mserverIP:port/apicontext/getsitebyuserid/userId. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
My APIs are setup in Springboot and I have already tried following:
Set up #CrossOrigin(origins = "*") annotation at class and method levels. Also enabled GET, POST, OPTIONS for cross origin as well as allowed for all the headers.
Setup the added CORS configuration globally with following code:
httpServletResponse.setHeader("Access-Control-Allow-Origin","*");
httpServletResponse.setHeader("Access-Control-Allow-Methods","GET,POST,OPTIONS,HEAD");
httpServletResponse.setHeader("Access-Control-Max-Age", "7200");
httpServletResponse.setHeader("Access-Control-Allow-Headers",
"Content-Type, X-Requested-With, accept, authorization, Origin, Access-Control-Request-Method, Access-Control-Request-Headers");
Tried it via proxy authentication (authentication being used is JWT).
This piece of information might be vital: for an unauthenticated API, the CORS issue doesn't happen but for the protected routes, it returns 403. The problem for protected routes happen even if I have not set authentication header to true.
Also, I have noticed earlier that during preflight, its combination of 2 headers that's causing the issue. If I send origin: http://localhost:4200 and Access-Control-Request-Method: GET it errors out. But if I sends one of the headers it works. During the OPTIONS request, if there's a request header called origin, the request fails. If I remove origin from postman it works.
First of all if you are using spring security then you can get rid of the class level annotations and handle the CORS configuration globally in your security configuration class like :
#Override
protected void configure(HttpSecurity http) throws Exception {
http.
cors().and().csrf().disable()
.authorizeRequests()
.antMatchers("/**").permitAll()
.antMatchers("/login").hasRole("ADMIN")
.antMatchers("/Signup").hasRole("USER")
.and()
.exceptionHandling()
.accessDeniedPage("/access-denied")
.and()
.addFilter(new JWTAuthenticationFilter(authenticationManager()))
.addFilter(new JWTAuthorizationFilter(authenticationManager(), customUserDetailService));
}
#Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200")); //or * if you want to allow all
configuration.setAllowCredentials(true);
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
configuration.setExposedHeaders(Arrays.asList("custom-header1", "custom-header2"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
Secondly, you don't need the cors filter to manually add the response headers to every request because if you configure the cors configuration correctly , springboot will automatically add all the necessary headers in response through the CorsFilter . So, if you are using cors with spring security it is easier to us the provided filter with your configurations. Also, ensure that the springboot auto-configuration is working for you as using annotation #EnableWebMvc will disable the auto-configurations and in that case you will have to handle cors using filter probably.

Resources