Nginx + htpasswd实现基于用户认证的访问控制

 更新时间:2026年07月14日 09:18:49   作者:知远漫谈  
在现代 Web 应用架构中,安全永远是第一位的,基于用户名和密码的访问控制(Basic Authentication)依然是最简单、最可靠、最广泛支持的防护手段之一,本文将带你从零开始,深入理解 Nginx + htpasswd 的完整配置流程,需要的朋友可以参考下

引言

在现代 Web 应用架构中,安全永远是第一位的。无论你的服务是内部管理后台、测试环境、API 网关,还是仅限特定团队访问的文档系统,基于用户名和密码的访问控制(Basic Authentication)依然是最简单、最可靠、最广泛支持的防护手段之一。而 Nginx 作为高性能的反向代理服务器和 Web 服务器,内置了对 HTTP Basic Auth 的原生支持,配合 htpasswd 工具,我们可以快速搭建一套无需数据库、无需复杂框架、开箱即用的身份验证系统。

本文将带你从零开始,深入理解 Nginx + htpasswd 的完整配置流程,涵盖原理剖析、工具使用、配置细节、常见陷阱、Java 后端联动、自动化脚本、性能优化、日志审计、安全加固等多个维度。你将不仅学会“怎么配”,更明白“为什么这么配”。文末还会提供 Java 代码示例,展示如何在 Spring Boot 应用中优雅地配合 Nginx 认证机制,实现前后端协同的安全策略。

一、什么是 HTTP Basic Authentication?

HTTP Basic Authentication(HTTP 基本身份验证)是 HTTP 协议定义的一种简单认证机制。它的工作原理非常直接:

  1. 客户端(浏览器、curl、Postman 等)向服务器请求受保护资源。
  2. 服务器返回 401 Unauthorized 响应,并在 WWW-Authenticate 头中声明需要 Basic 认证。
  3. 客户端弹出登录框(浏览器)或由程序自动构造 Authorization 头。
  4. 客户端将用户名和密码拼接为 username:password,使用 Base64 编码后放入 Authorization: Basic <encoded> 头中发送。
  5. 服务器解码该头,比对用户名密码是否匹配预设凭证。
  6. 匹配成功则返回资源;失败则再次返回 401。

注意:Basic Auth 本身不加密!Base64 只是编码,不是加密。明文密码在传输中是可见的。因此,必须配合 HTTPS 使用,否则等于裸奔。

二、htpasswd 是什么?

htpasswd 是 Apache HTTP 服务器附带的一个命令行工具,用于创建和管理存储用户名和加密密码的文件。虽然它源自 Apache,但其生成的文件格式(username:encrypted_password)被 Nginx 完全兼容,因此成为 Nginx Basic Auth 的事实标准凭证文件。

htpasswd 文件格式示例:

alice:$apr1$H6sK3j4q$JkLmNoPqRsTuVwXyZ12345
bob:$apr1$K9pL2mNn$AbCdEfGhIjKlMnOpQrStUvWx

每一行代表一个用户,格式为:

用户名:加密后的密码

密码使用 MD5$apr1$ 前缀)或 SHA-1bcrypt(取决于编译选项)加密,不会明文存储,安全性较高。

重要:Nginx 不解析 .htaccess,只读取 htpasswd 文件。所以你不需要 Apache 的 .htaccess 文件,只需一个 htpasswd 文件即可。

三、安装与生成 htpasswd 文件

3.1 在 Linux 系统中安装 htpasswd

大多数 Linux 发行版都自带 Apache 工具包,htpasswd 已包含在内。

Ubuntu / Debian:

sudo apt update
sudo apt install apache2-utils

CentOS / RHEL / Fedora:

sudo yum install httpd-tools
# 或者在较新版本中
sudo dnf install httpd-tools

安装完成后,验证是否可用:

htpasswd -h

输出应包含帮助信息。

3.2 创建第一个用户

假设我们要为管理后台创建一个用户 admin,密码为 MySecurePass123!

sudo htpasswd -c /etc/nginx/.htpasswd admin
  • -c 表示创建新文件(如果文件已存在,会被覆盖!)
  • 路径 /etc/nginx/.htpasswd 是推荐位置,便于 Nginx 配置引用
  • 系统会提示你输入密码两次

