接口安全
api接口分类:
1>公共接口:你查快递,你查天气预报,你查飞机,火车班次等,这些都是有公共的接口
2>私密接口:需要登录访问或者公司内部接口
接口安全要求:
1.防伪装攻击(案例:在公共网络环境中,第三方 有意或恶意 的调用我们的接口):接口防刷
2.防篡改攻击(案例:在公共网络环境中,请求头/查询字符串/内容 在传输过程被修改):接口防篡改(签名机制)
3.防重放攻击(案例:在公共网络环境中,请求被截获,稍后被重放或多次重放):接口时效性
4.防数据信息泄漏(案例:截获用户登录请求,截获到账号、密码等):接口加密(https/对称加解密)
接口防刷
需求 :接口防刷
防止不法分子,频繁的请求同一个接口
核心点 :频繁怎么定义 约定:1分钟10次,
思考:每一个客户端都有一个ip ,那么可不可以使用ip作为redis的key
每一个接口都要独立控制访问频率 ,此时可以将接口路径也可以作为key
因为防护必须的在进入controller之前完成 , 多以逻辑必须放在filter或者interceptor选择
思路:
1:设计一个redis临时key, 有效时间是1分钟,1分钟内只允许10访问
key> url : ip
value>访问的次数
2:设置拦截器,拦截需要防刷的接口url
3:拦截逻辑
3.1>拦截url,拼接key查询redis中是否存在
3.2>如果不存在setnx url:ip 10
3.3>如果存在derc url:ip
3.4>如果次数减到0,拦截返回:请勿频繁访问
拓展:加载入黑名单
3.5>其他情况直接放行。
拦截器
public class BrushProofInterceptor implements HandlerInterceptor {
@Autowired
private ISecurityRedisService securityRedisService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
if(!(handler instanceof HandlerMethod)){
return true;
}
String url = request.getRequestURI().substring(1);
String ip = RequestUtil.getIPAddress();
String key = RedisKeys.BRUSH_PROOF.join(url, ip);
if(!securityRedisService.isAllowBrush(key)){
response.setContentType("text/json;charset=UTF-8");
response.getWriter().write(JSON.toJSONString(JsonResult.error(500, "请勿频繁访问","谢谢咯")));
return false;
}
return true;
}
}
redis服务
@Service
public class SecurityRedisServiceImpl implements ISecurityRedisService {
@Autowired
private StringRedisTemplate template;
@Override
public boolean isAllowBrush(String key) {
template.opsForValue().setIfAbsent(key, "10", RedisKeys.BRUSH_PROOF.getTime(), TimeUnit.SECONDS);
Long decrement = template.opsForValue().decrement(key);
return decrement >= 0;
}
}
拦截器配置
@Bean
public BrushProofInterceptor brushProofInterceptor(){
return new BrushProofInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(checkLoginInterceptor())
.addPathPatterns("/**");
registry.addInterceptor(brushProofIterceptor())
.addPathPatterns("/**");
}