I am running a jHipster instance with oAuth authentication and CORS enabled on the server. I've added the following bean:
#Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.setAllowedMethods(Arrays.asList(new String[]{"GET", "PUT", "POST", "DELETE", "OPTIONS"}));
source.registerCorsConfiguration("/api/**", config);
source.registerCorsConfiguration("/v2/api-docs", config);
source.registerCorsConfiguration("/oauth/**", config);
return new CorsFilter(source);
}
and added .antMatchers(HttpMethod.OPTIONS, "/oauth/token").permitAll() to ResourceServerConfiguration configuration.
When I attempt to authenticate a user (using jHipster running on a server) from an app running locally on a browser, I get:
Request Method:OPTIONS - Status Code:401 Unauthorized
It seems CORS is not configured properly to handle pre-flight authentication POST requests.
I've tried to implement some solutions proposed at Spring Data Rest and Cors and Spring Data Rest and Cors to no avail.
Is this something specific that can be done in jHipster to enabled authentication to work from a browser or app (not running on the jhipster server)?
I uncommented lines of CORS
cors: #By default CORS are not enabled. Uncomment to enable.
allowed-origins: "*"
allowed-methods: GET, PUT, POST, DELETE, OPTIONS
allowed-headers: "*"
exposed-headers:
allow-credentials: true
max-age: 1800
Added in SecurityConfiguration
**.antMatchers(HttpMethod.OPTIONS, "/**")**
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(HttpMethod.OPTIONS, "/**")
.antMatchers("/scripts/**/*.{js,html}")
.antMatchers("/bower_components/**")
.antMatchers("/i18n/**")
.antMatchers("/assets/**")
.antMatchers("/swagger-ui/index.html")
.antMatchers("/api/register")
.antMatchers("/api/activate")
.antMatchers("/api/login/**")
.antMatchers("/api/account/reset_password/init")
.antMatchers("/api/account/reset_password/finish")
.antMatchers("/test/**");
}
And it has been working so far.
Related
I added springdoc-openapi-ui 1.6.12 in my Spring Boot project. I configured oAuth2 with PKCE and everything works fine, when I click on the "authorize" button it redirects me to a sso connection page. Then, I can send requests via swagger ui.
The problem is that it interferes with my Angular front end authentication. The front loops on the /login rout, with a 401 error. Swagger oauth uses the same session cookie as Spring Security/Angular.
Is there a way to use the same session for swagger ui AND angular ? Or is the problem somewhere else ?
This is my configuration :
springdoc:
swagger-ui:
path: /api-docs
tagsSorter: alpha
oauth:
clientId: "XXX"
clientSecret: "XXX"
use-pkce-with-authorization-code-grant: true
oAuthFlow:
authorizationUrl: "XXX/as/authorization.oauth2"
tokenUrl: "XXX/as/token.oauth2"
scope : XXX profile groups XXX email
edit :
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors().configurationSource(corsConfigurationSource())
.and().csrf().disable()
.headers()
.frameOptions().disable()
.httpStrictTransportSecurity()
.includeSubDomains(false)
.maxAgeInSeconds(60*60*24*5)
.and().and()
.authorizeRequests(a -> a
// Management endpoints
.antMatchers(
"/health" + MATCH_ALL,
"/info",
"/prometheus",
"/loggers" + MATCH_ALL,
"/metrics" + MATCH_ALL
).permitAll()
// Authentication
.antMatchers(Routes.CURRENT_USER).permitAll()
.antMatchers("/oauth2/authorization/XXX").permitAll()
.antMatchers(Routes.LOGIN).authenticated()
// Preflight requests
.antMatchers(HttpMethod.OPTIONS).permitAll()
// Applications
.antMatchers(Routes.XXX.BASE + MATCH_ALL).hasAuthority(AuthorityUtil.AUTHORITY_XXX)
)
// By setting the login page here, Spring won't ask which provider we want to use
.oauth2Login().loginPage("/oauth2/authorization/XXX")
.and()
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::opaqueToken)
;
}
#Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.applyPermitDefaultValues();
config.setAllowedOriginPatterns(List.of("*"));
config.setAllowedMethods(List.of("*"));
config.setAllowedHeaders(List.of("*"));
config.setAllowCredentials(true);
config.setMaxAge(1800L);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration(MATCH_ALL, config);
return source;
}
I have a basic Spring Authorization Server set up as a Spring Boot application. I am attempting to access this server via an angular application using angular-auth-oidc-client.
When I attempt to log in, I get this error:
Access to XMLHttpRequest at 'http://localhost:9000/mydomain/.well-known/openid-configuration' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I've made multiple attempts to fix this issue, but have been unsuccessful.
Relevant parts of the Configuration for the authorization server are below:
// #formatter:off
#Bean
public RegisteredClientRepository registeredClientRepository() {
// removed
}
// #formatter:on
#Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(Arrays.asList("*"));
config.setAllowedMethods(Arrays.asList("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH"));
config.setAllowedHeaders(Arrays.asList("*"));
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("GET");
config.addAllowedMethod("POST");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
// #formatter:off
#Bean
#Order(Ordered.HIGHEST_PRECEDENCE)
public SecurityFilterChain authServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
http
.formLogin(Customizer.withDefaults())
.cors().configurationSource(corsConfigurationSource());
return http.build();
}
// #formatter:on
That CORS Configuration seems to be wide open, but I'm still seeing the issue.
Am I just making a stupid mistake that I'm not seeing?
Edit: yes, I've configured that port and domain in application.yml:
server:
port: 9000
servlet:
context-path: /mydomain
I have the following CORS configuration on my spring gateway:
#Configuration
#EnableWebFluxSecurity
public class GatewayConfig {
#Bean
public CorsWebFilter corsWebFilter() {
final CorsConfiguration corsConfig = new CorsConfiguration();
corsConfig.setAllowedOrigins(Collections.singletonList("*"));
corsConfig.setMaxAge(3600L);
corsConfig.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
corsConfig.addAllowedHeader("*");
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfig);
return new CorsWebFilter(source);
}
}
It works perfectly fine with the GET, PUT and DELETE requests, but any POST request returns:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at <service-url>. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 302
Update:
Actually, for some reason it only blocks POST request on one route only.
This is the security configuration:
protected void configure(HttpSecurity http) throws Exception {
// Validate tokens through configured OpenID Provider
http.oauth2ResourceServer().jwt().jwtAuthenticationConverter(jwtAuthenticationConverter());
// Service security setup
http
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/polls").hasRole("ADMIN")
.antMatchers(HttpMethod.PUT, "/polls/*").hasRole("ADMIN")
.antMatchers(HttpMethod.DELETE, "/polls/*").hasRole("ADMIN")
.antMatchers(HttpMethod.POST, "/polls/{author:[\\s\\S]+}/vote").authenticated()
.antMatchers(HttpMethod.POST, "/polls/*").hasRole("ADMIN")
.anyRequest().permitAll();
}
CORS only blocks POST requests on the "/polls" route, while every other request works fine
I am implementing a Spring Boot application that is hosted on a Google App Engine Standard Environment.
I have configured CORS like this, following the official guide:
#Configuration
#EnableWebSecurity
class WebSecurityConfigurer : WebSecurityConfigurerAdapter() {
#Throws(Exception::class)
override fun configure(http: HttpSecurity) {
http.csrf()
.disable()
.cors()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().authorizeRequests().antMatchers("/api/**").permitAll()
}
#Bean
fun corsConfigurationSource(): CorsConfigurationSource {
val configuration = CorsConfiguration()
configuration.allowedOrigins = listOf("*")
configuration.allowedMethods = listOf("GET", "POST", "OPTIONS", "PUT", "DELETE", "HEAD")
val source = UrlBasedCorsConfigurationSource()
source.registerCorsConfiguration("/**", configuration)
return source
}
executing the following cURL I receive the AllowedOrigins header as it is necessary:
curl -H "Access-Control-Request-Method: GET" -H "Origin: http://foo" -X OPTIONS "localhost:8080/api/abc/list?lang=de"
Response:
HTTP/1.1 200
Access-Control-Allow-Origin: *
Now when I have deployed my Spring App to AppEngine, I can also cURL successfully.
HTTP/2 200
access-control-allow-origin: https://myfrontend.com
access-control-allow-methods: GET
access-control-allow-credentials: true
Unfortunately, my Frontend Application gets blocked with a 403
Access to fetch at 'https://mybackend.com/api/abc/list?lang=de' from origin 'https://myfrontend.com' 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 tips?
Thanks.
I think you missed the important part setting headers in cors.
Add this line
configuration.allowedHeaders = listOf("*")
I used this code :
Ref : https://blogs.ashrithgn.com/disable-cors-in-spring-boot/
I have two GAE project
Python based using angular 11
Spring boot based micro services std env
Imp : No other changes in app.yaml or as mentioned by spring at
https://spring.io/guides/gs/rest-service-cors/ will make any difference
#Configuration
public class CorsConfig {
#Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
I am using jhipster v2.27.2
I have enabled cors by uncommenting the lines in the application.yml
jhipster:
async:
corePoolSize: 2
maxPoolSize: 50
queueCapacity: 10000
cors: #By default CORS are not enabled. Uncomment to enable.
allowed-origins: "*"
allowed-methods: GET, PUT, POST, DELETE, OPTIONS
allowed-headers: "*"
exposed-headers:
allow-credentials: true
max-age: 1800
In the "WebConfigurer"
#Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = props.getCors();
if (config.getAllowedOrigins() != null && !config.getAllowedOrigins().isEmpty()) {
source.registerCorsConfiguration("/api/**", config);
source.registerCorsConfiguration("/v2/api-docs", config);
source.registerCorsConfiguration("/oauth/**", config);
}
return new CorsFilter(source);
}
But still when I request for the access token, I see this error
http://localhost:8080/oauth/token?username=admin&password=admin&grant_type=password&scope=read.
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:9090' is therefore not allowed
access. The response had HTTP status code 401.
Looks like in the default SecurityConfiguration, its not skipping security check for OPTIONS.
Try adding the following antMatcher to the protected void configure(HttpSecurity http) method in SecurityConfiguration.java
.antMatchers(org.springframework.http.HttpMethod.OPTIONS, "/api/**").permitAll()
sometimes this issue will come if you forget to register cors on specified URLs.In WebConfigurer look for corsFilter and and add these line
log.debug("Registering CORS filter");
source.registerCorsConfiguration("/api/**", config);
Another option in the SecurityConfiguration.java. Instead of using antMatcher within the configure(HttpSecurity) override, is to add it within the configure(WebSecurity) override...
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(HttpMethod.OPTIONS, "/**")