1.背景
需要做一个微信分享的后端支持接口,请求响应中包含appid,为了避免对外暴露配置相应的安全策略
2.步骤
限制请求域名
在后端cors过滤器中添加指定的域名作为allowedOrigins的值,非此域名无法访问接口\
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("aa.bb.cc")
.allowCredentials(true)
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.maxAge(3600);
}
}
限制请求来源
在后端读取referer值判断是否是规定的来源页,否则禁止调用
String referer = request.getHeader("referer");
String pattern = "^http://h5.zwlearn.com/yifu.*$";
if (referer == null || !Pattern.matches(pattern, referer)) {
throw new RRException("禁止调用");
}
在以上步骤时,因为做了nginx的反向代理,所以为了获得真实的请求域名和请求来源页,做如下配置:
location /api/{
proxy_set_header Referer $http_referer;
proxy_set_header Host $http_host;
proxy_pass http://localhost:8085/;
}
http情况下默认不会发送referer ,为了在前端发送referer,做如下配置
<meta name="referrer" content="unsafe-url">
解释一下这个值,这个是用来设置Referrer Policy的
引用策略有以下几种:
- No Referrer:任何情况下都不发送Referrer信息
- No Referrer When Downgrade:仅当协议降级(如HTTPS页面引入HTTP资源)时不发送Referrer信息。是大部分浏览器默认策略。
- Origin Only:发送只包含host部分的referrer.
- Origin When Cross-origin:仅在发生跨域访问时发送只包含host的Referer,同域下还是完整的。与Origin Only的区别是多判断了是否Cross-origin。协议、域名和端口都一致,浏览器才认为是同域。
- Unsafe URL:全部都发送Referrer信息。最宽松最不安全的策略。
3.效果
在其他域名无法访问,在浏览器直接打开接口地址也无法访问(因为做了转发,和指定的前端referrer并不相同),但是在接口测试工具(类似postman之类)手动指定对应的referrer也是可以访问到的,这点没想到什么比较好的方法限制住