Skip to content

Commit

Permalink
docs(provider): 📝 Added AWS Cognito; Updated providers section
Browse files Browse the repository at this point in the history
  • Loading branch information
itpropro committed Sep 23, 2024
1 parent 3da9e5d commit 1e18b15
Show file tree
Hide file tree
Showing 15 changed files with 264 additions and 201 deletions.
117 changes: 103 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ If you are looking for a module that supports local authentication (and more) pr

### Recent breaking changes

:warning: Since 0.16.0, the data from the providers userInfo endpoint is written into `userInfo` on the user object instead of `providerInfo`.
⚠️ Since 0.16.0, the data from the providers userInfo endpoint is written into `userInfo` on the user object instead of `providerInfo`.
Please adjust your `nuxt.config.ts` and .env/environment files and configurations accordingly.
The `useOidcAuth` composable has introduced an alias from `providerInfo` to `userInfo`, but this will be removed in future versions.
If you are using the user object from the `useOidcAuth` composable change the access to `providerInfo` to `userInfo`.

## Installation

Expand Down Expand Up @@ -332,7 +332,7 @@ The following hooks are available to extend the default behavior of the OIDC mod
- `clear` (Called before a user session is cleared)
- `refresh` (Called before a user session is refreshed)

:warning: Remember to also update the refresh hook if you modify the session, as claims and other fields would otherwise be wiped.
⚠️ Remember to also update the refresh hook if you modify the session, as claims and other fields would otherwise be wiped.

#### Example