建议:使用强密码,包含大小写字母、数字、特殊字符,长度至少 12 位。

3.3 添加更多用户

添加第二个用户 dev,不覆盖原文件:

sudo htpasswd /etc/nginx/.htpasswd dev

注意:不再使用 -c,否则会清空原有用户!

查看文件内容:

cat /etc/nginx/.htpasswd

输出:

admin:$apr1$R5t3v7x8$Z9aBcDeFgHiJkLmNoPqRsT
dev:$apr1$X2y4z6w8$QwErTyUiOpAsDfGhJkLzMn

3.4 删除用户

若需删除某个用户:

sudo htpasswd -D /etc/nginx/.htpasswd dev

-D 表示 Delete,执行后该用户行将被移除。

3.5 重置密码

只需再次运行添加命令,即可覆盖旧密码:

sudo htpasswd /etc/nginx/.htpasswd admin

系统会提示输入新密码,旧密码自动被替换。

四、Nginx 配置 Basic Auth

现在我们有了 htpasswd 文件,接下来配置 Nginx 来启用认证。

4.1 编辑 Nginx 配置文件

通常配置文件位于:

  • Ubuntu/Debian:/etc/nginx/sites-available/default
  • CentOS/RHEL:/etc/nginx/nginx.conf/etc/nginx/conf.d/default.conf

我们以一个典型的站点配置为例:

server {
    listen 80;
    server_name admin.example.com;
    # 强制跳转 HTTPS(强烈推荐!)
    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl;
    server_name admin.example.com;
    # SSL 证书配置(请替换为你的实际路径)
    ssl_certificate /etc/ssl/certs/admin.example.com.crt;
    ssl_certificate_key /etc/ssl/private/admin.example.com.key;
    # 安全增强:启用 HSTS
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    # 网站根目录
    root /var/www/admin;
    index index.html index.htm;
    # 启用 Basic Auth
    auth_basic "Restricted Access";
    auth_basic_user_file /etc/nginx/.htpasswd;
    # 只允许特定路径受保护
    location / {
        try_files $uri $uri/ =404;
    }
    # 也可以只保护特定目录,例如 /api
    # location /api {
    #     auth_basic "Admin API";
    #     auth_basic_user_file /etc/nginx/.htpasswd;
    #     proxy_pass http://localhost:8080;
    # }
}

4.2 配置说明详解

指令说明
auth_basic "Restricted Access";设置弹出框提示文字,用户看到的认证提示信息。可自定义,如 "Internal Dashboard"
auth_basic_user_file /path/to/.htpasswd;指定凭证文件路径。必须是绝对路径,Nginx 不支持相对路径

⚠️ 重要警告:确保 .htpasswd 文件权限安全!

sudo chmod 640 /etc/nginx/.htpasswd
sudo chown root:www-data /etc/nginx/.htpasswd

避免让 nginx 进程以外的用户可读!

4.3 测试配置并重启 Nginx

# 检查语法是否正确
sudo nginx -t

# 重载配置(不中断服务)
sudo systemctl reload nginx

# 或重启(如需完全重启)
sudo systemctl restart nginx

现在访问 https://admin.example.com,浏览器会弹出登录框

输入 admin 和你设置的密码,即可进入。

五、Java 后端如何配合 Nginx 认证?

虽然 Nginx 执行了认证,但你的 Java 应用(如 Spring Boot)并不知道用户是谁。为了让后端服务知道“谁在访问”,我们需要利用 Nginx 的 X-Remote-User 头传递认证信息。

5.1 修改 Nginx 配置:传递用户信息

location 块中添加:

