You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+64-16Lines changed: 64 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,7 +4,7 @@ Reference implementation of NGINX Plus as relying party for OpenID Connect authe
4
4
5
5
## Description
6
6
7
-
This repository describes how to enable OpenID Connect integration for [NGINX Plus](https://www.nginx.com/products/nginx/). The solution depends on the [auth_jwt](http://nginx.org/en/docs/http/ngx_http_auth_jwt_module.html)module and as such is not suitable for [open source NGINX](http://www.nginx.org/en).
7
+
This repository describes how to enable OpenID Connect integration for [NGINX Plus](https://www.nginx.com/products/nginx/). The solution depends on NGINX Plus components ([auth_jwt module](http://nginx.org/en/docs/http/ngx_http_auth_jwt_module.html)and [key-value store](http://nginx.org/en/docs/http/ngx_http_keyval_module.html)) and as such is not suitable for [open source NGINX](http://www.nginx.org/en).
@@ -24,15 +24,23 @@ With this environment, both the client and NGINX Plus communicate directly with
24
24
25
25
NGINX Plus is configured to perform OpenID Connect authentication. Upon a first visit to a protected resource, NGINX Plus initiates the OpenID Connect authorization code flow and redirects the client to the OpenID Connect provider (IdP). When the client returns to NGINX Plus with an authorization code, NGINX Plus exchanges that code for a set of tokens by communicating directly with the IdP.
26
26
27
-
The ID Token received from the IdP is then [validated](https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation). NGINX Plus then issues a session cookie to the client using either the ID Token or the Access Token and is redirected to the original URI requested prior to authentication.
27
+
The ID Token received from the IdP is then [validated](https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation). NGINX Plus then stores the ID token in the key-value store, issues a session cookie to the client using a random string, (which becomes the key to obtain the ID token from the key-value store) and redirects the client to the original URI requested prior to authentication.
28
28
29
-
Subsequent requests to protected resources are authenticated using the session cookie by performing JWT validation.
30
-
31
-
For more information on OIDC and NGINX Plus JWT support, see [Authenticating Users to Existing Applications with OpenID Connect and NGINX Plus](https://www.nginx.com/blog/authenticating-users-existing-applications-openid-connect-nginx-plus/).
29
+
Subsequent requests to protected resources are authenticated by exchanging the session cookie for the ID Token in the key-value store. JWT validation is performed on each request, as normal, so that the ID Token validity period is enforced.
30
+
31
+
For more information on OpenID Connect and JWT validation with NGINX Plus, see [Authenticating Users to Existing Applications with OpenID Connect and NGINX Plus](https://www.nginx.com/blog/authenticating-users-existing-applications-openid-connect-nginx-plus/).
32
+
33
+
### Refresh Tokens
34
+
35
+
If a [refresh token](https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokens) was received from the IdP then it is also stored in the key-value store. When validation of the ID Token fails (typically upon expiry) then NGINX Plus sends the refresh token to the IdP. If the user's session is still valid at the IdP then a new ID token is received, validated, and updated in the key-value store. The refresh process is seamless to the client.
36
+
37
+
### Logout
38
+
39
+
Requests made to the `/logout` location invalidate both the ID token and refresh token by erasing them from the key-value store. Therefore, subsequent requests to protected resources will be treated as a first-time request and send the client to the IdP for authentication.
32
40
33
41
## Installation
34
42
35
-
OpenID Connect integration requires NGINX Plus R15 or later to be installed. See [Installing NGINX Plus](https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-plus/).
43
+
The master branch of this repo requires the most recent release of NGINX Plus. Older releases should use the branch corresponding to that NGINX Plus release. For installation instructions, see [Installing NGINX Plus](https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-plus/).
36
44
37
45
In addition, the [njs module](https://www.nginx.com/blog/introduction-nginscript/) is required for handling the interaction between NGINX Plus and the OpenID Connect provider (IdP). Install the njs module after installing NGINX Plus by running one of the following:
38
46
@@ -67,7 +75,7 @@ All files can be copied to **/etc/nginx/conf.d**
67
75
* Make a note of the `client ID` and `client secret`
68
76
69
77
* If your IdP supports OpenID Connect Discovery (usually at the URI `/.well-known/openid-configuration`) then use the `configure.sh` script to complete configuration. In this case you can skip the **frontend.conf** configuration. Otherwise:
70
-
*Download the `jwks_uri` JWK file to your NGINX Plus instance
78
+
*Obtain the URL for `jwks_uri` or download the JWK file to your NGINX Plus instance
71
79
* Obtain the URL for the **authorization endpoint**
72
80
* Obtain the URL for the **token endpoint**
73
81
@@ -78,8 +86,10 @@ Review the following files copied from the GitHub repository so that they match
78
86
***frontend.conf** - this is the reverse proxy configuration and where the IdP is configured. This file can be automatically configured by using the `configure.sh` script.
79
87
* Modify the upstream group to match your backend site or app
80
88
* Modify the `resolver` directive to match a DNS server that is capable of resolving the IdP defined in `$oidc_token_endpoint`
89
+
* Modify the URI defined in `$oidc_logout_redirect` to specify an unprotected resource to be displayed after requesting the `/logout` location
81
90
* Configure the preferred listen port and [enable SSL/TLS configuration](https://docs.nginx.com/nginx/admin-guide/security-controls/terminating-ssl-http/)
82
-
* Set the value of `$oidc_jwt_keyfile` to match the downloaded JWK file from the IdP and ensure that it is readable by the NGINX worker processes
91
+
* Set the value of `$oidc_jwt_keyfile` to specify the `jwks_uri` value or match the JWK file downloaded from the IdP (ensuring that it is readable by the NGINX worker processes)
92
+
* Comment/uncomment the `auth_jwt_key_file` or `auth_jwt_key_request` directives based on whether `$oidc_jwt_keyfile` is a file or URI, respectively
83
93
* Modify all of the `set $oidc_` directives to match your IdP configuration
84
94
* Set a unique value for `$oidc_hmac_key` to ensure nonce values are unpredictable
85
95
@@ -91,6 +101,49 @@ Review the following files copied from the GitHub repository so that they match
91
101
***openid_connect.js** - this is the JavaScript code for performing the authorization code exchange and nonce hashing
92
102
* No changes are required unless modifying the code exchange or validation process
93
103
104
+
### Configuring the Key-Value Store
105
+
106
+
The key-value store is used to maintain persistent storage for ID tokens and refresh tokens. The default configuration should be reviewed so that it suits the environment.
Each of the `keyval_zone` parameters are described below.
114
+
115
+
***zone** - Specifies the name of the key-value store and how much memory to allocate for it. Each session will typically occupy 1-2KB, depending on the size of the JWT, so scale this value to exceed the number of unique users that may authenticate.
116
+
117
+
***state** (optional) - Specifies where all of the ID Tokens in the key-value store are saved, so that sessions will persist across restart or reboot of the NGINX host. The NGINX Plus user account, typically **nginx**, must have write permission to the directory where the state file is stored. Consider creating a dedicated directory for this purpose.
118
+
119
+
***timeout** - Expired tokens are removed from the key-value store after the `timeout` value. This should be set to value slightly longer than the JWT validity period. JWT validation occurs on each request, and will fail when the expiry date (`exp` claim) has elapsed. If JWTs are issued without an `exp` claim then set `timeout` to the desired session duration. If JWTs are issued with a range of validity periods then set `timeout` to exceed the longest period.
120
+
121
+
***sync** (optional) - If deployed in a cluster, the key-value store may be synchronized across all instances in the cluster, so that all instances are able to create and validate authenticated sessions. Each instance must be configured to participate in state sharing with the [zone_sync module](http://nginx.org/en/docs/stream/ngx_stream_zone_sync_module.html) and by adding the `sync` parameter to the `keyval_zone` directives above.
122
+
123
+
## Session Management
124
+
125
+
The [NGINX Plus API](http://nginx.org/en/docs/http/ngx_http_api_module.html) is enabled in **openid_connect.server_conf** so that sessions can be monitored. The API can also be used to manage the current set of active sessions.
126
+
127
+
To query the current sessions in the key-value store:
Any errors generated by the OpenID Connect flow are logged in a separate file, `/var/log/nginx/oidc_error.log`. Check the contents of this file as it may include error responses received by the IdP.
@@ -102,21 +155,16 @@ Any errors generated by the OpenID Connect flow are logged in a separate file, `
102
155
***Authentication is successful but browser shows too many redirects**
103
156
* This is typically because the JWT sent to the browser cannot be validated, resulting in 'authorization required' `401` response and starting the authentication process again. But the user is already authenticated so is redirected back to NGINX, hence the redirect loop.
104
157
* Check the error log `/var/log/nginx/oidc_error.log` for JWT/JWK errors.
105
-
* Ensure that the JWK file (`$oidc_jwt_keyfile` variable) is correct and that the nginx workers have permission to read it.
158
+
* Ensure that the JWK file (`$oidc_jwt_keyfile` variable) is correct and that the nginx user has permission to read it.
106
159
107
160
## Support
108
161
109
-
All reference OpenID Connect implementations within the GitHub repository are supported for NGINX Plus subscribers.
110
-
111
-
## Other use cases
112
-
113
-
Subdirectories within the GitHub repository contain variations of the reference implementation for alternative OpenID Connect use cases.
162
+
This reference implementation for OpenID Connect is supported for NGINX Plus subscribers.
114
163
115
-
***opaque_session_token** - Uses the NGINX Plus key-value store to hold the ID Token, sending a random string to the client as the session token. The session token is then exchanged for the ID Token on each request. This use case is valuable when the ID Token contains sensitive information that should not reach the client.
116
-
117
164
## Changelog
118
165
119
166
***R15** Initial release of OpenID Connect reference implmentation
120
167
***R16** Added support for opaque session tokens using key-value store
121
168
***R17** Configuration now supports JSON Web Key (JWK) set to be obtained by URI
169
+
***R18** Opaque session tokens now used by default. Added support for refresh tokens. Added `/logout` location.
0 commit comments