Skip to content

Commit

Permalink
OIDC spec updates
Browse files Browse the repository at this point in the history
  • Loading branch information
blink1073 committed Apr 8, 2024
1 parent 7ae7fea commit 83952e7
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 15 deletions.
27 changes: 14 additions & 13 deletions source/auth/auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Drivers SHOULD contain a type called `MongoCredential`. It SHOULD contain some o
- username (string)

- Applies to all mechanisms.
- Optional for MONGODB-X509 and MONGODB-AWS.
- Optional for MONGODB-X509, MONGODB-AWS, and MONGODB-OIDC.

- source (string)

Expand Down Expand Up @@ -1361,10 +1361,10 @@ The driver MUST pass the following information to the callback:
The callback MUST be able to return the following information:

- `accessToken`: An OIDC access token string. The driver MUST NOT attempt to validate `accessToken` directly.
- `expiresIn`: An optional expiry duration for the access token. Drivers MUST interpret the value 0 as an infinite
duration and error if a negative value is returned. Drivers SHOULD use the most idiomatic type for representing a
duration in the driver's language. Note that the access token expiry value is currently not used in
[Credential Caching](#credential-caching), but is intended to support future caching optimizations.
- `expiresIn`: An optional expiry duration for the access token. Drivers with optional parameters MAY interpret a
missing value as infinite. Drivers MUST error if a negative value is returned. Drivers SHOULD use the most idiomatic
type for representing a duration in the driver's language. Note that the access token expiry value is currently not
used in [Credential Caching](#credential-caching), but is intended to support future caching optimizations.

The signature and naming of the callback API is up to the driver's discretion. Drivers MUST ensure that additional
optional input parameters and return values can be added to the callback signature in the future without breaking
Expand Down Expand Up @@ -1418,7 +1418,7 @@ An example human callback API might look like:
```typescript
interface IdpInfo {
issuer: string;
clientId: string;
clientId: Optional<string>;
requestScopes: Optional<Array<string>>;
}

Expand Down Expand Up @@ -1647,9 +1647,9 @@ Use the following algorithm to authenticate a new connection:

- Check if the the *Client Cache* has an access token.
- If it does, cache the access token in the *Connection Cache* and perform a `One-Step` SASL conversation using the
access token in the *Client Cache*. If the server returns a Authentication error (18), invalidate that access token,
sleep 100ms then continue.
- Call the configured built-in provider integration or the OIDC callback to retrieve a new access token.
access token in the *Client Cache*. If the server returns a Authentication error (18), invalidate that access token.
- Call the configured built-in provider integration or the OIDC callback to retrieve a new access token. Wait until it
has been at least 100ms since the last callback invocation, to avoid overloading the callback.
- Cache the new access token in the *Client Cache* and *Connection Cache*.
- Perform a `One-Step` SASL conversation using the new access token. Raise any errors to the user.

Expand Down Expand Up @@ -1685,14 +1685,15 @@ authenticate a new connection when a [OIDC Human Callback](#oidc-human-callback)
- Check if the *Client Cache* has an access token.
- If it does, cache the access token in the *Connection Cache* and perform a [One-Step](#one-step) SASL conversation
using the access token. If the server returns an Authentication error (18), invalidate the access token token from
the *Client Cache*, clear the *Connection Cache*, and continue. If the server returns another error, continue.
the *Client Cache*, clear the *Connection Cache*, and restart the loop. If the server returns another error, restart
the authentication flow.
- Check if the *Client Cache* has a refresh token.
- If it does, call the [OIDC Human Callback](#oidc-human-callback) with the cached refresh token and `IdpInfo` to get
a new access token. Cache the new access token in the *Client Cache* and *Connection Cache*. Perform a
[One-Step](#one-step) SASL conversation using the new access token. If the
[OIDC Human Callback](#oidc-human-callback) or the server returns an Authentication error (18), invalidate the
access token from the *Client Cache*, clear the *Connection Cache*, and continue. If the server returns another
error, continue.
access token from the *Client Cache*, clear the *Connection Cache*, and restart the authentication flow. If the
server returns another error, restart the authentication flow.
- Start a new [Two-Step](#two-step) SASL conversation.
- Run a `PrincipalStepRequest` to get the `IdpInfo`.
- Call the [OIDC Human Callback](#oidc-human-callback) with the new `IdpInfo` to get a new access token and optional
Expand All @@ -1714,7 +1715,7 @@ Use the following algorithm to perform speculative authentication:
- If it does, cache the access token in the *Connection Cache* and send a `JwtStepRequest` with the cached access
token in the speculative authentication SASL payload. If the response is missing a speculative authentication
document or the speculative authentication document indicates authentication was not successful, clear the the
*Connection Cache* and continue.
*Connection Cache* and proceed to the next step.
- Authenticate with the standard authentication handshake.

Example code for speculative authentication using the `auth` function described above:
Expand Down
4 changes: 2 additions & 2 deletions source/auth/tests/legacy/connection-string.yml
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ tests:
uri: mongodb://user:pass@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:test
valid: false
credential:
- description: should throw an exception if username is specified for aws (MONGODB-OIDC)
- description: should throw an exception if username is specified for test (MONGODB-OIDC)
uri: mongodb://principalName@localhost/?authMechanism=MONGODB-OIDC&ENVIRONMENT:test
valid: false
credential:
Expand All @@ -389,4 +389,4 @@ tests:
- description: should throw an exception when unsupported auth property is specified (MONGODB-OIDC)
uri: mongodb://localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=UnsupportedProperty:unexisted
valid: false
credential:
credential:
18 changes: 18 additions & 0 deletions source/auth/tests/mongodb-oidc.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,24 @@ Drivers MUST be able to authenticate using OIDC callback(s) when there is one pr
- Assert that a `find` operation fails with a client-side error.
- Close the client.

**1.7 Allowed Hosts in Connection String Ignored**

- Create an OIDC configured client with the connection string:
`mongodb+srv://example.com/?authMechanism=MONGODB-OIDC&authMechanismProperties=ALLOWED_HOSTS:%5B%22example.com%22%5D`
and a Human Callback.
- Assert that the creation of the client raises a configuration error.

**1.8 Machine IdP with Human Callback**

This test MUST only be run when `OIDC_IS_LOCAL` is set. This indicates that the server is local and not using Atlas. In
this case, `MONGODB_URI_SINGLE` will be configured with a human user `test_user1`, and a machine user `test_machine`.
This test uses the machine user with a human callback, ensuring that the missing `clientId` in the
`PrincipalStepRequest` response is handled by the driver.

- Create an OIDC configured client with `MONGODB_URI_SINGLE` and a username of `test_machine`.
- Perform a find operation that succeeds.
- Close the client.

### (2) OIDC Human Callback Validation

**2.1 Valid Callback Inputs**
Expand Down

0 comments on commit 83952e7

Please sign in to comment.