location / {
    auth_basic "Restricted Access";
    auth_basic_user_file /etc/nginx/.htpasswd;
    # 传递认证用户名给后端 Java 应用
    proxy_set_header X-Remote-User $remote_user;
    proxy_pass http://localhost:8080;
    # 其他代理配置
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

$remote_user 是 Nginx 内置变量,当 Basic Auth 成功后,它会自动包含已认证的用户名。

5.2 Java Spring Boot 接收用户名

在 Spring Boot 控制器中,我们可以从请求头中读取 X-Remote-User

package com.example.demo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.Optional;
@RestController
public class DashboardController {
    @GetMapping("/api/user")
    public User getCurrentUser(@RequestHeader(value = "X-Remote-User", required = false) String remoteUser,
                               HttpServletRequest request) {
        // 方法一:通过 @RequestHeader
        String username = Optional.ofNullable(remoteUser)
                .filter(u -> !u.trim().isEmpty())
                .orElse("anonymous");
        // 方法二:从 HttpServletRequest 获取(更安全)
        String headerUser = request.getHeader("X-Remote-User");
        if (headerUser != null && !headerUser.trim().isEmpty()) {
            username = headerUser;
        }
        return new User(username, System.currentTimeMillis(), request.getRemoteAddr());
    }
    @GetMapping("/api/health")
    public String health() {
        return "OK - Authenticated via Nginx";
    }
}
// 简单数据类
class User {
    private String username;
    private long loginTime;
    private String ipAddress;
    public User(String username, long loginTime, String ipAddress) {
        this.username = username;
        this.loginTime = loginTime;
        this.ipAddress = ipAddress;
    }
    // Getters
    public String getUsername() { return username; }
    public long getLoginTime() { return loginTime; }
    public String getIpAddress() { return ipAddress; }
    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", loginTime=" + loginTime +
                ", ipAddress='" + ipAddress + '\'' +
                '}';
    }
}

5.3 测试接口

启动 Spring Boot 应用(监听 8080),然后通过浏览器访问:

https://admin.example.com/api/user

你会看到:

{
  "username": "admin",
  "loginTime": 1712345678901,
  "ipAddress": "192.168.1.100"
}

成功!后端已获取到 Nginx 认证的用户名,可用于日志记录、权限控制、审计等。

5.4 安全增强:后端校验头来源

⚠️ 重要:不能完全信任客户端传来的 X-Remote-User!攻击者可能伪造该头。

所以,只应在 Nginx 层面设置该头,并在后端做来源校验:

@GetMapping("/api/user")
public User getCurrentUser(HttpServletRequest request) {
    String remoteUser = request.getHeader("X-Remote-User");
    // 校验:只有来自本地 Nginx 的请求才可信
    String clientIp = request.getRemoteAddr();
    if (!"127.0.0.1".equals(clientIp) && !"::1".equals(clientIp)) {
        throw new SecurityException("X-Remote-User header is not allowed from external requests");
    }
    if (remoteUser == null || remoteUser.trim().isEmpty()) {
        throw new SecurityException("Authentication required");
    }
    return new User(remoteUser.trim(), System.currentTimeMillis(), clientIp);
}

这样,即使外部攻击者伪造 X-Remote-User: admin,Nginx 也不会传递它,因为只有从 127.0.0.1 来的请求才会被代理,而本地代理是受控的。

六、进阶:多用户、多角色、分路径授权

有时我们需要:

  • /admin 路径:仅 admin 用户可访问
  • /api 路径:admindev 都可访问
  • /docs 路径:仅 dev 用户可访问

Nginx 支持通过 map 指令实现灵活的路径+用户组合控制。

6.1 使用 map 定义用户组

http 块中(通常在 nginx.conf 顶部):

http {
    map $remote_user $allowed_user {
        default 0;
        admin 1;
        dev 1;
    }
    map $request_uri $auth_required {
        default 0;
        ~^/admin/ 1;
        ~^/docs/ 1;
        ~^/api/ 1;
    }
    server {
        listen 443 ssl;
        server_name admin.example.com;
        ssl_certificate /etc/ssl/certs/admin.example.com.crt;
        ssl_certificate_key /etc/ssl/private/admin.example.com.key;
        root /var/www/admin;
        index index.html;
        location / {
            # 如果是受保护路径,且当前用户不在允许列表中,则要求认证
            if ($auth_required = 1) {
                auth_basic "Restricted Area";
                auth_basic_user_file /etc/nginx/.htpasswd;
            }
            try_files $uri $uri/ =404;
        }
        # 明确保护 /admin
        location /admin {
            auth_basic "Admin Only";
            auth_basic_user_file /etc/nginx/.htpasswd;
            # 可以进一步限制:只允许 admin 用户
            if ($remote_user != "admin") {
                return 403;
            }
            proxy_pass http://localhost:8080;
        }
        # 保护 /docs,允许 admin 和 dev
        location /docs {
            auth_basic "Docs Access";
            auth_basic_user_file /etc/nginx/.htpasswd;
            proxy_pass http://localhost:8080;
        }
        # 保护 /api,允许 admin 和 dev
        location /api {
            auth_basic "API Access";
            auth_basic_user_file /etc/nginx/.htpasswd;
            proxy_set_header X-Remote-User $remote_user;
            proxy_pass http://localhost:8080;
        }
    }
}

