技术一直在变革,老的技术一般都会成为现在的技术债,加上早期大家一般对于安全不是很重视(尤其是在内网环境的时候),尽管webservice 是包含了ws-security 安全指南的,但是很多时候大家不是很重视(而且这个规范稍晚),以下是一个简单的实践
参考图
原理简单说明
核心还是利用了openresty 的阶段处理能力,为了减少业务改造的成本我们可以直接使用影响小的基于header 以及基于ip 防护的处理策略
简单实践
- 环境准备
docker-compose.yaml
version: '3'
services:
app:
image: openresty/openresty:1.21.4.1-3-alpine-fat
volumes:
- "./nginx.conf:/usr/local/openresty/nginx/conf/nginx.conf"
ports:
- "80:80"
nginx.conf 配置
user root;
worker_processes 1;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
'$http_token';
include mime.types;
default_type application/octet-stream;
gzip on;
rewrite_log on;
real_ip_header X-Forwarded-For;
server {
listen 80;
charset utf-8;
default_type text/html;
location / {
access_by_lua_block {
-- 请求必须携带token,包括wsdl 文件,以及后续操作,实际可以集合认证机制
if ngx.req.get_headers()["token"] == nil then
ngx.exit(ngx.HTTP_FORBIDDEN)
end
}
access_log logs/access2.log main;
sub_filter http:// 'http://localhost';
sub_filter_types text/xml;
sub_filter_once off;
proxy_set_header Accept-Encoding '';
# 注意使用一个开放的webservice
proxy_set_header Host ;
proxy_set_header X-Forwarded-For $remote_addr;
client_body_buffer_size 10M;
proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 10G;
proxy_buffers 1024 4k;
proxy_read_timeout 300;
proxy_pass http://;
}
}
}
- api 调用使用了nodejs 的soap 包
var soap = require('soap');
var url = 'http://localhost/calculator.asmx?wsdl';
var args = {intA: 2,intB:3};
soap.createClient(url, {
wsdl_options:{
headers: {'token': 'mytoken'}, // wsdl 携带token
}
}, function(err, client) {
console.dir(client)
client.addHttpHeader("token","mytoken") // 请求携带token
client.Add(args, function(err, result) {
console.log(result.AddResult);
});
});
- 效果
直接访问(因为没有token 会被拦截)
nginx 请求日志,包含了一个get 以及一个post 请求
node 应用效果
说明
以上是一个简单的集成,同时包含了如何使用nginx 进行webservice 的代理(核心是sub_filter 指令),对于webservice 的安全实际上问题还是不少的,可以参考
基于ip也是一种模式,header 各种语言的基本都是可以支持的,难度不大