Install the jq command-line JSON processor. There is a dependency for this but it is not automatically installed.
sudo yum install jq
SELinux Issue Workaround
There is an issue with NGINIX’s permissions for the directory “/etc/nginx/conf.d". The simplest workaround for this is to change the owner and group of that directory to "nginix".
Modify the $oidc_logout_redirect to use the URI "/oidc_logout". This will be configured in the next section
map $host $oidc_logout_redirect {
# Where to send browser after requesting /logout location. This can be
# replaced with a custom logout page, or complete URL.
default "/oidc_logout";
}
This is a complete example of the updated openid_connect_configuration.conf file.
# OpenID Connect configuration
#
# Each map block allows multiple values so that multiple IdPs can be supported,
# the $host variable is used as the default input parameter but can be changed.
#
map $host $oidc_authz_endpoint {
default https://oidc.surepassid.com/connect/authorize;
}
map $host $oidc_token_endpoint {
default https://oidc.surepassid.com/connect/token;
}
map $host $oidc_endsession_endpoint {
default https://oidc.surepassid.com/connect/endsession;
}
map $host $oidc_jwks_uri {
default https://oidc.surepassid.com/.well-known/openid-configuration/jwks;
}
map $host $oidc_jwt_keyfile {
default conf.d/idp_jwk.json;
}
map $host $oidc_client {
default "<OIDC_CLIENT_ID>";
}
map $host $oidc_pkce_enable {
default 0;
}
map $host $oidc_client_secret {
default "<OIDC_CLIENT_SECRET>";
}
map $host $oidc_scopes {
default "openid+profile+email+offline_access";
}
map $host $oidc_logout_redirect {
# Where to send browser after requesting /logout location. This can be
# replaced with a custom logout page, or complete URL.
default "/oidc_logout";
}
map $host $oidc_hmac_key {
# This should be unique for every NGINX instance/cluster
default <UNIQUE_GENERATED_OIDC_HMCA_KEY>;
}
map $proto $oidc_cookie_flags {
http "Path=/; SameSite=lax;"; # For HTTP/plaintext testing
https "Path=/; SameSite=lax; HttpOnly; Secure;"; # Production recommendation
}
map $http_x_forwarded_port $redirect_base {
"" $proto://$host:$server_port;
default $proto://$host:$http_x_forwarded_port;
}
map $http_x_forwarded_proto $proto {
"" $scheme;
default $http_x_forwarded_proto;
}
# ADVANCED CONFIGURATION BELOW THIS LINE
# Additional advanced configuration (server context) in openid_connect.server_conf
# JWK Set will be fetched from $oidc_jwks_uri and cached here - ensure writable by nginx user
proxy_cache_path /var/cache/nginx/jwk levels=1 keys_zone=jwk:64k max_size=1m;
# Change timeout values to at least the validity period of each token type
keyval_zone zone=oidc_id_tokens:1M state=conf.d/oidc_id_tokens.json timeout=1h;
keyval_zone zone=refresh_tokens:1M state=conf.d/refresh_tokens.json timeout=8h;
keyval_zone zone=oidc_pkce:128K timeout=90s; # Temporary storage for PKCE code verifier.
keyval $cookie_auth_token $session_jwt zone=oidc_id_tokens; # Exchange cookie for JWT
keyval $cookie_auth_token $refresh_token zone=refresh_tokens; # Exchange cookie for refresh token
keyval $request_id $new_session zone=oidc_id_tokens; # For initial session creation
keyval $request_id $new_refresh zone=refresh_tokens; # ''
keyval $pkce_id $pkce_code_verifier zone=oidc_pkce;
auth_jwt_claim_set $jwt_audience aud; # In case aud is an array
js_import oidc from conf.d/openid_connect.js;
# vim: syntax=nginx
Make the following changes to the frontend.conf file. This is where the backend application server is configured.
upstream backend_app_server {
zone backend_app_server 64k;
# Server Private IP Address
server 10.1.2.3:443;
# DNS
#resolver 8.8.8.8;
#server app-proxy.example.com:443;
}
Add the /oidc_logout location. Place this in the server block before the / location.
server {
...
location = /oidc_logout {
# https://identityserver4.readthedocs.io/en/latest/endpoints/endsession.html
proxy_ssl_server_name on; # For SNI to the IdP
# $oidc_endsession_endpoint? // Defined in openid_connect_configuration.conf
# id_token_hint=$arg_token&
# post_logout_redirect_uri=https://app-proxy.example.com:433/_logout // The URL value must be URL encoded.
proxy_pass $oidc_endsession_endpoint?id_token_hint=$arg_token&post_logout_redirect_uri=https%3a%2f%2fapp-proxy.example.com%3a433%2f_logout;
}
location / {
...
}
}
Configure the reverse proxy to the backend application server.
server {
...
location / {
# This site is protected with OpenID Connect
auth_jwt "" token=$session_jwt;
error_page 401 = @do_oidc_flow;
#auth_jwt_key_file $oidc_jwt_keyfile; # Enable when using filename
auth_jwt_key_request /_jwks_uri; # Enable when using URL
# Successfully authenticated users are proxied to the backend,
# with 'sub' claim passed as HTTP header
proxy_set_header username $jwt_claim_sub;
proxy_pass https://backend_app_server; # The backend site/app
proxy_set_header Host app-proxy.example.com;
proxy_cookie_domain app-proxy.example.com $host;
}
}
This is a complete example of the updated frontend.conf file.
# This is the backend application we are protecting with OpenID Connect
upstream backend_app_server {
zone backend_app_server 64k;
# Private Azure IP
server 10.1.2.3:443;
# DNS
#resolver 8.8.8.8;
#server app-proxy.example.com:443;
}
# Custom log format to include the 'sub' claim in the REMOTE_USER field
log_format main_jwt '$remote_addr - $jwt_claim_sub [$time_local] "$request" $status '
'$body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"';
# The frontend server - reverse proxy with OpenID Connect authentication
#
server {
include conf.d/openid_connect.server_conf; # Authorization code flow and Relying Party processing
error_log /var/log/nginx/error.log debug; # Reduce severity level as required
#####################
# SSL Configuration #
#####################
server_name app-proxy.example.com;
listen 443 ssl;
ssl_certificate ssl/surepassid.com_2022-05-14.crt;
ssl_certificate_key ssl/surepassid.com_2022-05-14.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
location = /oidc_logout {
# https://identityserver4.readthedocs.io/en/latest/endpoints/endsession.html
proxy_ssl_server_name on; # For SNI to the IdP
proxy_pass $oidc_endsession_endpoint?id_token_hint=$arg_token&post_logout_redirect_uri=https%3a%2f%2fapp-proxy.example.com%3a433%2f_logout;
}
location / {
# This site is protected with OpenID Connect
auth_jwt "" token=$session_jwt;
error_page 401 = @do_oidc_flow;
#auth_jwt_key_file $oidc_jwt_keyfile; # Enable when using filename
auth_jwt_key_request /_jwks_uri; # Enable when using URL
# Successfully authenticated users are proxied to the backend,
# with 'sub' claim passed as HTTP header
proxy_set_header username $jwt_claim_sub;
proxy_pass https://backend_app_server; # The backend site/app
proxy_set_header Host app-proxy.example.com;
proxy_cookie_domain app-proxy.example.com $host;
}
}
# vim: syntax=nginx