从数据库中动态检索 Spring Boot CORS 配置以获取控制器中的特定方法
Posted
技术标签:
【中文标题】从数据库中动态检索 Spring Boot CORS 配置以获取控制器中的特定方法【英文标题】:Dynamicallly retrieve Spring Boot CORS Configuration from database for specific method in a Controller 【发布时间】:2020-06-02 02:17:46 【问题描述】:我正在尝试使用
在控制器级别设置 CORS 配置@CrossOrigin on Controller and Handler Method
public class AccountController
@CrossOrigin("retreive data from DB")
@RequestMapping("/id")
public Account retrieve(@PathVariable Long id)
// ...
我尝试过使用下面,但它仅在 spring boot 启动时设置,并且仅在下次重新启动服务时才进行更改...
@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
将从数据库中获取数据。仅当 Spring Boot App 重新启动时才会反映来自 DB 的任何更改...
【问题讨论】:
【参考方案1】:要实现此功能,您可以使用基本过滤器,您可以在其中编写自定义数据库逻辑,以根据某些数据库属性值将 CORS 标头添加到您的请求中。
您可以参考下面的示例来使用 spring-data-jpa 实现此功能。
将数据库连接属性添加到 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
创建具有以下属性的实体以将 URL 保存在数据库中
Cors.java
@Entity
@Getter
@Setter
public class Cors
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String url;
private boolean isAllowed;
并且在存储库中添加了一个findByUrl
方法来根据 URL 从数据库中获取价值
CorsRepository.java
public interface CorsRepository extends JpaRepository<Cors,Long>
Optional<Cors> findByUrl(String url);
下面是我的过滤器来拦截请求并进行 DB 调用,如果 isAllowed
为真,那么我添加 cors 标头以发出成功的请求
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()
您可以像这样创建示例控制器:
CorsTesterController.java
@RestController
public class CorsTesterController
@GetMapping("/api/v1/test")
String getResponse()
return "test response";
并将值插入 DB 以允许/禁止 url 来测试此示例代码。
testdb=# select * from cors;
id | is_allowed | url
----+------------+-----------------
1 | f | /api/v1/block
2 | t | /api/v1/allowed
【讨论】:
太棒了!!好主意 。如果您发现问题相关。请支持@Ajit Soman 的问题 为什么不自动装配 CorsRepository 而不是在 ApplicationCONtext 上使用 getBean()? 你可以查看这个链接:***.com/questions/32494398/… @GaëlMarziou,你是对的。@Autowiring
将在带有@Component
的过滤器中工作。注释。
@MohammadJaved。我已经根据评论更新了答案【参考方案2】:
发给 CorsService.fetchCorsConfigFromDb;
它应该从缓存中加载
然后您可以在运行时更新您的缓存
你应该实现CorsService.fetchCorsConfig();
-
此方法应首先在缓存中查找任何 cors 配置,如果找到任何配置,则直接从缓存中加载它,否则您将从 db 中检索 cors 并更新您的缓存
create update cors at runtime method
CorsService.updateCorsConfig();
,这应该更新你在 db 中的 cors 然后更新缓存。
【讨论】:
谢谢!!如果您发现问题相关。请为问题投票以上是关于从数据库中动态检索 Spring Boot CORS 配置以获取控制器中的特定方法的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring Boot 中使用特定日期范围和聚合从 MongoDB 数据库中检索数据?
如何从 AWS API Gateway 自定义授权方检索 Spring Boot 中的上下文对象?