-
Notifications
You must be signed in to change notification settings - Fork 0
4. 安全&拦截
项目运行起来之后怎么防止非法用户访问我们的资源,这里一般分为内网资源和公网资源
-
1.内网资源
内网资源只能由内网机器或者服务访问,我们一般可以在资源上添加过滤器,过滤掉外网ip地址,或者访问的时候携带某个key,然后验证key的有效性,有效则放行
添加过滤器的方式我就不在这里讲了,本文档主要讲的是服务A通过openfeign的方式调用服务B,网站怎么知道服务A有权限
项目中采用的方案比较简单,直接在配置文件配置token,让请求的header携带这个token,网关的过滤器验证token的合法性
1.1 在feign的参数里面“defaultRequestHeaders”新增一个authToken
feign: client: config: default: connectTimeout: 6000000 # 相当于Request.Options readTimeout: 6000000 # 相当于Request.Options defaultRequestHeaders: authToken: EbDcwcLG3zfGdiHFFzSQbbf4Y1epwOK14wRGvqt8BmYbW0FpWKY
1.2 网关过滤器验证authToken的合法性
@Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); String path = request.getPath().toString(); var authToken = request.getHeaders().get("authToken"); if(Contants.isInOpenFeignServices(path)){ if(authToken != null && authToken.size() > 0 && Contants.openFeignAuthToken.equals(authToken.get(0))){ //放行 return chain.filter(exchange); } //拒绝 ServerHttpResponse response = exchange.getResponse(); response.setStatusCode(HttpStatus.NOT_ACCEPTABLE); //这个状态码是406 return exchange.getResponse().setComplete(); } //其它是web服务,都放行,交给其它过滤器继续过滤 return chain.filter(exchange); }
这个方式有一个弊端,authToken是永久有效的,下一步需要用auth2的方式申请token
1.3 控制feign接口的访问路径
例如:web可以访问server1和server2,server1不能访问server2,但是server2不能访问server1(这个可以在网关层调整)
第一步:RequestTemplate增加相应的header
@Override public void apply(RequestTemplate template) { // 携带token到Feign的服务端 template.getRequestVariables(); template.header("Authorization", "chainTokenValue"); //在网关层用来控制资源访问路径,比如:web可以访问server1和server2,但是server2不能访问server1(这个可以在网关层调整) template.header("ApplicationName", applicationName); }
第二步:网关层过滤
var applicationNameHeader = request.getHeaders().get("ApplicationName"); String applicationName = applicationNameHeader != null && applicationNameHeader.size() > 0 ? applicationNameHeader.get(0) : ""; boolean appHasRight = Contants.havaRight(applicationName, path); if(appHasRight){ //放行 return chain.filter(exchange); }
-
2.公网资源
公网资源需要阻止某些非法用户、爬虫等对服务器资源的占用或者执行非法资源
我的思路是这样的:在数据库配置相应规则,例如某个ip,或者useragent携带某个参数,网关过滤器读取配置,然后验证相应的规则,如果包含在规则里面就阻止通过,以下是过滤器相关代码:
@Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { log.info("ServerGatewayFilter filter "); HttpHeaders headers = exchange.getRequest().getHeaders(); String userAgent = headers.get("User-Agent").toString(); if(userAgent.indexOf("spider") < 0){ return chain.filter(exchange); // 放行 } return null; }
过滤器比较简单,仅仅读取User-Agent是否包含spider。
有没发现filter跟我们常见的不一样,它的返回值是Mono<Void>类型,这是因为gateway采用的WebFlux,WebFlux是一个典型非阻塞异步的框架,它的核心是基于Reactor的相关API实现。
((*以上内容代码只贴了部分,全部代码都在项目中*))
@fancie 整理
有疑问联系:108491@qq.com