6.2 Java 后端实现角色校验

在 Java 中,我们可以根据用户名做角色判断:

@GetMapping("/api/admin/dashboard")
public String adminDashboard(@RequestHeader("X-Remote-User") String user) {
    Set<String> adminUsers = Set.of("admin");
    if (!adminUsers.contains(user)) {
        throw new AccessDeniedException("Only admin can access this endpoint");
    }
    return "Welcome, Admin! You have full control.";
}
@GetMapping("/api/dev/tools")
public String devTools(@RequestHeader("X-Remote-User") String user) {
    Set<String> devUsers = Set.of("admin", "dev");
    if (!devUsers.contains(user)) {
        throw new AccessDeniedException("Only admin and dev can use dev tools");
    }
    return "Dev tools are available.";
}

这样,你实现了 前端认证(Nginx) + 后端授权(Java) 的双重保障,符合最小权限原则。

七、自动化脚本:一键部署认证系统

为了在多台服务器上快速部署,我们可以编写一个 Bash 脚本。

7.1 deploy-auth.sh

#!/bin/bash
# deploy-auth.sh - 自动部署 Nginx + htpasswd 认证系统
set -e  # 出错即停
# 配置变量
DOMAIN="admin.example.com"
HTPASSWD_FILE="/etc/nginx/.htpasswd"
NGINX_CONF="/etc/nginx/sites-available/admin"
SSL_CERT="/etc/ssl/certs/${DOMAIN}.crt"
SSL_KEY="/etc/ssl/private/${DOMAIN}.key"
echo "🚀 正在部署 Nginx Basic Auth 系统..."
# 检查是否为 root
if [[ $EUID -ne 0 ]]; then
   echo "❌ 必须以 root 身份运行"
   exit 1
fi
# 安装 apache2-utils(含 htpasswd)
if ! command -v htpasswd &> /dev/null; then
    echo "🔧 安装 apache2-utils..."
    if apt-get -qq update && apt-get install -y apache2-utils; then
        echo "✅ apache2-utils 安装成功"
    else
        echo "❌ 安装失败,请检查网络"
        exit 1
    fi
fi
# 创建 htpasswd 文件
echo "🔐 创建用户凭证文件..."
if [ -f "$HTPASSWD_FILE" ]; then
    echo "⚠️ 文件已存在,备份中..."
    cp "$HTPASSWD_FILE" "$HTPASSWD_FILE.bak"
fi
# 交互式添加用户
read -p "请输入要添加的用户名: " USERNAME
if [ -z "$USERNAME" ]; then
    echo "❌ 用户名不能为空"
    exit 1
fi
htpasswd -c "$HTPASSWD_FILE" "$USERNAME"
# 设置权限
chmod 640 "$HTPASSWD_FILE"
chown root:www-data "$HTPASSWD_FILE"
echo "✅ 权限设置完成"
# 生成 Nginx 配置
cat > "$NGINX_CONF" <<EOF
server {
    listen 80;
    server_name $DOMAIN;
    return 301 https://\$host\$request_uri;
}
server {
    listen 443 ssl;
    server_name $DOMAIN;
    ssl_certificate $SSL_CERT;
    ssl_certificate_key $SSL_KEY;
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    root /var/www/admin;
    index index.html;
    auth_basic "Restricted Access";
    auth_basic_user_file $HTPASSWD_FILE;
    location / {
        proxy_set_header X-Remote-User \$remote_user;
        proxy_pass http://localhost:8080;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
    }
}
EOF
echo "✅ Nginx 配置已生成"
# 创建符号链接(如果使用 sites-available)
if [ -d "/etc/nginx/sites-enabled" ]; then
    ln -sf "$NGINX_CONF" "/etc/nginx/sites-enabled/"
    echo "✅ 启用站点配置"
fi
# 测试配置
echo "🔧 测试 Nginx 配置..."
if nginx -t; then
    echo "✅ 配置语法正确"
