Skip to content

FE: Closes #535, allowing to configure cors through spring properties #574

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.kafbat.ui.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
Expand All @@ -15,14 +16,17 @@
@Configuration
public class CorsGlobalConfiguration {

@Autowired
private CorsProperties corsProperties;

@Bean
public WebFilter corsFilter() {
return (final ServerWebExchange ctx, final WebFilterChain chain) -> {
final ServerHttpRequest request = ctx.getRequest();

final ServerHttpResponse response = ctx.getResponse();
final HttpHeaders headers = response.getHeaders();
fillCorsHeader(headers, request);
fillCorsHeader(headers);

if (request.getMethod() == HttpMethod.OPTIONS) {
response.setStatusCode(HttpStatus.OK);
Expand All @@ -33,11 +37,11 @@ public WebFilter corsFilter() {
};
}

public static void fillCorsHeader(HttpHeaders responseHeaders, ServerHttpRequest request) {
responseHeaders.add("Access-Control-Allow-Origin", request.getHeaders().getOrigin());
responseHeaders.add("Access-Control-Allow-Credentials", "true");
responseHeaders.add("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, OPTIONS");
responseHeaders.add("Access-Control-Max-Age", "3600");
responseHeaders.add("Access-Control-Allow-Headers", "Content-Type");
public void fillCorsHeader(HttpHeaders responseHeaders) {
responseHeaders.add("Access-Control-Allow-Origin", corsProperties.getAllowedOrigins());
responseHeaders.add("Access-Control-Allow-Credentials", corsProperties.getAllowCredentials());
responseHeaders.add("Access-Control-Allow-Methods", corsProperties.getAllowedMethods());
responseHeaders.add("Access-Control-Max-Age", corsProperties.getMaxAge());
responseHeaders.add("Access-Control-Allow-Headers", corsProperties.getAllowedHeaders());
}
}
18 changes: 18 additions & 0 deletions api/src/main/java/io/kafbat/ui/config/CorsProperties.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.kafbat.ui.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "cors")
@Data
public class CorsProperties {

private String allowedOrigins;
private String allowedMethods;
private String allowedHeaders;
private String allowCredentials;
private String maxAge;

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.WebProperties;
import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
Expand All @@ -38,6 +39,9 @@
@Order(Ordered.HIGHEST_PRECEDENCE)
public class GlobalErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {

@Autowired
private CorsGlobalConfiguration corsGlobalConfiguration;

public GlobalErrorWebExceptionHandler(ErrorAttributes errorAttributes,
ApplicationContext applicationContext,
ServerCodecConfigurer codecConfigurer) {
Expand Down Expand Up @@ -151,9 +155,7 @@ private String requestId(ServerRequest request) {
}

private Consumer<HttpHeaders> headers(ServerRequest request) {
return (HttpHeaders headers) -> {
CorsGlobalConfiguration.fillCorsHeader(headers, request.exchange().getRequest());
};
return corsGlobalConfiguration::fillCorsHeader;
}

private BigDecimal currentTimestamp() {
Expand Down
7 changes: 7 additions & 0 deletions api/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,10 @@ logging:
reactor.netty.http.server.AccessLog: INFO
org.hibernate.validator: WARN

cors:
allowed-origins: "*"
allowed-methods: "GET, PUT, POST, DELETE, OPTIONS"
allowed-headers: "Content-Type"
allow-credentials: "true"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* for allow-origin can not be used simultaneously with allow-credentials set to true. I suggest keeping the configuration as it is right now for backward compatibility and using the new approach if either of the properties (cors.*) is set (not null) or introducing even a new properly like (cors.enabled). What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think allowed-origins should be null by default and if it is null we could pass request.getHeaders().getOrigin(). This will keep backward compatibility.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aditya-baldwa hi, could you address this please?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Haarolean, yes, will check on it

max-age: "3600"

39 changes: 39 additions & 0 deletions contract/src/main/resources/swagger/kafbat-ui-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4426,3 +4426,42 @@ components:
type: object
additionalProperties:
type: string
cors:
type: object
properties:
allowedOrigins:
type: array
items:
type: string
description: >-
List of allowed origins for CORS.
If not provided, defaults to allowing all origins (`*`)
default: ["*"]
allowedMethods:
type: array
items:
type: string
description: >-
List of allowed HTTP methods for CORS
If not provided, defaults to `GET, POST, PUT, DELETE, OPTIONS`.
default: ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
allowedHeaders:
type: array
items:
type: string
description: >-
List of allowed HTTP headers for CORS.
If not provided, defaults to allowing all headers (`*`).
default: ["*"]
allowCredentials:
type: boolean
description: >-
Whether to allow credentials in CORS requests.
If not provided, defaults to `true`
default: true
maxAge:
type: integer
description: >-
Maximum age (in seconds) for CORS preflight requests.
If not provided, defaults to `3600` seconds.
default: 3600
Loading