Skip to content

Commit

Permalink
feat: add userinfo endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
shawnhankim committed Dec 22, 2022
1 parent 6ad8ec6 commit 312304f
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 4 deletions.
4 changes: 2 additions & 2 deletions configure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ fi
# Build an intermediate configuration file
# File format is: <NGINX variable name><space><IdP value>
#
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
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

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

# Loop through each configuration variable
echo "$COMMAND: NOTICE: Configuring $CONFDIR/openid_connect_configuration.conf"
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
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
# Pull the configuration value from the intermediate file
VALUE=`grep "^$OIDC_VAR " /tmp/${COMMAND}_$$_conf | cut -f2 -d' '`
echo -n "$COMMAND: NOTICE: - $OIDC_VAR ..."
Expand Down
39 changes: 37 additions & 2 deletions openid_connect.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/
var newSession = false; // Used by oidcAuth() and validateIdToken()

export default {auth, codeExchange, validateIdToken, logout};
export default {auth, codeExchange, validateIdToken, logout, userInfo};

function retryOriginalRequest(r) {
delete r.headersOut["WWW-Authenticate"]; // Remove evidence of original failed auth_jwt
Expand Down Expand Up @@ -298,4 +298,39 @@ function idpClientAuth(r) {
} else {
return "code=" + r.variables.arg_code + "&client_secret=" + r.variables.oidc_client_secret;
}
}
}

// Return necessary user info claims after receiving and extracting all claims
// that are received from the OpenID Connect Provider(OP).
function userInfo(r) {
r.subrequest('/_userinfo',
function(res) {
if (res.status == 200) {
var error_log = "OIDC userinfo JSON failure";
var claimsOP = ''; // Claims that are received by the OP.
try {
claimsOP = JSON.parse(res.responseBody);
} catch (e) {
error_log += ": " + res.responseBody;
r.error(error_log);
r.return(500);
return;
}
// The claimsRP is to extract claims that are configured in
// $oidc_userinfo_required_claims in the RP and send them to
// the client using the response of the OP.
var claimsRP = r.variables.oidc_userinfo_required_claims.split(",");
var ret = {};
for (var i in claimsRP) {
if (claimsRP[i] in claimsOP) {
ret[claimsRP[i]] = claimsOP[claimsRP[i]];
}
}
r.variables.user_info = JSON.stringify(ret);
r.return(200, r.variables.user_info);
} else {
r.return(res.status)
}
}
);
}
20 changes: 20 additions & 0 deletions openid_connect.server_conf
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,26 @@
error_page 500 502 504 @oidc_error;
}

location = /userinfo {
# This location is to provide signed-in user information claims that are
# defined in $oidc_userinfo_required_claims.
default_type application/json;
if ($oidc_userinfo_required_claims = '') {
return 200 '{"name": "", "message":"details not provided per your policy"}';
}
js_content oidc.userInfo;
}

location = /_userinfo {
# This location is called by oidc.userInfo() when calling /userinfo
# to get signed-in user information from the OP:
# - https://openid.net/specs/openid-connect-core-1_0.html#UserInfo
internal;
proxy_ssl_server_name on; # For SNI to the IdP
proxy_set_header Authorization "Bearer $access_token";
proxy_pass $oidc_userinfo_endpoint;
}

location = /logout {
status_zone "OIDC logout";
add_header Set-Cookie "auth_token=; $oidc_cookie_flags"; # Send empty cookie
Expand Down
13 changes: 13 additions & 0 deletions openid_connect_configuration.conf
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,19 @@ map $host $oidc_jwt_keyfile {
default "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/certs";
}

map $host $oidc_userinfo_endpoint {
default "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/userinfo";
}

map $host $oidc_userinfo_required_claims {
# The $oidc_userinfo_endpoint returns OP's response that contains default or
# customized claims. This is used for scenarios where the SPA needs to show
# user name or specific profiles instead of forwarding the response from the
# OP to the SPA to minimize exposure of user info claims.
default "";
#www.example.com "sub,name,preferred_username,given_name,family_name,email,photo";
}

map $host $oidc_client {
default "my-client-id";
}
Expand Down

0 comments on commit 312304f

Please sign in to comment.