else
    echo "❌ 配置错误,请检查"
    exit 1
fi
# 重启 Nginx
echo "🔄 重启 Nginx..."
systemctl reload nginx
echo "🎉 部署完成!"
echo "访问:https://$DOMAIN"
echo "使用用户名:$USERNAME 登录"

7.2 使用方法

chmod +x deploy-auth.sh
sudo ./deploy-auth.sh

脚本会:

  • 自动安装 htpasswd
  • 创建 .htpasswd 文件并添加用户
  • 生成 Nginx 配置文件
  • 启用站点
  • 重启 Nginx

可集成到 Ansible、Terraform 或 CI/CD 流程中,实现 DevOps 自动化。

八、性能与安全最佳实践

8.1 性能优化

优化项说明
✅ 使用 auth_basic_user_file 指定绝对路径避免 Nginx 搜索路径,减少 I/O 开销
✅ 将 .htpasswd 放在 SSD 磁盘高频访问时,磁盘读取速度影响响应延迟
✅ 启用 gzip 压缩减少认证失败时 401 响应体积
✅ 使用 keepalive 连接减少 TLS 握手开销
keepalive_timeout 65;
gzip on;
gzip_types text/plain application/json application/javascript;

8.2 安全加固

措施说明
🔒 强制 HTTPS所有 Basic Auth 必须走 HTTPS,否则密码明文传输
🔐 禁用弱密码使用 zxcvbnpwquality 检查密码强度
🚫 禁用目录遍历autoindex off; 防止列出文件
📜 限制登录尝试使用 fail2ban 监控 Nginx 日志,自动封禁暴力 破解 IP
📊 日志记录记录认证成功/失败事件,用于审计

fail2ban 示例规则(/etc/fail2ban/jail.d/nginx-basic-auth.conf)

[nginx-basic-auth]
enabled = true
port = http,https
filter = nginx-basic-auth
logpath = /var/log/nginx/error.log
maxretry = 5
bantime = 3600
findtime = 600

filter 文件(/etc/fail2ban/filter.d/nginx-basic-auth.conf)

[Definition]
failregex = ^.*"GET.*" 401 .*$
ignoreregex =

重启 fail2ban:

sudo systemctl restart fail2ban

现在,5 分钟内 5 次认证失败,IP 将被封 1 小时。

九、日志与监控:追踪谁在访问?

Nginx 默认会记录所有请求,包括认证状态。我们可以分析日志:

# 查看认证失败记录
grep "401" /var/log/nginx/access.log

# 查看认证成功记录(包含用户名)
grep -E "200.*\"GET.*\" \"[^\"]*\"" /var/log/nginx/access.log | awk '{print $1, $9, $10}'

更高级的分析,可用 awk 统计每个用户访问次数:

awk '$9 == "200" && $10 ~ /Basic/ {print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr

输出示例:

245 192.168.1.10
87 192.168.1.15
3 192.168.1.20

结合 ELK(Elasticsearch + Logstash + Kibana)或 Grafana Loki,可实现可视化监控。

十、与 Java 应用的整合流程图 

下面是一个 Mermaid 流程图,展示整个认证与授权流程:

这个流程清晰地展示了:

  • 认证发生在 Nginx 层
  • 授权发生在 Java 层
  • 用户名通过安全头传递
  • 整体架构松耦合,易于维护

十一、常见问题与解决方案

Q1:为什么我输入正确密码还是 401?

  • .htpasswd 文件路径错误
  • 文件权限不是 640,Nginx 无法读取
  • 文件编码不是 UTF-8(某些编辑器保存为 UTF-16)
  • Nginx 配置未重载

✅ 解决方案:

ls -l /etc/nginx/.htpasswd
cat /etc/nginx/.htpasswd | hexdump -C  # 检查是否有 BOM
nginx -t && systemctl reload nginx

Q2:如何支持中文用户名?

htpasswd 本身支持 UTF-8,但某些旧版本工具可能有问题。

建议:使用英文用户名(如 alice_zhang),避免编码问题。

Q3:能不能不用 htpasswd?用数据库?

