OIDC#

该模块添加了 OpenID Connect(OIDC)认证。当未认证的用户请求受保护的页面时,Angie 会将用户重定向到 OIDC 提供方(如 Google、Azure AD 或 Keycloak)的登录页面;登录成功后,用户返回原始页面。Angie 通过变量将用户数据传递给后端,因此后端本身无需任何认证代码。

OIDC 身份验证设置 指南介绍了在 Angie 中使用 Lua 脚本配置 OIDC 认证的另一种方式。

安装#

要 安装 该模块,请使用以下软件包之一:

  • Angie:angie-module-oidc

  • Angie PRO:angie-pro-module-oidc

指令#

该模块的主要指令:

  • oidc_provider — 定义提供方:其 issuer、客户端凭据、回调路径 redirect_uri、会话生存期(session_timeout,默认为 8 小时)以及其他设置

  • oidc_session_store — 定义具名会话存储,可在内存中(type memory)或 Redis 中(type redis);仅当提供方的 session_store 参数指定该名称时,提供方才会使用它;未设置 session_store 的提供方将会话保存在默认的内存存储中

  • auth_oidc — 启用使用指定提供方的认证;off 表示禁用

  • auth_oidc_mode — 设置未认证请求的处理方式:默认值 require 会将其重定向到提供方;verify 则将其放行,并将 $oidc_authenticated 设为 0

  • auth_oidc_bearer — 同时接受 Authorization: Bearer 请求头中的访问令牌:携带此类令牌的请求仅凭令牌进行认证,令牌验证失败时返回 401 响应;其他请求通过会话 cookie 进行认证

  • oidc_base_url — 设置回调的基础 URL(协议、主机,以及可选的端口),而不是取自请求的值

该模块通过变量传递认证数据:$oidc_claim_name 保存用户 ID 令牌的声明,例如 $oidc_claim_sub 或 $oidc_claim_email(数组类型的声明以逗号连接);$oidc_id_token 和 $oidc_access_token 保存令牌;对于已认证的请求,$oidc_authenticated 为 1,否则为 0。对于通过 Bearer 令牌认证的请求,仅设置声明变量和 $oidc_authenticated。

所有指令、提供方和存储参数以及变量均在模块文档 中说明。

加载模块#

要使用该模块,必须在 main{} 上下文中加载它:

load_module modules/ngx_http_oidc_module.so;

配置示例#

http {
    oidc_provider google {
        issuer "https://accounts.google.com";
        client_id "your-client-id.apps.googleusercontent.com";
        client_secret "your-client-secret";
        redirect_uri "/oauth2/callback";
    }

    server {
        listen 80;
        server_name myapp.example.com;

        # Enable authentication for the entire server
        auth_oidc google;

        location / {
            proxy_pass http://127.0.0.1:9090;
            proxy_set_header X-User-ID $oidc_claim_sub;
        }

        location /_oidc_http_fetch {
            internal;
            auth_oidc off;

            proxy_pass $oidc_fetch_url;
            proxy_method $oidc_fetch_method;
            proxy_set_header Content-Type $oidc_fetch_content_type;
            proxy_set_header Content-Length $oidc_fetch_content_length;
            proxy_set_header Authorization $oidc_fetch_bearer;

            proxy_set_header Host $proxy_host;
            proxy_set_header Accept-Encoding "";
            proxy_pass_request_body on;
            proxy_max_temp_file_size 0;
            subrequest_output_buffer_size 200k;

            proxy_http_version 1.1;
            proxy_set_header Connection "";

            proxy_ssl_verify on;
            proxy_ssl_verify_depth 2;
            proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
            proxy_ssl_server_name on;
            proxy_ssl_name $proxy_host;

            proxy_connect_timeout 30s;
            proxy_send_timeout 30s;
            proxy_read_timeout 30s;
        }
    }
}

client_id 和 client_secret 的值由提供方在注册应用时颁发。同时还需注册完整的回调 URL,本例中为 http://myapp.example.com/oauth2/callback:模块根据协议、请求的主机名以及 Angie 接受连接的端口(端口为 80(HTTP)或 443(HTTPS)时省略)构建该 URL,后接 redirect_uri 路径。

在生产环境中,请通过 HTTPS 提供站点服务:只有当客户端通过 TLS 连接到 Angie 时,模块才会为其 cookie 添加 Secure 属性。如果 TLS 在 Angie 前端的代理处终止,请将 oidc_base_url 设置为外部的 https URL,以使回调 URL 与注册的一致。

本例中的提供方将会话保存在默认的内存存储中。内存中的会话在重新加载配置后不会保留,因此重新加载后用户需要重新登录。

模块通过 /_oidc_http_fetch location 向提供方发送自己的请求,例如获取提供方的发现文档和密钥,或用授权码换取令牌。该 location 的名称是固定的;如果缺少它,配置检查将失败。在该 location 中:

  • proxy_pass $oidc_fetch_url 和 proxy_set_header Content-Type $oidc_fetch_content_type 是必需的:没有 Content-Type 请求头,提供方可能会拒绝令牌请求,导致登录失败。

  • 仅当提供方块启用了 userinfo 时,才需要 proxy_set_header Authorization $oidc_fetch_bearer。

  • subrequest_output_buffer_size 必须能容纳提供方最大的响应:如果发现文档或密钥集超出缓冲区,子请求将失败,浏览器会收到空响应。

  • proxy_ssl_* 指令适用于 https URL 的 issuer(如 Google):它们根据受信任的 CA 证书验证提供方的证书,并在 SNI 中发送提供方的名称。

  • internal 使该 location 无法从外部访问,auth_oidc off 将其排除在认证之外。

该 location 中的其余行是模块作者推荐的设置。

Angie 使用自己的解析器解析提供方的主机名;默认情况下,它会查询 /etc/resolv.conf 中列出的名称服务器。仅当默认设置不适用时,才需在此 location 中添加 resolver 指令。

模块在访问阶段检查认证,因此受保护 location 中的 return 指令会在检查之前作出响应;请改用 proxy_pass 或文件来提供受保护的内容。

认证流程#

使用上述配置,用户按以下步骤获得访问权限:

  1. 浏览器在没有会话 cookie 的情况下请求页面。Angie 将浏览器重定向到提供方的授权端点,并在 URL 中添加 state、nonce 和 PKCE 参数。

  2. 用户在提供方处登录,提供方携带授权码将浏览器重定向到 /oauth2/callback。

  3. Angie 通过 /_oidc_http_fetch 用授权码换取令牌,验证 ID 令牌,设置 NGX_OIDC_SESSION 会话 cookie,并将浏览器重定向到原始页面。

  4. 携带会话 cookie 的请求无需重定向即可到达后端;后端在 X-User-ID 请求头中接收用户标识符,即 sub 声明。

附加信息#

版本: 0.8.0

详细文档和源代码可在以下位置获取: kjdev/nginx-oidc