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

Java 从数据库中动态检索控制器中特定方法的Spring Boot CORS配置,java,spring-boot,cors,microservices,jhipster,Java,Spring Boot,Cors,Microservices,Jhipster,我正在尝试使用以下命令在控制器级别设置CORS配置 @CrossOrigin on Controller and Handler Method public class AccountController { @CrossOrigin("retreive data from DB") @RequestMapping("/{id}") public Account retrieve(@PathVariable Long id) { // ... } } 我尝试过使用下面的方法,但它只

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

@CrossOrigin on Controller and Handler Method

public class AccountController {

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

我尝试过使用下面的方法,但它只在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
将从数据库中获取数据。DB中的任何更改只有在Spring Boot应用程序重新启动时才会反映出来


用于
CorsService.fetchCorsConfigFromDb
它应该从缓存加载

然后您可以在运行时更新缓存

您应该实现
CorsService.fetchCorsConfig()

  • 此方法应首先在缓存中查找任何cors配置,如果找到任何配置,请直接从缓存加载它,否则您将从db检索cors并更新缓存
  • 创建运行时更新cors方法
    CorsService.updateCorsConfig(),这将更新数据库中的cors,然后更新缓存

  • 要实现此功能,您可以使用一个基本筛选器,在该筛选器中,您可以编写自定义数据库逻辑,根据某些数据库属性值将CORS头添加到请求中

    您可以参考下面的示例,使用SpringDataJPA实现此功能

    将DB连接属性添加到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;
    }
    
    public interface CorsRepository extends JpaRepository<Cors,Long> {
        Optional<Cors> findByUrl(String url);
    }
    
    @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() { }
    }
    
    @RestController
    public class CorsTesterController {
    
        @GetMapping("/api/v1/test")
        String getResponse(){
            return "test response";
        }
    }
    
    并且在存储库中添加了一个
    findByUrl
    方法,根据URL从数据库中获取值

    CorsRepository.java

    @Entity
    @Getter
    @Setter
    public class Cors {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private long id;
        private String url;
        private boolean isAllowed;
    }
    
    public interface CorsRepository extends JpaRepository<Cors,Long> {
        Optional<Cors> findByUrl(String url);
    }
    
    @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() { }
    }
    
    @RestController
    public class CorsTesterController {
    
        @GetMapping("/api/v1/test")
        String getResponse(){
            return "test response";
        }
    }
    
    您可以创建如下示例控制器:

    CorsTesterController.java

    @Entity
    @Getter
    @Setter
    public class Cors {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private long id;
        private String url;
        private boolean isAllowed;
    }
    
    public interface CorsRepository extends JpaRepository<Cors,Long> {
        Optional<Cors> findByUrl(String url);
    }
    
    @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() { }
    }
    
    @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为什么不在ApplicationCOntext上使用getBean()而不是自动连接CorsRepository?您可以查看以下链接:@GaëlMarziou,您是对的<代码>@Autowiring
    将在带有
    @组件的过滤器中工作。注释已删除。我已经根据评论更新了答案