OIDC#

The module adds OpenID Connect (OIDC) authentication. When an unauthenticated user requests a protected page, Angie redirects the user to the sign-in page of an OIDC provider, such as Google, Azure AD, or Keycloak; after a successful sign-in, the user returns to the original page. Angie passes the user's data to the backend in variables, so the backend itself needs no authentication code.

The OIDC Authentication Setup guide describes another way to set up OIDC authentication in Angie, with Lua scripts.

Installation#

To install the module, use one of the following packages:

  • Angie: angie-module-oidc

  • Angie PRO: angie-pro-module-oidc

Directives#

The main directives of the module:

  • oidc_provider — defines a provider: its issuer, the client credentials, the redirect_uri callback path, the session lifetime (session_timeout, 8 hours by default), and other settings

  • oidc_session_store — defines a named session store, in memory (type memory) or in Redis (type redis), that a provider uses only when its session_store parameter names it; a provider without session_store keeps sessions in a default memory store

  • auth_oidc — enables authentication with the named provider; off disables it

  • auth_oidc_mode — sets how unauthenticated requests are handled: require, the default, redirects them to the provider; verify passes them on with $oidc_authenticated set to 0

  • auth_oidc_bearer — also accepts an access token in the Authorization: Bearer header: a request that carries such a token is authenticated by the token alone and gets a 401 response if the token fails verification; other requests are authenticated by the session cookie

  • oidc_base_url — sets the base URL of the callback (scheme, host and, optionally, port) instead of the one taken from the request

The module passes authentication data in variables: $oidc_claim_name holds a claim of the user's ID token, such as $oidc_claim_sub or $oidc_claim_email (array claims are joined with commas); $oidc_id_token and $oidc_access_token hold the tokens; $oidc_authenticated is 1 for an authenticated request and 0 otherwise. For a request authenticated by a Bearer token, only the claim variables and $oidc_authenticated are set.

All directives, provider and store parameters, and variables are described in the module documentation.

Loading the Module#

To use the module, it must be loaded in the main{} context:

load_module modules/ngx_http_oidc_module.so;

Configuration Example#

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;
        }
    }
}

The client_id and client_secret values are issued by the provider when the application is registered there. Register the full callback URL as well, http://myapp.example.com/oauth2/callback in this example: the module builds it from the scheme, the host name of the request and, when it is not 80 (HTTP) or 443 (HTTPS), the port on which Angie accepted the connection, followed by the redirect_uri path.

In production, serve the site over HTTPS: the module adds the Secure attribute to its cookies only when the client connects to Angie over TLS. If TLS ends at a proxy in front of Angie, set oidc_base_url to the external https URL so that the callback URL matches the registered one.

The provider in this example keeps sessions in the default memory store. Sessions in memory do not survive a configuration reload, so after a reload users sign in again.

The module sends its own requests to the provider, such as fetching the provider's discovery document and keys or exchanging the authorization code for tokens, through the /_oidc_http_fetch location. The name of this location is fixed; if it is missing, the configuration check fails. In this location:

  • proxy_pass $oidc_fetch_url and proxy_set_header Content-Type $oidc_fetch_content_type are required: without the Content-Type header, the provider can reject the token request, and sign-in fails.

  • proxy_set_header Authorization $oidc_fetch_bearer is needed only if the provider block enables userinfo.

  • subrequest_output_buffer_size must fit the provider's largest response: a discovery document or key set that exceeds the buffer makes the subrequest fail, and the browser gets an empty reply.

  • The proxy_ssl_* directives apply to an issuer with an https URL, as with Google: they verify the provider's certificate against the trusted CA certificates and send the provider's name in SNI.

  • internal keeps the location unreachable from outside, and auth_oidc off excludes it from authentication.

The remaining lines of the location are settings recommended by the module authors.

Angie resolves the provider's host name with its own resolver; by default, it queries the name servers listed in /etc/resolv.conf. Add the resolver directive to this location only if the default does not fit.

The module checks authentication in the access phase, so a return directive in a protected location responds before the check; serve protected content with proxy_pass or from files instead.

Authentication Flow#

With the configuration above, a user gets access in the following steps:

  1. The browser requests a page without a session cookie. Angie redirects the browser to the provider's authorization endpoint, adding the state, nonce, and PKCE parameters to the URL.

  2. The user signs in with the provider, which redirects the browser to /oauth2/callback with an authorization code.

  3. Angie exchanges the code for tokens through /_oidc_http_fetch, verifies the ID token, sets the NGX_OIDC_SESSION session cookie, and redirects the browser to the original page.

  4. Requests with the session cookie reach the backend without redirects; the backend receives the user identifier, the sub claim, in the X-User-ID header.

Additional Information#

Version: 0.8.0

Detailed documentation and source code are available at: kjdev/nginx-oidc