# Windows 托管应用认证：IIS、AD、JWT 与 OIDC

> 在 Windows/AD 认证、Basic、JWT、OIDC 之间有意选择，避开双跳陷阱，并区分 401 与 403。

**测试环境**

- 版本号: 26100.33650
- 版本: Standard / Datacenter
- 架构: x64
- 证据: E1
- 核验日期: 2026-10-29

## 一句话结论

| 需求 | 选择 |
|---|---|
| 域内 Windows 用户 | Windows 认证（Negotiate/Kerberos） |
| 遗留应用、无 SSO | Basic **仅 TLS**，绝不公网 |
| SPA/API | OIDC 授权码 + PKCE，JWT access token |
| 服务间 | client credentials/mTLS，不是共享密码 |
| 公网消费者 | OIDC/IdP + MFA；不要自建密码库 |

认证回答“是谁”；授权回答“能做什么”。401 是未认证；403 是已认证但无权。

## IIS Windows 认证

只开需要的 provider：

```powershell
Enable-WindowsOptionalFeature -Online -FeatureName IIS-WindowsAuthentication -All
```

IIS：关匿名，开 Windows 认证；选 Negotiate/Kerberos（必要时 NTLM 回退）。Kerberos 要：

- 服务账户/主机注册 SPN；
- DNS 名匹配 SPN；
- 只有双跳才配委派。

双跳（IIS → SQL/文件共享以用户身份）没有约束委派会失败。优先用服务身份访问后端，而不是到处模拟用户。

## Basic

Basic 发 Base64 凭据；无 TLS 就是明文。只给内网遗留设备、HTTPS、限定账户。绝不公网。

## JWT/OIDC

- 验签、issuer、audience、expiry、clock skew。
- 不信任 `alg: none`，不因为能 decode 就信任。
- access token 短；refresh token 小心。
- 浏览器 token 尽量 HttpOnly/Secure/SameSite cookie；长期 token 别放 localStorage。
- 授权检查在服务端；隐藏按钮不是授权。

## 代理认证

- 边缘/IdP 认证，再把签名身份（header/JWT）传给应用。
- 代理剥掉客户端自带的身份头；只有代理能设。
- 不要让应用信任公网来的 `X-User`。

> **警告: 401/403 是诊断信息**
>
> 401 带 `WWW-Authenticate` = 客户端没认证。403 = 认证了但身份/角色不够。混用会掩盖授权 bug。

## 验证

```powershell
curl.exe -I https://app.example/
curl.exe -I -u user:pass https://app.example/private
```

看 challenge、cookie 标志（`Secure`、`HttpOnly`、`SameSite`）、token 过期；低权限用户应得 403，不是数据。

## 实验室边界

E1。实验室 WAC 用本地管理员；没有为 Web 应用配 AD/Kerberos/OIDC。决策表是 Server 2025 上待验证设计。

## 来源

- [Microsoft Learn — IIS 认证](https://learn.microsoft.com/zh-cn/iis/configuration/system.webserver/security/authentication/)
- [Microsoft Learn — ASP.NET Core 认证](https://learn.microsoft.com/zh-cn/aspnet/core/security/authentication/)
- [OWASP — 认证速查](https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html)

---

来源页面: https://winbook.fyi/zh/server/security/auth/
