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

问题描述 投票:0回答:5

我正在尝试按如下方式设置 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 返回错误:

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

这种情况我该如何设置条件?

authentication drupal nginx config
5个回答
34
投票
您可以在

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。


5
投票
您可以尝试使用地图。

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_basic
auth_basic_user_file
 始终位于 
server {
 块内。


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

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


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和这些规则可能无法正常工作或干扰较大配置的其他部分。


2
投票
算了,

不行。

它失败的原因是因为

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(内部服务器错误) 回来了。在这种情况下,“重写或内部重定向周期” 可以在错误日志中看到消息。

查看

此链接了解更多信息,希望有帮助。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.