OIDC 身份验证设置#
本指南说明如何使用 Google 作为身份提供商 和 Angie Web 服务器通过 Lua 脚本设置 OpenID Connect (OIDC) 身份验证。
该实现使用 OAuth2/OIDC 身份验证保护内部端点, 并演示了一种基于电子邮件域限制访问的方法。 这只是一种示例方法;您可以按照自己喜欢的方式实现访问控制, 例如维护特定用户的允许列表、检查提供商响应中的域成员资格 或组属性,或使用来自您私有 IAM 系统的自定义声明。
小技巧
此 OIDC 实现为身份验证提供了基础,但应根据生产环境进行调整, 采用适当的安全措施、监控以及符合您组织的安全策略。
架构#
此处建议的 OIDC 设置包括:
Angie - 支持 Lua 模块以进行 OIDC 处理
lua-resty-openidc - 用于 OIDC 身份验证的 OpenResty Lua 库
Google OAuth2 - 用于用户身份验证的身份提供商
Docker Compose - 在本示例中仅用于快速启动; 在生产环境中使用您喜欢的任何部署方法
前提条件#
在配置 OIDC 身份验证之前,请确保您具备:
支持 Lua 模块 的 Angie Web 服务器
Docker 和 Docker Compose(用于部署)
Google Cloud Console 项目
来自 Google 的 OAuth2 凭据
Google OAuth2 设置#
要将 Google 配置为您的 OIDC 提供商:
创建新项目或选择现有项目
为您的项目配置 OAuth 同意屏幕(外部或内部)并发布它,以便用户可以进行身份验证
创建 OAuth2 凭据:
应用类型: Web 应用程序
已授权的重定向 URI:
http://localhost/auth/callback
保存您的
client_id和client_secret以供配置使用
备注
标准 Google Identity Services 已经支持 OIDC;不需要旧版 Google+ API。 仅当您的应用程序需要其数据时才启用其他 Google API。
配置设置#
让我们从 OIDC 设置所需的配置文件开始。 Docker 部署使用以下配置文件: 此配置执行以下操作: 使用支持 Lua 模块的 模板化 Angie 镜像 加载 Lua 模块 以实现 OIDC 功能 映射端口 80 以进行 HTTP 访问 从本地目录挂载配置文件 对于即插即用的演示,
下载 创建一个 OIDC 身份验证脚本,
使用 配置参数: 使用必要的 location 块配置 Angie
以进行 OIDC 身份验证。 要使用 OIDC 身份验证保护资源: 此配置执行以下操作: 使用 OIDC 身份验证保护 将经过身份验证的请求代理到 配置 OAuth2 流程端点: 端点功能: 配置对内部 API 的受限访问: 这提供了: 访问 Angie 的 状态 API 仅限本地主机访问 (127.0.0.1) 通过 Docker Compose 配置#
services:
angie:
image: docker.angie.software/angie:templated
environment:
ANGIE_LOAD_MODULES: "lua"
ports:
- 80:80
volumes:
- ./files/etc/angie/http.d:/etc/angie/http.d
OIDC 快速启动包,
在 files/etc/angie/http.d/oidc.lua 中设置您的 client_id 和 client_secret,
一切都将开箱即用。OIDC 身份验证脚本#
lua-resty-openidc 库处理身份验证逻辑:access_by_lua_block {
local res, err = require("resty.openidc").authenticate({
redirect_uri = "http://localhost/auth/callback",
discovery = "https://accounts.google.com/.well-known/openid-configuration",
logout_path = "/auth/logout",
redirect_after_logout_uri = "/auth/logged-out",
revoke_tokens_on_logout = true,
client_id = "YOUR_CLIENT_ID",
client_secret = "YOUR_CLIENT_SECRET"
})
}
redirect_uri: 成功身份验证后的回调 URLdiscovery: Google 的 OIDC 发现端点logout_path: 用户注销路径redirect_after_logout_uri: 注销后的重定向目标revoke_tokens_on_logout: 注销时撤销令牌以确保安全client_id 和 client_secret: 您的 Google OAuth2 凭据Angie 配置#
受保护的资源#
location /internal/ {
include /etc/angie/http.d/oidc.lua;
proxy_pass http://127.0.0.1/status/;
}
/internal/ 路径/status/ 的 内部 API身份验证端点#
location /auth/callback {
include /etc/angie/http.d/oidc.lua;
}
location /auth/logout {
include /etc/angie/http.d/oidc.lua;
}
location /auth/logged-out {
default_type text/plain;
return 200 "You have been logged out. Bye!";
}
/auth/callback: 处理来自 Google 的 OAuth2 回调/auth/logout: 启动用户注销/auth/logged-out: 成功注销后的着陆页内部 API 访问#
location /status/ {
api /status/;
allow 127.0.0.1;
deny all;
}
/internal/ 访问时的 OIDC 保护
部署步骤#
按照以下步骤部署 OIDC 身份验证: 在您的 OIDC Lua 脚本中更新 OAuth2 凭据: 替换 将 将 启动 Docker 服务: 验证部署: 导航到 您应该被重定向到 Google 进行身份验证 成功登录后,您将访问受保护的内容配置更新#
oidc.lua 中的占位符值:client_id 替换为您的 Google OAuth2 客户端 IDclient_secret 替换为您的 Google OAuth2 客户端密钥服务启动#
$ docker-compose up -d
http://localhost/internal/
安全配置#
电子邮件域限制#
实现域验证以按电子邮件域限制访问:
if not string.match(res.user.email, "gmail.com$") then
ngx.exit(ngx.HTTP_FORBIDDEN)
end
对于生产环境,请考虑以下事项:
将
gmail.com替换为您组织的域实现允许的电子邮件地址白名单
添加基于角色的访问控制
令牌管理#
OIDC 实现包括安全功能:
注销时自动撤销令牌 (
revoke_tokens_on_logout = true)lua-resty-openidc 库安全地管理会话
所有身份验证流程都遵循 OAuth2/OIDC 安全最佳实践
警告
对于生产部署:
始终对 OAuth2 回调使用 HTTPS
安全地存储客户端密钥,切勿存储在版本控制中
实施适当的会话超时和续订策略
监控身份验证日志以发现安全事件
身份验证流程#
OIDC 身份验证流程遵循标准 OAuth2/OIDC 程序:
用户访问受保护的 URL(例如
http://localhost/internal/)如果未经身份验证,用户将被重定向到 Google OAuth2
用户使用 Google 凭据进行身份验证
Google 使用授权码重定向回
/auth/callback服务器将代码交换为访问令牌和 ID 令牌
验证用户信息(包括电子邮件域检查)
授予用户访问受保护资源的权限
注销过程确保安全的会话终止:
用户导航到
http://localhost/auth/logout在 Google 的 OAuth2 端点撤销令牌
清除本地会话数据
用户被重定向到
/auth/logged-out
高级配置#
要限制对特定组织域的访问:
if not string.match(res.user.email, "yourcompany.com$") then
ngx.exit(ngx.HTTP_FORBIDDEN)
end
对于具有多个允许域的组织:
local allowed_domains = {"company1.com", "company2.com", "gmail.com"}
local email_valid = false
for _, domain in ipairs(allowed_domains) do
if string.match(res.user.email, domain .. "$") then
email_valid = true
break
end
end
if not email_valid then
ngx.exit(ngx.HTTP_FORBIDDEN)
end
用户信息访问#
从 OIDC 提供商访问其他用户声明:
-- 从 ID 令牌访问用户信息
local user_name = res.user.name
local user_picture = res.user.picture
local user_locale = res.user.locale
local user_email = res.user.email
这些值可用于日志记录、个性化或其他访问控制决策。