Nginx配置:如果没有提供ssl_client_certificate,如何使用auth_basic身份验证?

时间:2014-05-17 22:15:10

标签: authentication drupal nginx config

我试图按如下方式设置Nginx服务器:

首先,服务器应检查用户是否提供客户端SSL证书(通过 ssl_client_certificate )。 如果提供了SSL证书,则允许访问该站点,

如果未提供SSL证书,请要求用户输入密码并通过 auth_basic 进行登录。

我能够同时配置身份验证方法 。但是这个配置是多余的。

要检查,用户是否提供其SSL证书,我尝试这样的配置:

18:    if ($ssl_client_verify != SUCCESS) {
19:        auth_basic "Please login";
20:        auth_basic_user_file .passfile;
21:    }

但Nginx会返回错误:

  

" auth_basic"这里不允许使用指令... / ssl.conf:19

在这种情况下如何设置条件?

5 个答案:

答案 0 :(得分:10)

您可以在auth_basic子句中设置if配置,如下所示:

server {
    listen 443;
    auth_basic_user_file    .htpasswd;
    ssl_client_certificate  ca.cert;
    ssl_verify_client       optional;
    ...

    location / {
      ...

      if ($ssl_client_verify = SUCCESS) {
        set $auth_basic off;
      }
      if ($ssl_client_verify != SUCCESS) {
        set $auth_basic Restricted;
      }

      auth_basic $auth_basic;
    }
}

现在,如果没有提供客户端证书(或验证失败),身份验证将回退到HTTP Basic。

答案 1 :(得分:4)

我目前无法对此进行测试,但是这样会有效吗?

server {
    listen 80;
    server_name www.example.com example.com;
    rewrite ^ https://$server_name$request_uri? permanent;
}
server {
    listen 443;
    ...

    if ($ssl_client_verify != SUCCESS) {
        rewrite ^ http://auth.example.com/ permanent;
    } 
    location / {
        ...
    }

}
server {
    listen 80;
    server_name auth.example.com;
    location / {
        auth_basic "Please login";
        auth_basic_user_file .passfile;
    }
} 

所以基本上:
- 接受所有初始请求(在端口80上显示您正在使用的任何名称)并重写为ssl
- 检查客户端是否已经过验证 - 如果不是,请重写为使用基本身份验证的备用域

就像我说的那样,我现在无法测试它,但我会尝试解决它!如果有帮助,请告诉我,我很有兴趣看看它是否有效。

答案 2 :(得分:3)

当客户端证书失败时,Nginx无法回退到基本身份验证。作为替代方案,您可以使用变量来限制访问:

location / { 
  if ($ssl_client_verify = "SUCCESS") {
    set $authorized 1;
  }
  if ($authorized != 1) {
    error_page 401 @basicauth;
    return 401;
  }
}

location @basicauth {
  auth_basic "Please login";
  auth_basic_user_file .passfile;
  set $authorized 1;
  rewrite /(.*) /$1;
}

*请注意IfIsEvil这些规则可能无法正常工作或干扰较大配置的其他部分。

答案 3 :(得分:1)

忘记它,它将无效。

失败的原因是因为if不是人们应该相信的一般配置模块的一部分。 if是重写模块的一部分,auth_basic是另一个模块。你不能拥有带有基本身份验证的动态虚拟主机。

另一方面......

您可以拥有带有自己错误页面的动态虚拟主机。以下示例是为自定义404页面设计的,但您可以将其实现到代码中。

server {
    listen 80;
    server_name _;

    set $site_root /data/www/$host;

    location / {
        root $site_root;
    }

    error_page 404 =404 /404.html;

    location /404.html {
        root $site_root/error_files;
        internal;

        error_page 404 =404 @fallback_404;
    }

    location @fallback_404 {
        root /var/www/;
        try_files /404.html =404;
        internal;
    }

    error_log  /var/log/nginx/error.log  info;
    access_log  /var/log/nginx/access.log;
}

会发生什么......

  • 您告诉Nginx在/404.html
  • 的情况下使用HTTP_NOT_FOUND
  • 更改位置root以匹配网站error_pages目录。
  • 内部重定向
  • 返回404 http代码
  • location @fallback_404中配置后备404页面:在此位置,root已更改为/var/www/,因此它将从该路径而不是$site_root中读取文件
  • 在最后阶段,如果代码存在404 http代码,则代码返回/var/www/404.html

注意:根据Nginx文档:

  

指定给定位置只能用于内部   要求。对于外部请求,客户端错误404(未找到)是   回。内部请求如下:

     
      
  • 由error_page,index,random_index和try_files指令重定向的请求;
  •   
  • 来自上游服务器的“X-Accel-Redirect”响应头字段重定向的请求;
  •   
  • 由ngx_http_ssi_module模块的“include virtual”命令和ngx_http_addition_module模块形成的子请求   指令;
  •   
  • 请求由重写指令更改。
  •   

此外:

  

每个请求都有10个内部重定向限制以防止   请求在错误配置中发生的处理周期。   如果达到此限制,则错误500(内部服务器错误)为   回。在这种情况下,“重写或内部重定向周期”   消息可以在错误日志中看到。

点击this link了解更多信息,希望有所帮助。

答案 4 :(得分:0)

您可以尝试使用地图。

map $ssl_client_verify $var_auth_basic {
   default off;
   SUCCESS "Please login";
}

server {
   ....
   auth_basic $var_auth_basic;
   auth_basic_user_file .passfile;

这样,该值取决于 $ssl_client_verify 但始终是 alsa 定义的,并且 auth_basicauth_basic_user_file 始终位于 server { 块内。