access 阶段
11个阶段中经过的模块
allow 指令 和 deny 指令
用于限制某些IP的访问
上下文:http,server,location,limit_except
示例:
location / {
deny 192.168.5.100;
deny 192.168.5.0/24; # 限制IP段
deny all;
allow 192.168.5.3; # 限制了192.168.5这个IP段,但是允许192.168.5.2
}
allow和deny是顺序执行的,后者会覆盖前者。
auth_basic 模块
可用于简单的用户验证
auth_basic string|off; # 默认off
auth_basic_user_file file; # 指定用户名和密码所在的文件
上下文:http,server,location,limit_except
这个用户密码文件要使用 httpd-tools 命令生成,如果安装了Apache,这个模块默认存在。
yum install -y httpd-tools
htpasswd -bc 文件名 用户名 密码 # 创建文件并写入用户密码
htpasswd -b 文件名 用户名 密码 # 在已有的文件中添加一个用户
一个文件可以有多个用户名和密码。
该用户验证基于cookie,只要输入一次就可以不用再输。
小实验:
htpasswd -bc /var/www/html/auth.pass zbp 123456
htpasswd -b /var/www/html/auth.pass yf 123456
server {
listen 8080;
server_name limit.zbpblog.com;
root /var/www/html;
# error_log /var/www/html/error.log info;
location / {
#auth_basic "Auth check"; # 验证的页面的title叫做"Auth check",同时表示开启验证。
#auth_basic_user_file /var/www/html/auth.pass;
}
#location /test.html {
# auth_basic "Auth check";
# auth_basic_user_file /var/www/html/auth.pass;
#}
location ~ ^/test/?$ {
auth_basic "Auth check";
auth_basic_user_file /var/www/html/auth.pass;
rewrite /test/? /test.html break;
}
}
测试结果:
如果在 location / 添加auth验证,则所有页面都要输入账号密码。
如果 只在location /test.html 添加auth验证,只有/test.html要输入账号密码。
如果涉及到重定向:例如location ~ ^/test/?$ 只要是 /test或者/test/就可以进入该location,此时我想重定向到/test.html,而且验证密码。
此时要将跳转放到auth_basic命令之后,而且使用break。否则不会验证。原因是,不使用break,重定向后为/test.html就会重新匹配到location /,而location /中没有auth_basic指令,此时就不会进行验证。要知道 rewrite指令是在11个阶段中的rewrite阶段,而auth_basic是在access阶段,肯定是要等rewrite阶段执行完了才会去执行access阶段的auth_basic的。
auth_request 模块 使用上游服务做验证
该模块默认未编译进Nginx:--with-http_auth_request_module
auth_request uri|off; # uri就是验证页面的路径
auth_request_set $variable value;
原理:
例如我要访问A服务。
A收到请求后,生成一个一模一样的子请求通过反向代理将请求传给上游服务B,这个上游服务B就是专门用来验证的。
若上游服务B返回响应码为2xx,则返回继续请求A服务的内容;如果上游服务返回403或401,则将401/403返回给客户端。
小实验:
访问 http://limit.zbpblog.com:8080,但要经过验证才可以访问。
先编译auth_request模块
server {
listen 8080;
server_name limit.zbpblog.com;
root /var/www/html;
location / {
auth_request /auth;
}
location /auth {
proxy_pass http://127.0.0.1:8090/auth;
proxy_pass_request_body off;
proxy_set_header Content-Length ""; # 请求体为空
proxy_set_header X-Original-URI $request_uri; # 注明客户端请求的URI
}
}
server {
listen 8090;
location /auth {
return 200 "OK";
#return 401 "Auth Fail";
}
}
上面访问 http://limit.zbpblog.com:8080 成功;
修改第二个server,改为return 401 "Auth Fail";再访问一次http://limit.zbpblog.com:8080,验证失败。
satisfy指令
satisfy all|any; 默认all
satisfy all;
表示 只要 access模块(如deny命令)、auth_basic模块、auth_request模块以及其他模块 全都 对请求放行才能真的放行。
any 只要有一个放行就对该请求放行。
问题:如果一个location中使用了return指令和auth_basic指令,而且auth_basic在return之前,请问是否会进行验证?
答:不会。因为return是rewrite模块的指令,属于11个阶段中的rewrite阶段。而auth_basic是属于access阶段,rewrite阶段的指令会先执行,无论return和auth_basic指令在配置文件中出现的顺序如何,都是return先执行。return执行就会中断后面所有代码的执行。
问题2:
location /{
satisfy all;
auth_basic "auth";
auth_basic_user_file auth.pass;
deny all;
}
请问有机会输入用户密码进行验证码?
答:没有,因为使用了satify all,只要有一个不放行就都不放行,而deny属于access模块,在流程图中先于auth_basic模块运行,在access模块就拒绝了请求,就不会再执行auth_basic。
如果改为 satify any,还是可以输入密码的,而且密码如果输对了,就可以无视deny all通过请求。
如果您需要转载,可以点击下方按钮可以进行复制粘贴;本站博客文章为原创,请转载时注明以下信息
张柏沛IT技术博客 > Nginx HTTP模块篇 access阶段的deny allow auth_basic auth_request指令 (十三)