当然可以!但代价是复杂性飙升:

  • 需要写 Nginx Lua 模块(如 ngx_http_auth_request_module
  • 或使用 OpenID Connect / OAuth2(如 Keycloak)
  • 或使用 auth_request + 后端 API 校验

对于简单场景,htpasswd 是最优解。复杂场景才考虑 JWT + OAuth2。

Q4:能否禁用浏览器缓存认证?

可以。在 Nginx 中添加:

add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
add_header Expires "0";

但注意:浏览器会缓存 Basic Auth 凭证直到关闭标签页,这是协议行为,无法完全禁用。

十二、为什么不用 JWT / OAuth2?什么时候该用 htpasswd?

方案适用场景优点缺点
htpasswd + Nginx内部系统、测试环境、文档站、小团队零依赖、快速部署、无需代码修改、稳定不支持多设备、无会话管理、不可扩展
JWT / OAuth2公开 API、移动端、SaaS、多租户可扩展、支持 token 刷新、无状态、可跨域需要开发、需管理密钥、需 Token 有效期策略

建议

  • 内部管理后台 → 用 htpasswd
  • 外部 API → 用 JWT + API Key
  • 用户系统 → 用 OAuth2 + Keycloak / Auth0

十三、Java 项目中如何优雅地处理匿名访问?

即使有 Nginx 认证,我们也应让 Java 应用具备“优雅降级”能力:

@RestController
public class SecurityController {
    @GetMapping("/api/public")
    public String publicEndpoint() {
        return "This is public. No auth needed.";
    }
    @GetMapping("/api/protected")
    public String protectedEndpoint(@RequestHeader(value = "X-Remote-User", required = false) String user) {
        if (user == null || user.trim().isEmpty()) {
            return "Access Denied: Please authenticate via Nginx.";
        }
        return "Hello " + user + "! You are authenticated.";
    }
    @GetMapping("/api/me")
    public ResponseEntity<User> me(HttpServletRequest request) {
        String user = request.getHeader("X-Remote-User");
        if (user == null) {
            return ResponseEntity.status(401).body(null);
        }
        return ResponseEntity.ok(new User(user, System.currentTimeMillis(), request.getRemoteAddr()));
    }
}

这样,即使 Nginx 认证被绕过(如测试环境),Java 也能给出明确提示,而不是返回 500。

十四、未来演进:从 htpasswd 到 SSO 的路径

虽然 htpasswd 简单,但随着组织扩大,你可能需要:

  1. LDAP / Active Directory 集成 → Nginx + auth_request + LDAP
  2. OAuth2 / OpenID Connect → 使用 Keycloak 作为认证中心
  3. MFA(双因素认证) → 通过 Nginx + ModSecurity 实现短信/OTP 验证
  4. 零信任架构 → 使用 Istio + SPIFFE 实现服务网格认证

十五、总结:你该选择什么?

场景推荐方案
内部运维后台、测试环境htpasswd + Nginx
API 网关、公开服务✅ JWT + API Key
用户注册登录系统✅ OAuth2 + Spring Security
大型企业统一认证✅ SAML / LDAP / Keycloak
高安全要求(金融、政府)✅ MFA + 审计日志 + 证书双向认证

记住:安全不是技术,是流程。
无论你用什么方案,定期轮换密码、记录访问日志、限制 IP、启用 HTTPS,才是真正的安全。

附录:完整 Nginx 配置模板

upstream java_backend {
    server 127.0.0.1:8080;
}
server {
    listen 80;
    server_name admin.example.com;
    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl http2;
    server_name admin.example.com;
    ssl_certificate /etc/ssl/certs/admin.example.com.crt;
    ssl_certificate_key /etc/ssl/private/admin.example.com.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    root /var/www/admin;
    index index.html;
    # 认证配置
    auth_basic "Internal Dashboard - Authorized Access Only";
    auth_basic_user_file /etc/nginx/.htpasswd;
    # 传递用户名给后端
    proxy_set_header X-Remote-User $remote_user;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    location / {
        try_files $uri $uri/ =404;
    }
    location /api/ {
        proxy_pass http://java_backend;
    }
    location /docs/ {
        alias /var/www/docs;
        autoindex off;
    }
    # 限制访问频率
    limit_req zone=one burst=5 nodelay;
}
# 限流区域
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;

结语:安全,从最小的一步开始

你不需要一个庞大的 IAM 系统来保护一个内部管理页面。
你不需要复杂的 OAuth2 流程来锁住一个测试 API。
你只需要一个 htpasswd 文件,一行 Nginx 配置,和一点安全意识。

真正的安全,不是堆砌技术,而是知道何时用对工具。

今天,你学会了用最朴素的方式,构筑最坚固的防线。
明天,当你面对更复杂的系统时,你会感谢今天这份扎实的根基。

记住
Security is not a product, it’s a process.” — Bruce Schneier

你,已经比 90% 的开发者更懂安全了。
继续前行,安全之路,永无止境。

以上就是Nginx+htpasswd实现基于用户认证的访问控制的详细内容,更多关于Nginx htpasswd用户认证访问控制的资料请关注脚本之家其它相关文章!

相关文章

  • nginx生成自签名SSL证书配置HTTPS的实现

    nginx生成自签名SSL证书配置HTTPS的实现

    本文主要介绍在Nginx中生成自签名SSL证书并配置HTTPS,包括安装Nginx、创建证书、配置证书以及测试访问,具有一定的参考价值,感兴趣的可以了解一下
    2025-03-03
  • 阿里云国际版使用Nginx作为HTTPS转发代理服务器的处理方法

    阿里云国际版使用Nginx作为HTTPS转发代理服务器的处理方法

    本文介绍了使用NGINX作为HTTPS流量转发代理的两种方法。它总结了NGINX使用HTTP CONNECT隧道和NGINX流充当HTTPS转发代理的解决方案的原则,环境构建要求,应用场景和关键问题
    2022-05-05
  • Nginx配置移动端和PC端自动跳转方式

    Nginx配置移动端和PC端自动跳转方式

    文章介绍了如何通过Nginx配置PC端和移动端自动跳转,PC端和移动端各有独立的域名,PC端访问任何域名时会跳转到www.yxf.com,移动端访问任何域名时会跳转到m.yxf.com,配置时需要修改Nginx的conf文件,使用302或301重定向
    2025-11-11
  • 在Nginx中拦截特定用户代理的教程

    在Nginx中拦截特定用户代理的教程

    这篇文章主要介绍了在Nginx中拦截特定用户代理的教程,并为这些被拦截的用户设置一个黑名单以方便管理,需要的朋友可以参考下
    2015-06-06
  • Nginx静态文件处理和传输的优化方法

    Nginx静态文件处理和传输的优化方法

    Nginx 在处理静态文件时非常高效,它可以直接从文件系统中读取静态文件并返回给客户端,而不需要经过复杂的处理流程,在本章中,我们将详细介绍NGINX如何处理静态文件以及传输优化,需要的朋友可以参考下
    2025-06-06
  • nginx与apache限制ip并发访问 限制ip连接的设置方法

    nginx与apache限制ip并发访问 限制ip连接的设置方法

    nginx限制ip并发数,也是说限制同一个ip同时连接服务器的数量,要使apache服务器做对同一IP地址的连接限制,需要mod_limitipconn来实现。一般需要手动编译。不过模块作者也提供了一些编译好的模块,根据自己的apache版本可以直接使用
    2012-11-11
  • nginx之内存池的实现

    nginx之内存池的实现

    本文主要介绍了nginx之内存池的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • prometheus监控nginx的两种方式

    prometheus监控nginx的两种方式

    这篇文章主要介绍了两种不同的Nginx监控方法,第一种是nginx自带的tub_status模块进行监控,第二种是用vts监控工具进行监控,都是基于prometheus、grafana结合第三方模块或监控工具搭建,文中通过图文结合的方式介绍的非常详细,需要的朋友可以参考下
    2024-05-05
  • 图文详解Nginx多种匹配方式

    图文详解Nginx多种匹配方式

    nginx作为一款高性能的服务器,用途很多,下面这篇文章主要给大家介绍了Nginx多种匹配方式的相关资料,文中通过图文介绍的介绍的非常详细,需要的朋友可以参考下
    2022-05-05
  • Nginx SSL/TLS配置的实现

    Nginx SSL/TLS配置的实现

    Nginx支持SSL/TLS协议,用于加密HTTPS通信,本文主要介绍了Nginx SSL/TLS配置的实现,具有一定的参考价值,感兴趣的可以了解一下
    2025-02-02

最新评论