Nginx HTTP模块篇 access阶段的deny allow auth_basic auth_request指令 (十三)-张柏沛IT博客

正文内容

Nginx HTTP模块篇 access阶段的deny allow auth_basic auth_request指令 (十三)

栏目:Linux 发布时间:2020-02-15 20:48 浏览量:322

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指令 (十三)

热门推荐
推荐新闻