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.
You can refer to below example to implement this functionality using spring-data-jpa.
Add DB connection attributes to application.properties file
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
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
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
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
@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.
testdb=# select * from cors;
id | is_allowed | url
----+------------+-----------------
1 | f | /api/v1/block
2 | t | /api/v1/allowed