@udibo/oauth2 0.12.2 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -5,15 +5,15 @@ Udibo's identity service, or host an authorization server for your own app. The
|
|
|
5
5
|
package includes clients, authorization and resource servers, Hono middleware,
|
|
6
6
|
React bindings, and optional login flows over your own database.
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
[udibo.com](https://www.udibo.com/) for
|
|
10
|
-
locally without a hosted account.
|
|
8
|
+
Using Udibo's managed identity service requires a Udibo account; see
|
|
9
|
+
[udibo.com](https://www.udibo.com/) for how to get one. The self-hosted examples
|
|
10
|
+
run locally without a hosted account.
|
|
11
11
|
|
|
12
12
|
## Choose your path
|
|
13
13
|
|
|
14
14
|
| Your application needs | Start here |
|
|
15
15
|
| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
|
|
16
|
-
| Udibo to handle sign-in | [Use Udibo's identity service](docs/guides/use-udibo.md) —
|
|
16
|
+
| Udibo to handle sign-in | [Use Udibo's identity service](docs/guides/use-udibo.md) — requires a Udibo account |
|
|
17
17
|
| Its own login and authorization server | [Run the quickstart](docs/quickstart.md), then [host authorization for your app](docs/guides/become-an-oauth-provider.md) |
|
|
18
18
|
| An API that accepts access tokens | [Protect an API](docs/guides/protect-an-api.md) |
|
|
19
19
|
| A React application with server-held tokens | [Juniper starter](templates/juniper/README.md) or [React Router starter](templates/react-router/README.md) |
|
|
@@ -21,6 +21,16 @@ export type ClientCredentialsGrantOptions<Client extends ClientInterface, User,
|
|
|
21
21
|
* Used for machine-to-machine authentication where the client itself
|
|
22
22
|
* is the resource owner. Does not support refresh tokens.
|
|
23
23
|
*
|
|
24
|
+
* **Only confidential clients may use it.** RFC 6749 §4.4 restricts this grant
|
|
25
|
+
* to confidential clients, so a request that presents no client secret — a
|
|
26
|
+
* public client, or a confidential client leaving its secret out — is refused
|
|
27
|
+
* with 401 `invalid_client`. Register a machine client with a secret and send
|
|
28
|
+
* that secret with HTTP Basic or as `client_secret` in the body. The grant
|
|
29
|
+
* relies on `ClientServiceInterface.getAuthenticated` refusing a public client
|
|
30
|
+
* that presents a secret, which `runClientServiceContractTests` pins. A client
|
|
31
|
+
* service written before 0.9.2 must pass `runClientServiceContractTests`, or
|
|
32
|
+
* `client_credentials` is not limited to confidential clients.
|
|
33
|
+
*
|
|
24
34
|
* **The token need not carry a user.** RFC 6749 §4.4 has no resource owner, so
|
|
25
35
|
* a `ClientServiceInterface.getUser` that resolves nothing is the conformant
|
|
26
36
|
* case, not an error: the grant issues a token whose {@linkcode Token.user} is
|
|
@@ -37,6 +47,20 @@ export declare class ClientCredentialsGrant<Client extends ClientInterface, User
|
|
|
37
47
|
readonly issuesIdToken = false;
|
|
38
48
|
/** Creates the grant from its {@linkcode ClientCredentialsGrantOptions}. */
|
|
39
49
|
constructor(options: ClientCredentialsGrantOptions<Client, User, S>);
|
|
50
|
+
/**
|
|
51
|
+
* Authenticates the client from a request that must carry its client
|
|
52
|
+
* secret, by HTTP Basic or in the body. Credentials are read through
|
|
53
|
+
* {@linkcode getClientCredentials} and checked by the grant's
|
|
54
|
+
* `clientService.getAuthenticated`.
|
|
55
|
+
*
|
|
56
|
+
* A subclass that authenticates clients by other means, such as a signed
|
|
57
|
+
* client assertion, overrides this method and must itself admit only
|
|
58
|
+
* confidential clients.
|
|
59
|
+
*
|
|
60
|
+
* @throws {InvalidClientError} If the request presents no non-empty client
|
|
61
|
+
* secret, or authentication fails.
|
|
62
|
+
*/
|
|
63
|
+
getAuthenticatedClient(request: Request, body: FormData): Promise<Client>;
|
|
40
64
|
/**
|
|
41
65
|
* Handles a token request for the client credentials grant. Issues an access
|
|
42
66
|
* token (never a refresh token) to the client acting as its own resource
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* RFC 6749 Section 4.4.
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
+
import { InvalidClientError } from "../../errors.js";
|
|
7
|
+
import { authenticateClientCredentials } from "../client-authentication.js";
|
|
6
8
|
import { AbstractGrant, } from "./grant.js";
|
|
7
9
|
/**
|
|
8
10
|
* The client credentials grant type.
|
|
@@ -11,6 +13,16 @@ import { AbstractGrant, } from "./grant.js";
|
|
|
11
13
|
* Used for machine-to-machine authentication where the client itself
|
|
12
14
|
* is the resource owner. Does not support refresh tokens.
|
|
13
15
|
*
|
|
16
|
+
* **Only confidential clients may use it.** RFC 6749 §4.4 restricts this grant
|
|
17
|
+
* to confidential clients, so a request that presents no client secret — a
|
|
18
|
+
* public client, or a confidential client leaving its secret out — is refused
|
|
19
|
+
* with 401 `invalid_client`. Register a machine client with a secret and send
|
|
20
|
+
* that secret with HTTP Basic or as `client_secret` in the body. The grant
|
|
21
|
+
* relies on `ClientServiceInterface.getAuthenticated` refusing a public client
|
|
22
|
+
* that presents a secret, which `runClientServiceContractTests` pins. A client
|
|
23
|
+
* service written before 0.9.2 must pass `runClientServiceContractTests`, or
|
|
24
|
+
* `client_credentials` is not limited to confidential clients.
|
|
25
|
+
*
|
|
14
26
|
* **The token need not carry a user.** RFC 6749 §4.4 has no resource owner, so
|
|
15
27
|
* a `ClientServiceInterface.getUser` that resolves nothing is the conformant
|
|
16
28
|
* case, not an error: the grant issues a token whose {@linkcode Token.user} is
|
|
@@ -29,6 +41,27 @@ export class ClientCredentialsGrant extends AbstractGrant {
|
|
|
29
41
|
constructor(options) {
|
|
30
42
|
super({ ...options, allowRefreshToken: false });
|
|
31
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Authenticates the client from a request that must carry its client
|
|
46
|
+
* secret, by HTTP Basic or in the body. Credentials are read through
|
|
47
|
+
* {@linkcode getClientCredentials} and checked by the grant's
|
|
48
|
+
* `clientService.getAuthenticated`.
|
|
49
|
+
*
|
|
50
|
+
* A subclass that authenticates clients by other means, such as a signed
|
|
51
|
+
* client assertion, overrides this method and must itself admit only
|
|
52
|
+
* confidential clients.
|
|
53
|
+
*
|
|
54
|
+
* @throws {InvalidClientError} If the request presents no non-empty client
|
|
55
|
+
* secret, or authentication fails.
|
|
56
|
+
*/
|
|
57
|
+
async getAuthenticatedClient(request, body) {
|
|
58
|
+
const credentials = this.getClientCredentials(request, body);
|
|
59
|
+
if (!credentials.clientSecret) {
|
|
60
|
+
throw new InvalidClientError("client authentication failed");
|
|
61
|
+
}
|
|
62
|
+
const { clientService } = await this.resolveServices(request);
|
|
63
|
+
return await authenticateClientCredentials(credentials, clientService);
|
|
64
|
+
}
|
|
32
65
|
/**
|
|
33
66
|
* Handles a token request for the client credentials grant. Issues an access
|
|
34
67
|
* token (never a refresh token) to the client acting as its own resource
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@udibo/oauth2",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "A flexible OAuth2 toolkit: framework-agnostic authorization & resource servers, a typed client, Hono adapters (including a backend-for-frontend), and React bindings.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|