Authentication Nginx config:如果未提供ssl\u客户端\u证书,如何使用auth\u基本身份验证?

Authentication Nginx config:如果未提供ssl\u客户端\u证书,如何使用auth\u基本身份验证?,authentication,drupal,nginx,config,Authentication,Drupal,Nginx,Config,我正在尝试按如下方式设置Nginx服务器: 首先,服务器应检查用户是否提供了客户端SSL证书(通过SSL\U客户端\U证书)。 如果提供了SSL证书,则允许访问站点 如果未提供SSL证书,请要求用户输入密码并通过auth_basic登录 我能够同时配置这两种身份验证方法。但这种配置是多余的 为了检查用户是否提供了SSL证书,我尝试如下配置: 18: if ($ssl_client_verify != SUCCESS) { 19: auth_basic "Please logi

我正在尝试按如下方式设置Nginx服务器:

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

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

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

为了检查用户是否提供了SSL证书,我尝试如下配置:

18:    if ($ssl_client_verify != SUCCESS) {
19:        auth_basic "Please login";
20:        auth_basic_user_file .passfile;
21:    }
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;
    }
}
但是Nginx返回一个错误:

此处不允许在…/ssl.conf:19中使用“auth_basic”指令


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

算了吧,它不起作用。

它失败的原因是因为
if
不是人们应该相信的通用配置模块的一部分<代码>如果是重写模块的一部分,
auth_basic
是另一个模块。您不能使用带有基本身份验证的动态vhost

另一方面 您可以使用动态虚拟主机及其自己的错误页面。下面的示例是为自定义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在HTTP\u找不到的情况下使用
    /404.html
  • 更改位置
    根目录
    以匹配网站
    错误页面
    目录
  • 内部重定向
  • 返回404HTTP代码
  • location@fallback\u 404
    中配置回退404页面:在该位置,
    root
    更改为
    /var/www/
    ,因此它将从该路径而不是
    $site\u root
    读取文件
  • 在最后一个阶段,如果存在404 http代码,代码将返回
    /var/www/404.html
注:根据Nginx文件:

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

  • 错误页面、索引、随机索引和重试文件指令重定向的请求
  • “X-Accel-Redirect”响应头字段从上游服务器重定向的请求
  • 由ngx_http_ssi_模块的“include virtual”命令和ngx_http_addition_模块形成的子请求 指令
  • 重写指令更改的请求
此外:

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


查看更多信息,希望对您有所帮助。

我目前无法测试此功能,但是否需要此功能

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
-检查是否存在验证客户端的错误。
-如果没有,请重写到使用基本身份验证的备用域


就像我说的,我现在不能测试它,但我会尽力去做!让我知道它是否有用,我很想看看它是否有效。

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;
}

*请记住,这些规则可能工作不正确或干扰较大配置的其他部分。

您可以在
if
子句中设置
auth\u basic
配置,如下所示:

18:    if ($ssl_client_verify != SUCCESS) {
19:        auth_basic "Please login";
20:        auth_basic_user_file .passfile;
21:    }
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。

您可以尝试使用映射

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

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

这样,该值取决于
$ssl\u client\u verify
,但也始终是定义的,
auth\u basic
auth\u basic\u user\u文件始终在
服务器内{
block.

hi pavel,你做过你想做的事吗?我也有同样的问题…我得到了你的主意。谢谢!赏金是你的)对此很好奇,你有没有让它工作过?上面的实现工作吗?