从数据库中动态检索控制器中特定方法的 Spring Boot CORS 配置

Moh*_*ved 4 java cors spring-boot jhipster microservices

我正在尝试使用以下命令在控制器级别设置 CORS 配置

@CrossOrigin on Controller and Handler Method

public class AccountController {

@CrossOrigin("retreive data from DB")
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

}

我尝试过使用下面的方法,但它仅在 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);
}
Run Code Online (Sandbox Code Playgroud)

fetchCorsConfigFromDb将从数据库获取数据。仅当 Spring Boot 应用程序重新启动时,数据库中的任何更改才会反映出来......

Aji*_*man 5

要实现此功能,您可以使用基本过滤器,在其中编写自定义数据库逻辑,以根据某些数据库属性值将 CORS 标头添加到您的请求中。

您可以参考下面的示例使用 spring-data-jpa 来实现此功能。

将数据库连接属性添加到 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
Run Code Online (Sandbox Code Playgroud)

创建具有以下属性的实体以将 URL 保存在数据库中

java

@Entity
@Getter
@Setter
public class Cors {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    private String url;
    private boolean isAllowed;
}
Run Code Online (Sandbox Code Playgroud)

并在存储库中添加了一种findByUrl根据 URL 从数据库获取值的方法

CorsRepository.java

public interface CorsRepository extends JpaRepository<Cors,Long> {
    Optional<Cors> findByUrl(String url);
}
Run Code Online (Sandbox Code Playgroud)

下面是我的过滤器,用于拦截请求并进行数据库调用,如果isAllowed为 true,则我添加 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() { }
}
Run Code Online (Sandbox Code Playgroud)

您可以像这样创建一个示例控制器:

CorsTesterController.java

@RestController
public class CorsTesterController {

    @GetMapping("/api/v1/test")
    String getResponse(){
        return "test response";
    }
}
Run Code Online (Sandbox Code Playgroud)

并将值插入数据库以允许/禁止 URL 来测试此示例代码。

testdb=# select * from cors;
 id | is_allowed |       url
----+------------+-----------------
  1 | f          | /api/v1/block
  2 | t          | /api/v1/allowed
Run Code Online (Sandbox Code Playgroud)