Skip to content

Commit 7ebe23b

Browse files
committed
feat: add userinfo endpoint
1 parent 6ad8ec6 commit 7ebe23b

4 files changed

+75
-5
lines changed

configure.sh

+2-2
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ fi
120120
# Build an intermediate configuration file
121121
# File format is: <NGINX variable name><space><IdP value>
122122
#
123-
jq -r '. | "$oidc_authz_endpoint \(.authorization_endpoint)\n$oidc_token_endpoint \(.token_endpoint)\n$oidc_jwks_uri \(.jwks_uri)"' < /tmp/${COMMAND}_$$_json > /tmp/${COMMAND}_$$_conf
123+
jq -r '. | "$oidc_authz_endpoint \(.authorization_endpoint)\n$oidc_token_endpoint \(.token_endpoint)\n$oidc_jwks_uri \(.jwks_uri)\n$oidc_userinfo_endpoint \(.userinfo_endpoint)"' < /tmp/${COMMAND}_$$_json > /tmp/${COMMAND}_$$_conf
124124

125125
# Create a random value for HMAC key, adding to the intermediate configuration file
126126
echo "\$oidc_hmac_key `openssl rand -base64 18`" >> /tmp/${COMMAND}_$$_conf
@@ -178,7 +178,7 @@ fi
178178

179179
# Loop through each configuration variable
180180
echo "$COMMAND: NOTICE: Configuring $CONFDIR/openid_connect_configuration.conf"
181-
for OIDC_VAR in \$oidc_authz_endpoint \$oidc_token_endpoint \$oidc_jwt_keyfile \$oidc_hmac_key $CLIENT_ID_VAR $CLIENT_SECRET_VAR $PKCE_ENABLE_VAR; do
181+
for OIDC_VAR in \$oidc_authz_endpoint \$oidc_token_endpoint \$oidc_jwt_keyfile \$oidc_userinfo_endpoint \$oidc_hmac_key $CLIENT_ID_VAR $CLIENT_SECRET_VAR $PKCE_ENABLE_VAR; do
182182
# Pull the configuration value from the intermediate file
183183
VALUE=`grep "^$OIDC_VAR " /tmp/${COMMAND}_$$_conf | cut -f2 -d' '`
184184
echo -n "$COMMAND: NOTICE: - $OIDC_VAR ..."

openid_connect.js

+37-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66
var newSession = false; // Used by oidcAuth() and validateIdToken()
77

8-
export default {auth, codeExchange, validateIdToken, logout};
8+
export default {auth, codeExchange, validateIdToken, logout, userInfo};
99

1010
function retryOriginalRequest(r) {
1111
delete r.headersOut["WWW-Authenticate"]; // Remove evidence of original failed auth_jwt
@@ -298,4 +298,39 @@ function idpClientAuth(r) {
298298
} else {
299299
return "code=" + r.variables.arg_code + "&client_secret=" + r.variables.oidc_client_secret;
300300
}
301-
}
301+
}
302+
303+
// Return necessary user info claims after receiving and extracting all claims
304+
// that are received from the OpenID Connect Provider(OP).
305+
function userInfo(r) {
306+
r.subrequest('/_userinfo',
307+
function(res) {
308+
if (res.status == 200) {
309+
var error_log = "OIDC userinfo JSON failure";
310+
var claimsOP = ''; // Claims that are received by the OP.
311+
try {
312+
claimsOP = JSON.parse(res.responseBody);
313+
} catch (e) {
314+
error_log += ": " + res.responseBody;
315+
r.error(error_log);
316+
r.return(500);
317+
return;
318+
}
319+
// The claimsRP is to extract claims that are configured in
320+
// $oidc_userinfo_required_claims in the RP and send them to
321+
// the client using the response of the OP.
322+
var claimsRP = r.variables.oidc_userinfo_required_claims.split(",");
323+
var ret = {};
324+
for (var i in claimsRP) {
325+
if (claimsRP[i] in claimsOP) {
326+
ret[claimsRP[i]] = claimsOP[claimsRP[i]];
327+
}
328+
}
329+
r.variables.user_info = JSON.stringify(ret);
330+
r.return(200, r.variables.user_info);
331+
} else {
332+
r.return(res.status)
333+
}
334+
}
335+
);
336+
}

openid_connect.server_conf

+20
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,26 @@
6666
error_page 500 502 504 @oidc_error;
6767
}
6868

69+
location = /userinfo {
70+
# This location is to provide signed-in user information claims that are
71+
# defined in $oidc_userinfo_required_claims.
72+
default_type application/json;
73+
if ($oidc_userinfo_required_claims = '') {
74+
return 200 '{"name": "", "message":"details not provided per your policy"}';
75+
}
76+
js_content oidc.userInfo;
77+
}
78+
79+
location = /_userinfo {
80+
# This location is called by oidc.userInfo() when calling /userinfo
81+
# to get signed-in user information from the OP:
82+
# - https://openid.net/specs/openid-connect-core-1_0.html#UserInfo
83+
internal;
84+
proxy_ssl_server_name on; # For SNI to the IdP
85+
proxy_set_header Authorization "Bearer $access_token";
86+
proxy_pass $oidc_userinfo_endpoint;
87+
}
88+
6989
location = /logout {
7090
status_zone "OIDC logout";
7191
add_header Set-Cookie "auth_token=; $oidc_cookie_flags"; # Send empty cookie

openid_connect_configuration.conf

+16-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,19 @@ map $host $oidc_jwt_keyfile {
2828
default "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/certs";
2929
}
3030

31+
map $host $oidc_userinfo_endpoint {
32+
default "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/userinfo";
33+
}
34+
35+
map $host $oidc_userinfo_required_claims {
36+
# The $oidc_userinfo_endpoint returns OP's response that contains default or
37+
# customized claims. This is used for scenarios where the SPA needs to show
38+
# user name or specific profiles instead of forwarding the response from the
39+
# OP to the SPA to minimize exposure of user info claims.
40+
default "";
41+
#www.example.com "sub,name,preferred_username,given_name,family_name,email,photo";
42+
}
43+
3144
map $host $oidc_client {
3245
default "my-client-id";
3346
}
@@ -89,12 +102,14 @@ proxy_cache_path /var/cache/nginx/jwk levels=1 keys_zone=jwk:64k max_size=1m;
89102
# Change timeout values to at least the validity period of each token type
90103
keyval_zone zone=oidc_id_tokens:1M state=conf.d/oidc_id_tokens.json timeout=1h;
91104
keyval_zone zone=refresh_tokens:1M state=conf.d/refresh_tokens.json timeout=8h;
92-
keyval_zone zone=oidc_pkce:128K timeout=90s; # Temporary storage for PKCE code verifier.
105+
keyval_zone zone=oidc_pkce:128K timeout=90s; # Temporary storage for PKCE code verifier.
106+
keyval_zone zone=oidc_userinfo:128K timeout=90s; # Temporary storage for user information.
93107

94108
keyval $cookie_auth_token $session_jwt zone=oidc_id_tokens; # Exchange cookie for JWT
95109
keyval $cookie_auth_token $refresh_token zone=refresh_tokens; # Exchange cookie for refresh token
96110
keyval $request_id $new_session zone=oidc_id_tokens; # For initial session creation
97111
keyval $request_id $new_refresh zone=refresh_tokens; # ''
112+
keyval $request_id $user_info zone=oidc_userinfo;
98113
keyval $pkce_id $pkce_code_verifier zone=oidc_pkce;
99114

100115
auth_jwt_claim_set $jwt_audience aud; # In case aud is an array

0 commit comments

Comments
 (0)