-
Notifications
You must be signed in to change notification settings - Fork 144
feat: HMAC SHA256 Authentication #795
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
41 commits
Select commit
Hold shift + click to select a range
0c551dc
Initial work on HMAC implementation.
tswagger f634172
Authenticator test pass
tswagger 52b5d8b
Authenticator test pass
tswagger 1a7802e
Added HMAC Filter tests. Pass
tswagger 1cd518f
Added documentation
tswagger 91adb87
Added missing helper
tswagger 50d70e2
Minor syntax fix
tswagger 5be8b2c
Codeing standards cleanup
tswagger 89f38a8
Clarified Return statements
tswagger 2adcdbd
Update docs/guides/api_hmac_keys.md
tswagger bbc2496
Update docs/guides/api_hmac_keys.md
tswagger 1243efc
Minor typo fix, clarification of key vs secretKey
tswagger 498e685
Update docs/authentication.md
tswagger ac61035
Renamed 'HMAC' in the code to a consistent 'Hmac'
tswagger c8058f7
Update docs/authentication.md
tswagger 755a99c
Update docs/authentication.md
tswagger 19d7cea
Update docs/authentication.md
tswagger 72b9a70
Update docs/authentication.md
tswagger daee371
Update docs/guides/api_hmac_keys.md
tswagger 8990cef
Update docs/guides/api_hmac_keys.md
tswagger 5f56a55
Added ToC entries.
tswagger 4b452b9
Added CURLRequest example
tswagger 547e455
Update docs/guides/api_hmac_keys.md
tswagger 65853f7
Update docs/guides/api_hmac_keys.md
tswagger 9f9506d
Improved HMAC Docs
tswagger 7791f87
Updated phpdpd to suppress errors from HMAC Addition
tswagger b5d7fa1
Updated login recording to match JWT Authorization
tswagger d8e4262
Update src/Authentication/Authenticators/HmacSha256.php
tswagger 6ac224e
Added HMAC References to installation documentation
tswagger 08e0b8e
Cleaned up table formatting in markdown
tswagger bbcf8b5
Updated byte size for HMAC Secret Key
tswagger f47891a
Update tests/Authentication/Authenticators/HmacAuthenticatorTest.php
tswagger 10147cf
Update tests/Authentication/Authenticators/HmacAuthenticatorTest.php
tswagger 2eb3588
Initial fix to PHPStan errors
tswagger 37c9f82
Syntax adjustment
tswagger 58b6042
Added additional test
tswagger 76baf80
Added additional tests
tswagger f57f45f
Fix to test
tswagger 968997a
Removed redundant comment
tswagger a1b64db
Added config copy to Setup script
tswagger 9d223a4
Minor fix in docs
tswagger File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,115 @@ | ||
| # Protecting an API with HMAC Keys | ||
|
|
||
| > **Note** | ||
| > For the purpose of this documentation and to maintain a level of consistency with the Authorization Tokens, | ||
| the term "Token" will be used to represent a set of API Keys (key and secretKey). | ||
|
|
||
| HMAC Keys can be used to authenticate users for your own site, or when allowing third-party developers to access your | ||
| API. When making requests using HMAC keys, the token should be included in the `Authorization` header as an | ||
| `HMAC-SHA256` token. | ||
|
|
||
| > **Note** | ||
| > By default, `$authenticatorHeader['hmac']` is set to `Authorization`. You can change this value by | ||
| > setting the `$authenticatorHeader['hmac']` value in the **app/Config/Auth.php** config file. | ||
|
|
||
| Tokens are issued with the `generateHmacToken()` method on the user. This returns a | ||
| `CodeIgniter\Shield\Entities\AccessToken` instance. These shared keys are saved to the database in plain text. The | ||
| `AccessToken` object returned when you generate it will include a `secret` field which will be the `key` and a `secret2` | ||
| field that will be the `secretKey`. You should display the `secretKey` to your user once, so they have a chance to copy | ||
| it somewhere safe, as this is the only time you should reveal this key. | ||
|
|
||
| The `generateHmacToken()` method requires a name for the token. These are free strings and are often used to identify | ||
| the user/device the token was generated from/for, like 'Johns MacBook Air'. | ||
|
|
||
| ```php | ||
| $routes->get('/hmac/token', static function () { | ||
| $token = auth()->user()->generateHmacToken(service('request')->getVar('token_name')); | ||
|
|
||
| return json_encode(['key' => $token->secret, 'secretKey' => $token->secret2]); | ||
| }); | ||
| ``` | ||
|
|
||
| You can access all the user's HMAC keys with the `hmacTokens()` method on that user. | ||
|
|
||
| ```php | ||
| $tokens = $user->hmacTokens(); | ||
| foreach ($tokens as $token) { | ||
| // | ||
| } | ||
| ``` | ||
|
|
||
| ### Usage | ||
tswagger marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| In order to use HMAC Keys/Token the `Authorization` header will be set to the following in the request: | ||
|
|
||
| ``` | ||
| Authorization: HMAC-SHA256 <key>:<HMAC HASH of request body> | ||
| ``` | ||
|
|
||
| The code to do this will look something like this: | ||
|
|
||
| ```php | ||
| header("Authorization: HMAC-SHA256 {$key}:" . hash_hmac('sha256', $requestBody, $secretKey)); | ||
| ``` | ||
|
|
||
| ## HMAC Keys Permissions | ||
|
|
||
| HMAC keys can be given `scopes`, which are basically permission strings, for the HMAC Token/Keys. This is generally not | ||
| the same as the permission the user has, but is used to specify the permissions on the API itself. If not specified, the | ||
| token is granted all access to all scopes. This might be enough for a smaller API. | ||
|
|
||
| ```php | ||
| $token = $user->generateHmacToken('token-name', ['users-read']); | ||
| return json_encode(['key' => $token->secret, 'secretKey' => $token->secret2]); | ||
| ``` | ||
|
|
||
| > **Note** | ||
| > At this time, scope names should avoid using a colon (`:`) as this causes issues with the route filters being | ||
| > correctly recognized. | ||
|
|
||
| When handling incoming requests you can check if the token has been granted access to the scope with the `hmacTokenCan()` method. | ||
|
|
||
| ```php | ||
| if ($user->hmacTokenCan('users-read')) { | ||
| // | ||
| } | ||
| ``` | ||
|
|
||
| ### Revoking Keys/Tokens | ||
|
|
||
| Tokens can be revoked by deleting them from the database with the `revokeHmacToken($key)` or `revokeAllHmacTokens()` methods. | ||
|
|
||
| ```php | ||
| $user->revokeHmacToken($key); | ||
| $user->revokeAllHmacTokens(); | ||
| ``` | ||
|
|
||
| ## Protecting Routes | ||
|
|
||
| The first way to specify which routes are protected is to use the `hmac` controller filter. | ||
|
|
||
| For example, to ensure it protects all routes under the `/api` route group, you would use the `$filters` setting | ||
| on **app/Config/Filters.php**. | ||
|
|
||
| ```php | ||
| public $filters = [ | ||
| 'hmac' => ['before' => ['api/*']], | ||
| ]; | ||
| ``` | ||
|
|
||
| You can also specify the filter should run on one or more routes within the routes file itself: | ||
|
|
||
| ```php | ||
| $routes->group('api', ['filter' => 'hmac'], function($routes) { | ||
| // | ||
| }); | ||
| $routes->get('users', 'UserController::list', ['filter' => 'hmac:users-read']); | ||
| ``` | ||
|
|
||
| When the filter runs, it checks the `Authorization` header for a `HMAC-SHA256` value that has the computed token. It then | ||
| parses the raw token and looks it up the `key` portion in the database. Once found, it will rehash the body of the request | ||
| to validate the remainder of the Authorization raw token. If it passes the signature test it can determine the correct user, | ||
| which will then be available through an `auth()->user()` call. | ||
|
|
||
| > **Note** | ||
| > Currently only a single scope can be used on a route filter. If multiple scopes are passed in, only the first one is checked. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.