[英]Dynamicallly retrieve Spring Boot CORS Configuration from database for specific method in a Controller
I am trying to set the CORS configuration at Controller level using我正在尝试使用 Controller 级别设置 CORS 配置
@CrossOrigin on Controller and Handler Method
public class AccountController {
@CrossOrigin("retreive data from DB")
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
} }
I have tried using below but its set only when the spring boot starts and takes changes only when the service is restarted next time...我尝试在下面使用,但它仅在 spring 引导启动时设置,并且仅在下次重新启动服务时才进行更改...
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
// CorsConfiguration config = jHipsterProperties.getCors();
CorsConfiguration config=CorsService.fetchCorsConfigFromDb;
if (config.getAllowedOrigins() != null && !config.getAllowedOrigins().isEmpty()) {
log.debug("Registering CORS filter");
source.registerCorsConfiguration("/api/**", config);
source.registerCorsConfiguration("/management/**", config);
source.registerCorsConfiguration("/v2/api-docs", config);
}
return new CorsFilter(source);
}
fetchCorsConfigFromDb
will fetch data from DB.fetchCorsConfigFromDb
将从数据库中获取数据。 Any changes from DB will be reflected only when Spring Boot App is restarted...只有当 Spring Boot App 重新启动时,DB 的任何更改才会反映出来...
To implement this functionality you can use a basic filter in which you can write your custom database logic to add CORS header to your request based on some database attribute value.要实现此功能,您可以使用基本过滤器,您可以在其中编写自定义数据库逻辑,以根据某些数据库属性值将 CORS 标头添加到您的请求中。
You can refer to below example to implement this functionality using spring-data-jpa.您可以参考以下示例使用 spring-data-jpa 实现此功能。
Add DB connection attributes to application.properties file将数据库连接属性添加到 application.properties 文件
application.properties应用程序属性
spring.jpa.database=POSTGRESQL
spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=update
spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/testdb
spring.datasource.username=postgres
spring.datasource.password=root
Create a entity with below attribute to save URL in DB创建具有以下属性的实体以将 URL 保存在数据库中
Cors.java驱动程序
@Entity
@Getter
@Setter
public class Cors {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String url;
private boolean isAllowed;
}
And in the repository added a findByUrl
method to get value from DB based on URL并在存储库中添加了一个findByUrl
方法以根据 URL 从数据库中获取值
CorsRepository.java CorsRepository.java
public interface CorsRepository extends JpaRepository<Cors,Long> {
Optional<Cors> findByUrl(String url);
}
Below is my filter to intercept request and make DB call and if isAllowed
is true then i add cors headers to make a successful request下面是我的过滤器拦截请求并进行数据库调用,如果isAllowed
为真,那么我添加 cors 标头以发出成功的请求
CorsFilter.java CorsFilter.java
@Component
public class CorsFilter implements Filter {
@Autowired
CorsRepository corsRepository;
@Override
public void init(FilterConfig filterConfig) throws ServletException { }
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
String url = request.getRequestURI().toString();
System.out.println(url);
Optional<Cors> cors = corsRepository.findByUrl(url);
if(cors.isPresent() && cors.get().isAllowed()){
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");
}
chain.doFilter(req, res);
}
@Override
public void destroy() { }
}
You can create a sample controller like this:您可以像这样创建一个示例控制器:
CorsTesterController.java CorsTesterController.java
@RestController
public class CorsTesterController {
@GetMapping("/api/v1/test")
String getResponse(){
return "test response";
}
}
and insert values to DB to allow/disallow a url to test this example code.并将值插入 DB 以允许/禁止 url 来测试此示例代码。
testdb=# select * from cors;
id | is_allowed | url
----+------------+-----------------
1 | f | /api/v1/block
2 | t | /api/v1/allowed
For CorsService.fetchCorsConfigFromDb;
对于CorsService.fetchCorsConfigFromDb;
it should load from cache它应该从缓存加载
then you can update your cache at run-time然后你可以在运行时更新你的缓存
you should implement CorsService.fetchCorsConfig();
你应该实现CorsService.fetchCorsConfig();
CorsService.updateCorsConfig();
在运行时方法CorsService.updateCorsConfig();
创建更新 cors CorsService.updateCorsConfig();
, this should update your cors in db and then update cache . ,这应该更新您在 db 中的 cors ,然后更新缓存。Usually reading properties from database - not secured variant and if you lost connection to database you service can startup not correct.通常从数据库读取属性 - 不是安全变体,如果您失去与数据库的连接,您的服务可能无法正确启动。
Anyway you can do it, but would like to draw attention to default support by Spring a lot of remote properties sources无论如何你可以做到,但想提请注意默认支持 Spring 很多远程属性来源
For loading custom properties you may use要加载自定义属性,您可以使用spring.config.import=optional:file:./cors.yml
or from java args或来自 java 参数-Dspring.config.import=optional:file:./cors.yml
This method support reading from file , from url , config server此方法支持从文件读取,从url , config server
Spring documentation about this Spring 关于这个的文档
For reading CORS configuration from properties file you may use library (I'm developer of this)要从属性文件中读取 CORS 配置,您可以使用库(我是这个的开发者)
<dependency>
<groupId>io.github.iruzhnikov</groupId>
<artifactId>spring-webmvc-cors-properties-autoconfigure</artifactId>
<version>VERSION</version>
</dependency>
and properties config和属性配置
spring:
web:
cors:
enabled: true
mappings: #spring.web.cors.mappings.<any_name>.<property>: <value>
anyName: #just any name, just for grouping properties under the same path pattern (not used in internal logic)
paths: #ant style path pattern, ATTENTION! not ordered, /** pattern override all other pattern
- /path/to/api
- /path/to/api/**
#allowed-origins: "*"
allowed-methods: GET #Enable override all defaults! If disabled: a lot more from all the controller methods included from the path pattern matches
#allowed-headers: "*"
#exposed-headers: ('*' - not-supported)
#allow-credentials: true
allowed-origin-patterns: .*
#max-age: PT30M
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.