# Windows 集成(Negotiate)一键登录:IIS / 应用程序 / nginx 对照 本文对应代码中的 **`GET /board/api/winauth/negotiate`**:`[Authorize]` 要求已通过 **Windows / Negotiate** 身份后,由 **`AdAuthenticationService.AdLoginAsync`** 做 LDAP(与 `searchFilter`/组策略一致)并写入 **Session**(`board.sid`),再 **302** 回业务页;LDAP 失败则 **302** 到 `/board/login?negotiate_error=...`(避免对 API 返回 401 引发浏览器凭据框)。 > **关于「不加入 Intranet、绝不弹框」** > 完全无弹窗依赖 **Kerberos/浏览器与站点信任关系**;仅用 NTLM 或非信任站点时,浏览器仍可能提示。生产环境建议:**HTTPS + 正确 DNS/SPN + 组策略** 将站点加入受信任区域或使用 Kerberos。 --- ## 一、应用程序内(`aspnet/BoardApp`) | 项 | 说明 | |----|------| | 认证注册 | **检测到 `ASPNETCORE_IIS_PHYSICAL_PATH`(IIS 托管)** → `AddAuthentication(IISDefaults.AuthenticationScheme)`;**否则(Kestrel,如 nginx→3000)** → `AddNegotiate()`。 | | 中间件顺序 | `UseRouting` → `UseSession` → `UseAuthentication` → `UseAuthorization` → `BoardRequireAuthMiddleware` → `MapControllers`。 | | 一键入口 | `GET /board/api/winauth/negotiate?next=/board/`(由登录页按钮 **整页跳转** 触发)。 | | LDAP | 与 `POST /api/winauth/login` 相同:`VerifyUserForIntegratedLogin`。 | | 反代头 | `app.config.json` 中 **`trustProxy: true`**,以便识别 `X-Forwarded-Proto` 等(与 nginx 一致)。 | --- ## 二、IIS 托管 Board 时的推荐设置(无 nginx 或 nginx 只反代到 IIS) 1. 安装 **.NET 8 Hosting Bundle**,应用池 **无托管代码**、**集成**、**启用 32/64 位与发布一致**。 2. 站点下建 **应用程序 `/board`**,物理路径指向 Board 发布目录。 3. **身份验证**(站点或 `/board` 应用程序,按你是否拆分而定): - **启用**「Windows 身份验证」。 - **启用**「匿名身份验证」(推荐):未建立 Windows 身份的用户仍可打开登录页与 `POST /api/login`;一键登录由 **`/api/winauth/negotiate`** 在 **已认证** 时建 Session。若整站关匿名,未加入域的客户端可能无法打开登录页。 4. **Windows 身份验证** → **提供程序**:保留 **Negotiate**(与 **NTLM** 按需;域环境优先 Negotiate/Kerberos)。 5. **应用程序池标识**:域环境下一键登录一般使用 **客户端身份**;LDAP 绑定仍使用 **`ldap.config.json` 中的服务账号**。 6. **内核模式身份验证**:默认可开;若与 Kerberos 冲突再按微软文档关闭排查。 7. 出站若经 HTTPS 终止在 nginx,Board 仍须能读到 **`X-Forwarded-Proto`**(见 nginx 段)。 --- ## 三、Kestrel(`:3000`)+ nginx(`:80`)时的对应关系 | 层级 | 配置要点 | |------|----------| | **nginx** | 使用示例 **`nginx/board-aspnet-negotiate.sample.conf`**:`location ^~ /board/` 中 **`proxy_set_header Authorization $http_authorization`**、**`proxy_pass_header WWW-Authenticate`**,并 **`proxy_http_version 1.1`** / **`Connection ""`**(见文件内注释)。 | | **Board(Kestrel)** | 不经 IIS 时自动走 **`AddNegotiate()`**;浏览器经 nginx 与 Kestrel 做 **SPNEGO/NTLM** 多跳,行为因客户端而异。 | | **应用程序** | 同上:`trustProxy`、同一 `config/*.json`。 | --- ## 四、与现有 `nginx/board.conf` 的关系 - **`board.conf`**:逻辑不变;未增加 Negotiate 专用头。 - **`board-aspnet-negotiate.sample.conf`**:在 **仅 `/board/` 反代** 上增强 Negotiate 兼容性;**`auth_request`、`DataEase` 段与 `board.conf` 对齐**,可按需合并到你自己的 include 中。 --- ## 五、验收步骤(简要) 1. 浏览器打开 `http:///board/login`。 2. 点击 **一键登录(Windows 集成)** → 应跳转到 `/board/api/winauth/negotiate?...`。 3. 成功:302 到 `next` 或 `/board/`,且 `GET /board/check/` 为 200(供 nginx `auth_request`)。 4. 失败(非域、无票、LDAP 拒绝):回到登录页并显示 **`negotiate_error`** 文案,而非反复弹出系统凭据框(LDAP 失败路径);若仍弹框,多为 **Negotiate 质询** 或 **nginx 未透传 `Authorization/WWW-Authenticate`**。