Expand Down Expand Up @@ -435,7 +435,7 @@ export default defineNuxtConfig({
| additionalAuthParameters | `Record<string, string>` (optional) | - | Additional parameters to be added to the authorization request. See [Provider specific configurations](#provider-specific-configurations) for possible parameters. |
| additionalTokenParameters | `Record<string, string>` (optional) | - | Additional parameters to be added to the token request. See [Provider specific configurations](#provider-specific-configurations) for possible parameters. |
| baseUrl | `string` (optional) | - | Base URL for the provider, used when to dynamically create authorizationUrl, tokenUrl, userInfoUrl and logoutUrl if possible. |
| openIdConfiguration | `Record<string, unknown>` or `function (config) => Record<string, unknown>` (optional) | - | OpenID Configuration object or function promise that resolves to an OpenID Configuration object. |
| openIdConfiguration | `string` or `Record<string, unknown>` or `function (config) => Record<string, unknown>` (optional) | - | OpenID Configuration url, object or function promise that resolves to an OpenID Configuration object. |
| validateAccessToken | `boolean` (optional) | `true` | Validate access token. |
| validateIdToken | `boolean` (optional) | `true` | Validate id token. |
| encodeRedirectUri | `boolean` (optional) | `false` | Encode redirect uri query parameter in authorization request. Only for compatibility with services that don't implement proper parsing of query parameters. |
Expand Down Expand Up @@ -476,29 +476,95 @@ The following options are available on every provider as overrides for the globa

Some providers have specific additional fields that can be used to extend the authorization or token request. These fields are available via. `additionalAuthParameters` or `additionalTokenParameters` in the provider configuration.

:warning: Tokens will only be validated if the `clientId` or the optional `audience` field is part of the access_tokens audiences. Even if `validateAccessToken` or `validateIdToken` is set, if the audience doesn't match, the token should not and will not be validated.
⚠️ Tokens will only be validated if the `clientId` or the optional `audience` field is part of the access_tokens audiences. Even if `validateAccessToken` or `validateIdToken` is set, if the audience doesn't match, the token should not and will not be validated.

The `redirectUri` property is always required.

### Auth0

additionalAuth/TokenParameters:
**Provider support:**

&nbsp; PKCE<br>
&nbsp; Nonce<br>
&nbsp; State<br>
&nbsp; Access Token validation<br>
&nbsp; ID Token validation<br>

**Instructions**

Additional parameters to be used in additionalAuthParameters,
additionalTokenParameters or additionalLogoutParameters:

| Option | Type | Default | Description |
|---|---|---|---|
| connection | `string` | - | Optional. Specifies the connection. |
| organization | `string` | - | Optional. Specifies the organization. |
| invitation | `string` | - | Optional. Specifies the invitation. |
| loginHint | `string` | - | Optional. Specifies the login hint. |
| connection | `string` | - | Optional. Forces the user to sign in with a specific connection. For example, you can pass a value of github to send the user directly to GitHub to log in with their GitHub account. When not specified, the user sees the Auth0 Lock screen with all configured connections. You can see a list of your configured connections on the Connections tab of your application. |
| organization | `string` | - | Optional. ID of the organization to use when authenticating a user. When not provided, if your application is configured to Display Organization Prompt, the user will be able to enter the organization name when authenticating. |
| invitation | `string` | - | Optional. Ticket ID of the organization invitation. When inviting a member to an Organization, your application should handle invitation acceptance by forwarding the invitation and organization key-value pairs when the user accepts the invitation. |
| loginHint | `string` | - | Optional. Populates the username/email field for the login or signup page when redirecting to Auth0. Supported by the Universal Login experience. |
| audience | `string` | - | Optional. The unique identifier of the API your web app wants to access. |

Depending on the settings of your apps `Credentials` tab, set `authenticationScheme` to `body` for 'Client Secret (Post)', set to `header` for 'Client Secret (Basic)', set to `''` for 'None'

### AWS Cognito

**Provider support:**

- Depending on the settings of your apps `Credentials` tab, set `authenticationScheme` to `body` for 'Client Secret (Post)', set to `header` for 'Client Secret (Basic)', set to `''` for 'None'
&nbsp; PKCE<br>
&nbsp; Nonce<br>
&nbsp; State<br>
&nbsp; Access Token validation<br>
&nbsp; ID Token validation<br>

AWS Congito doesn't correctly implement the OAuth 2 standard and doesn't provide a `aud` field for the audience. Therefore it is not possible to verify the access or id token.

**Instructions**

For AWS Cognito you have to provide at least the `baseUrl`, `clientId`, `clientSecret` and `logoutRedirectUri` properties. The `baseUrl` is used to dynamically create the `authorizationUrl`, `tokenUrl`, `logoutUrl` and `userInfoUrl`.
The only supported OAuth grant type is `Authorization code grant`.
The final url should look something like this `https://cognito-idp.eu-north-1.amazonaws.com/eu-north-1_SOMEID/.well-known/openid-configuration`.
You will also encounter an error, if you have not correctly registered the `redirectUri` under "Allowed callback URLs" or the `logoutRedirectUri` under "Allowed sign-out URLs".
If you need additional scopes, specify them in the `scope` property in you nuxt config like `scope: ['openid', 'email', 'profile'],`.

### Entra ID/Microsoft

**Provider support:**

&nbsp; PKCE<br>
&nbsp; Nonce<br>
&nbsp; State<br>
⚠️&nbsp; Access Token validation (Supported, but disabled as only possible for custom audience tokens)<br>
&nbsp; ID Token validation<br>

**Instructions**

Additional parameters to be used in additionalAuthParameters,
additionalTokenParameters or additionalLogoutParameters:

| Option | Type | Default | Description |
|---|---|---|---|
| resource | `string` | - | Optional. The resource identifier for the requested resource. |
| audience | `string` | - | Optional. The audience for the token, typically the client ID. |
| prompt | `string` | - | Optional. Indicates the type of user interaction that is required. Valid values are login, none, consent, and select_account. |
| loginHint | `string` | - | Optional. You can use this parameter to pre-fill the username and email address field of the sign-in page for the user. Apps can use this parameter during reauthentication, after already extracting the login_hint optional claim from an earlier sign-in. |
| logoutHint | `string` | - | Optional. Enables sign-out to occur without prompting the user to select an account. To use logout_hint, enable the login_hint optional claim in your client application and use the value of the login_hint optional claim as the logout_hint parameter. |
| domainHint | `string` | - | Optional. If included, the app skips the email-based discovery process that user goes through on the sign-in page, leading to a slightly more streamlined user experience. |

If you want to validate access tokens from Microsoft Entra ID (previously Azure AD), you need to make sure that the scope includes your own API. You have to register an API first and expose some scopes to your App Registration that you want to request. If you only have GraphAPI entries like `openid`, `mail` GraphAPI specific ones in your scope, the returned access token cannot and should not be verified. If the scope is set correctly, you can set `validateAccessToken` option to `true`.

If you use this module with Entra ID for Customers make sure you have set the `audience` config field to your application id, otherwise it will not be possible to get a valid OpenID Connect well-known configuration and thereby verify the JWT token.
If you use this module with Entra External ID (previously Entra ID for Customers) make sure you have set the `audience` config field to your application id, otherwise it will not be possible to get a valid OpenID Connect well-known configuration and thereby verify the JWT token.

### GitHub

**Provider support:**

&nbsp; PKCE<br>
&nbsp; Nonce<br>
&nbsp; State<br>
&nbsp; Access Token validation<br>
&nbsp; ID Token validation<br>

**Instructions**

GitHub is not strictly an OIDC provider, but it can be used as one. Make sure that validation is disabled and that you keep the `skipAccessTokenParsing` option to `true`.

Try to use a [GitHub App](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/differences-between-github-apps-and-oauth-apps), not the legacy OAuth app. They don't provide the same level of security, have no granular permissions, don't provide refresh tokens and are not tested.
Expand All @@ -507,8 +573,31 @@ Make sure to set the callback URL in your OAuth app settings as `<your-domain>/a

### Keycloak

For Keycloak you have to provide at least the `baseUrl`, `clientId` and `clientSecret` properties. The `baseUrl` is used to dynamically create the `authorizationUrl`, `tokenUrl` and `userInfoUrl`.
**Provider support:**

&nbsp; PKCE<br>
&nbsp; Nonce<br>
&nbsp; State<br>
&nbsp; Access Token validation<br>
&nbsp; ID Token validation<br>

**Instructions**

Additional parameters to be used in additionalAuthParameters,
additionalTokenParameters or additionalLogoutParameters:

| Option | Type | Default | Description |
|---|---|---|---|
| realm | `string` | - | Optional. This parameter allows to slightly customize the login flow on the Keycloak server side. For example, enforce displaying the login screen in case of value login. |
| realm | `string` | - | Optional. Used to pre-fill the username/email field on the login form. |
| realm | `string` | - | Optional. Used to tell Keycloak to skip showing the login page and automatically redirect to the specified identity provider instead. |
| realm | `string` | - | Optional. Sets the 'ui_locales' query param. |

For more information on these parameters, check the [KeyCloak documentation](https://www.keycloak.org/docs/latest/securing_apps/#methods).

For Keycloak you have to provide at least the `baseUrl`, `clientId` and `clientSecret` properties. The `baseUrl` is used to dynamically create the `authorizationUrl`, `tokenUrl`, `logoutUrl` and `userInfoUrl`.
Please include the realm you want to use in the `baseUrl` (e.g. `https://<keycloak-url>/realms/<realm>`).
If you don't want to use the post logout redirect feature of key cloak, set `logoutUrl` to `undefined` or `''`.
Also remember to enable `Client authentication` to be able to get a client secret.

## Dev mode
Expand Down Expand Up @@ -543,7 +632,7 @@ The properties on the generated token are
- `sub`: `devMode.subject` setting, default `nuxt:oidc:auth:subject`
- `exp`: current DateTime + 24h

:warning: The access token will be generated with a fixed local secret and can in no way be considered secure. Dev mode can only be enabled in local development and should exclusively be used there for testing purposes. Never set any environment variables on your production systems that could put any component into development mode.
⚠️ The access token will be generated with a fixed local secret and can in no way be considered secure. Dev mode can only be enabled in local development and should exclusively be used there for testing purposes. Never set any environment variables on your production systems that could put any component into development mode.

## Contributing

Expand Down
14 changes: 7 additions & 7 deletions playground/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,17 @@ export default defineNuxtConfig({
responseType: 'code id_token',
scope: ['profile', 'openid', 'offline_access', 'email'],
logoutUrl: '',
optionalClaims: ['unique_name', 'family_name', 'given_name'],
optionalClaims: ['unique_name', 'family_name', 'given_name', 'login_hint'],
audience: '',
additionalAuthParameters: {
resource: '',
prompt: 'select_account',
},
validateAccessToken: false,
validateIdToken: true,
exposeIdToken: false,
exposeAccessToken: true,
additionalLogoutParameters: {
logoutHint: '',
},
exposeIdToken: true,
exposeAccessToken: false,
allowedClientAuthParameters: [
'test',
],
Expand Down Expand Up @@ -64,7 +65,7 @@ export default defineNuxtConfig({
clientId: '',
clientSecret: '',
redirectUri: 'http://localhost:3000/auth/keycloak/callback',
exposeAccessToken: true,
exposeAccessToken: false,
userNameClaim: 'preferred_username',
},
cognito: {
Expand All @@ -74,7 +75,6 @@ export default defineNuxtConfig({
scope: ['openid', 'email', 'profile'],
logoutRedirectUri: 'https://google.com',
baseUrl: '',
openIdConfiguration: '',
}
},
session: {
Expand Down
2 changes: 1 addition & 1 deletion playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@
"@iconify-json/simple-icons": "^1.2.3",
"@nuxtjs/color-mode": "^3.5.1",
"@unocss/nuxt": "^0.62.4",
"nuxt-oidc-auth": "latest"
"nuxt-oidc-auth": "workspace:^"
}
}
3 changes: 2 additions & 1 deletion playground/pages/auth/login.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ definePageMeta({
})
const { currentProvider, login, user } = useOidcAuth()
const { providers } = useProviders(currentProvider.value as string)
// use `@click="login(provider.name as any, { test: 'thiswillappearinentra', test2: 'thiswillbeignored' })"` for testing the logout params
</script>

<template>
Expand All @@ -13,7 +14,7 @@ const { providers } = useProviders(currentProvider.value as string)
:key="index"
class="btn-base btn-login"
:disabled="provider.disabled"
@click="login(provider.name as any, { test: 'thiswillappearinentra', test2: 'thiswillbeignored' })"
@click="login(provider.name as any)"
>
<span :class="provider.icon" />
<span class="pl-2">{{ provider.label }}</span>
Expand Down
10 changes: 9 additions & 1 deletion playground/pages/index.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
const { loggedIn, user, refresh, login, logout, currentProvider, clear } = useOidcAuth()
const { loggedIn, user, refresh, fetch, login, logout, currentProvider, clear } = useOidcAuth()
const { providers } = useProviders(currentProvider.value as string)
</script>

Expand Down Expand Up @@ -36,6 +36,14 @@ const { providers } = useProviders(currentProvider.value as string)
<span class="i-majesticons-refresh" />
<span class="pl-2">Refresh</span>
</button>
<button
class="btn-base btn-login"
:disabled="!loggedIn"
@click="fetch()"
>
<span class="i-majesticons-refresh" />
<span class="pl-2">Fetch</span>
</button>
<button
class="btn-base btn-login"
:disabled="!loggedIn"
Expand Down
Loading

0 comments on commit 1e18b15

Please sign in to comment.