Динамически извлекайте конфигурацию Spring Boot CORS из базы данных для указанного метода c в контроллере - PullRequest
2 голосов
/ 18 февраля 2020

Я пытаюсь установить конфигурацию CORS на уровне контроллера, используя

@CrossOrigin on Controller and Handler Method

public class AccountController {

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

}

Я попытался использовать ниже, но его установка только тогда, когда пружинная загрузка запускается и принимает изменения только тогда, когда служба будет перезапущена в следующий раз ...

@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 ...

Ответы [ 2 ]

3 голосов
/ 18 февраля 2020

Для реализации этой функции вы можете использовать базовый фильтр c, в котором вы можете записать свои собственные логики базы данных c, чтобы добавить заголовок 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);
}

Ниже приведен мой фильтр для перехвата запроса и сделать вызов БД, и если 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";
    }
}

и вставьте значения в БД, чтобы разрешить / запретить URL для тестирования этого примера кода.

testdb=# select * from cors;
 id | is_allowed |       url
----+------------+-----------------
  1 | f          | /api/v1/block
  2 | t          | /api/v1/allowed
1 голос
/ 18 февраля 2020

Для CorsService.fetchCorsConfigFromDb; он должен загружаться из кеша

, тогда вы можете обновить кеш в во время выполнения

вы должны реализовать CorsService.fetchCorsConfig();

  1. этот метод должен сначала искать любую конфигурацию cors в кеше, если найдены какие-либо конфигурации, загружающие ее непосредственно из кеша, иначе вы извлечете cors из db и обновите ваш кеш
  2. создайте cors для обновления во время выполнения метода CorsService.updateCorsConfig();, это должно обновить ваши cors в db и затем обновить кеш.
...