① 基本描述
- 场景: 限制某些'ip来源'的访问;基于'ip'进行限制
-
- 细节点: 基于'$remote_addr'进行判断的
③ 官方案例
说明: 按照配置文件中'allow|deny'的先后顺序,只要匹配上则'停止'继续匹配
④ 经典应用场景
- +++++++++++ '只允许192.168.1.100访问,其余都拒绝' +++++++++++
-
- allow 192.168.1.100;
-
- deny all;
-
- +++++++++++ '只拒绝192.168.1.100访问,其余都允许' +++++++++++
-
- deny 192.168.1.100;
-
- allow all;
⑤ 补充
补充: 'ip被禁止'之后会返回'403'状态码
① 基本描述
- 说明:校验'username'和'passwd'是否匹配,来决定'是否'拒绝访问
-
- 特点: nginx 基于'文件列表进行'认证
-
- 注意: openresty默认'没有'将http_auth_basic_module'编译'进去
④ 交互原理
说明:如果是'http'协议就是'明文'传输的,建议使用'https'
⑤ 密码文件生成
- 1)使用htpasswd生成密码 -->'最简单(增删改),但是系统不一定有httpd-tools工具'
-
- 2)使用openssl生成密码 -->'推荐'
-
- 3)使用python生成密码 -->'了解'
-
- 备注: 密码文件最好以'隐藏'文件的形式,并注意'权限'和'属性'
1)openssl passwd
2)htpasswd
- 细节点:htpasswd的密码文件'不是base64编码'
-
- 密码文件:建议命名格式'.basic_auth.db'
⑥ 典型应用场景
- 1)背景:只要用户在浏览器输入,就可以访问监控页面;这样'很不安全',因为任何人都可以'访问'这个页面
-
- 2)是否可以再添加一个'授权模块'呢?监控nginx服务器'运行情况'的模块
⑦ 案例讲解
说明: 本文以'变量'的形式,只是告诉'可以'这样用,要根据'具体场景'使用
1)未使用变量可能存在500的报错
2)使用变量,但实际密码文件不存在报错403
3)案例3
4)正常浏览器访问
细节点: 清除'历史'的登陆记录 -->'ctrl+shift+delete'
5)通过Authorization请求头进行认证
① 概述
- 使用'第三方'做权限控制: 提供更'复杂'的用户密码权限验证 --> "解耦"
-
- 细节点: 对于'子请求返回的401'错误,客户端还从'子请求响应'中接收"WWW-Authenticate"响应头
-
- 补充: auth_request'支持grpc、ws'等协议
-
- 附加: rpm安装默认'没有'编译'auth_request'模块
- 生成一个'子请求',这个子请求会'访问这个uri'
-
- 特点: 子请求是'GET'请求,会携带客户端原始的'请求'信息,例如'Cookie头'
-
- 场景: 多个项目下部署'统一的权限接口时'还是有用的
- 应用场景1: 把上游'认证失败的原因'记录到内部日志中,对外'统一'用固定的页面展示
-
- 应用场景2: 提取上游'响应头中的 [例如响应头]'信息,保存为'变量',然后供'proxy_paas'使用
-
- 例如:鉴权中心给'鉴权'的同时返回一个'访问'地址,通过'auth_request_set'补获,proxy_pass转发
-
- 效果:相当于在'auth_request'模块作用的'access'阶段set一个'变量',透传给后续的'请求阶段'
- value主要来'三方面': 客户端的'请求'信息、'子请求响应'的信息、'其它'自定义信息
-
- 题外话: 401是'未鉴权',403是'鉴权失败'
auth_request 模块集成 LDAP 认证 了解原理
auth_request 补获subrequest 401 重新login
④ 案例讲解
1)源码编译
2)nginx配置
- 工作原理:
-
- 1) 在匹配'location /private/'后,会执行'auth_request /auth'子请求
-
- 备注:会'携带'原始客户端的'请求信息[特别是请求头的Cookie,这里不探讨请求参数和请求体]'
-
- 补充:建议在'该部分'设置error_page 401 = @error_401;
-
- 2) 继续匹配'location = /auth',建议'该location 块'如下设置:
-
- proxy_set_header Host $host;
-
- proxy_pass_request_body off; 不将客户端的请求体发送给'上游服务器'
-
- proxy_set_header Content-Length "";
-
- 原因:
-
- 1、auth 子请求是通过 HTTP 'GET 方法'发送的,一般是'没有'请求体
-
- 2、为'避免'挂起,Content-Length 标头设置为'空'字符串
-
- 备注: 可在该location块,'设置' prxy_set_header 传递给proxy_pass'第三方'认证服务器
-
- 补充: 建议在该部分增加'internal;'
-
- 3) 返回到'location /private/'中的'auth_request_set'获取相关信息
-
- 1、如果'401',nginx拦截,返回到'named location',进行login登陆认证
-
- 2、如果'2xx',进行'该location块'的proxy_paas进行'业务'处理
-
- 备注:该'proxy_paas'可以使用'auth_request_set'的变量或'location /private/'set变量
3)第三方认证服务器配置1
4)认证服务器配置2
⑤ 搜集的案例汇总
携带Content-Length请求头导致auth_request不生效
⑥ 补充解读
- [1]、可以帮助我们实现对资源的'统一'权限验证,这在'微服务'中非常有用
-
- [2]、可以实现自己的权限认证服务,将所有的资源的请求都'通过权限认证服务后'再处理,提高系统安全性
-
- [3]、但同时会增加请求的'响应'时间,因为此时每次请求都会发起'两次'http调用
⑦ 相关的思考
① 基本概述
② 指令解读
- 场景:
-
- 如果用了'多个http模块'做access访问控制的话,并且需要做"与&"以及"或"这种逻辑操作时,才用得上的
③ 思考1
解读: 不会生效,因为'return'是rewrite阶段,在access之前
④ 思考2
⑤ 思考3
说明: 'allow all'属于access_module,'优先级'最高
⑥ 补充
遗留:还有哪些'第三方'的access模块