-
Notifications
You must be signed in to change notification settings - Fork 140
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rework authentication based on Authentication extension, implement HT…
…TP Basic and OpenID Connect (#439) * Rework authentication based on STAC extension * Add OpenID Connect support * Fix authConfig with API key is broken #446
- Loading branch information
Showing
34 changed files
with
1,200 additions
and
273 deletions.
There are no files selected for viewing
This file contains 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 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 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 |
---|---|---|
|
@@ -288,25 +288,44 @@ Please note that this option can only be provided through a config file and is n | |
|
||
***experimental*** | ||
|
||
This allows to enable a simple authentication form where a user can input a token, an API key or similar things. | ||
It is disabled by default (`null`). If enabled, the token provided by the user can be used in the HTTP headers or in the query parameters of the requests. This option is affected by [`allowedDomains`](#alloweddomains). | ||
This allows to enable some authentication methods. Currently the supported methods are: | ||
- API Keys (`type: apiKey`) via query parameter or HTTP Header | ||
- HTTP Basic (`type: http`, `scheme: basic`) | ||
- OpenID Connect (`type: openIdConnect`) | ||
|
||
There are four options you can set in the `authConfig` object: | ||
Authentication is disabled by default (`null`). | ||
|
||
* `type` (string): `null` (disabled), `"query"` (use token in query parameters), or `"header"` (use token in HTTP request headers). | ||
* `key` (string): The query string parameter name or the HTTP header name respecively. | ||
* `formatter` (function|string|null): You can optionally specify a formatter for the query string value or HTTP header value respectively. If the string `"Bearer"` is provided formats as a Bearer token according to RFC 6750. If not given, the token is provided as provided by the user. | ||
* `description` (string|null): Optionally a description that is shown to the user. This should explain how the token can be obtained for example. CommonMark is allowed. | ||
The options you can set in the `authConfig` object are defined in the | ||
[Authentication Scheme Object of the STAC Authentication Extension](https://github.com/stac-extensions/authentication?tab=readme-ov-file#authentication-scheme-object) (limited by the supported methods listed above). | ||
|
||
**Note:** Before STAC Browser 3.2.0 a different type of object was supported. | ||
The old way is deprecated, but will be converted to the new object internally. | ||
Please migrate to the new configuration options now. | ||
|
||
In addition the following properties are supported: | ||
|
||
* `formatter` (function|string|null): You can optionally specify a formatter for the query string value or HTTP header value respectively. If the string `"Bearer"` is provided formats as a Bearer token according to RFC 6750. If not given, the token is sent as provided by the user. | ||
* `description` (string|null): Optionally a description that is shown to the user. This should explain how the credentials can be obtained for example. CommonMark is allowed. | ||
**Note:** You can leave the description empty in the config file and instead provide a localized string with the key `authConfig` -> `description` in the file for custom phrases (`src/locales/custom.js`). | ||
|
||
Please note that this option can only be provided through a config file and is not available via CLI/ENV. | ||
Authentication is generally affected by the [`allowedDomains`](#alloweddomains) option. | ||
|
||
The `authConfig` option can only be provided through a config file and is not available via CLI/ENV. | ||
|
||
### API Keys | ||
|
||
API keys can be configured to be sent via HTTP header or query parameter: | ||
|
||
### Example 1: HTTP Request Header Value | ||
- For query parameters you need to set `in: query` with a respective `name` for the query parameter | ||
- For HTTP headers you need to set `in: header` with a respective `name` for the header field | ||
|
||
#### Example 1: HTTP Request Header Value | ||
|
||
```js | ||
{ | ||
type: 'header', | ||
key: 'Authorization', | ||
type: 'apiKey', | ||
in: 'header', | ||
name: 'Authorization', | ||
formatter: token => `Bearer ${token}`, // This is an example, there's also the simpler variant to just provide the string 'Bearer' in this case | ||
description: `Please retrieve the token from our [API console](https://example.com/api-console).\n\nFor further questions contact <mailto:[email protected]>.` | ||
} | ||
|
@@ -315,18 +334,57 @@ Please note that this option can only be provided through a config file and is n | |
For a given token `123` this results in the following additional HTTP Header: | ||
`Authorization: Bearer 123` | ||
|
||
### Example 2: Query Parameter Value | ||
#### Example 2: Query Parameter Value | ||
|
||
```js | ||
{ | ||
type: 'query', | ||
key: 'API_KEY' | ||
type: 'apiKey', | ||
in: 'query', | ||
name: 'API_KEY' | ||
} | ||
``` | ||
|
||
For a given token `123` this results in the following query parameter: | ||
`https://example.com/stac/catalog.json?API_KEY=123` | ||
|
||
### HTTP Basic | ||
|
||
HTTP Basic is supported according to [RFC 7617](https://datatracker.ietf.org/doc/html/rfc7617). | ||
|
||
**Example:** | ||
|
||
```js | ||
{ | ||
type: 'http', | ||
scheme: 'basic' | ||
} | ||
``` | ||
|
||
### OpenID Connect | ||
|
||
**IMPORTANT: OpenID Connect is only supported if `historyMode` is set to `history`!** | ||
|
||
For OpenID Connect some additional options must be provided, which currently follow the | ||
[oidc-client-ts Configuration options](https://github.com/okta/okta-auth-js?tab=readme-ov-file#configuration-options). | ||
These options (except for `issuer`) must be provided in the property `oidcConfig`. | ||
The `clientId` option defaults to `stac-browser`. | ||
The redirect URL for the OIDC client must be set as follows: | ||
|
||
#### Example | ||
|
||
```js | ||
{ | ||
type: 'openIdConnect', | ||
openIdConnectUrl: 'https://stac.example/.well-known/openid-configuration', | ||
oidcOptions: { | ||
client_id: 'abc123' | ||
} | ||
} | ||
``` | ||
|
||
For a given token `123` this results in the following additional HTTP Header: | ||
`Authorization: Bearer 123` | ||
|
||
## preprocessSTAC | ||
|
||
***experimental*** | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains 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 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 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,59 @@ | ||
import Auth from "./index"; | ||
import i18n from '../i18n'; | ||
import Utils from "../utils"; | ||
|
||
export default class ApiKey extends Auth { | ||
|
||
constructor(options, changeListener, router) { | ||
super(options, changeListener, router); | ||
} | ||
|
||
getButtonTitle() { | ||
return i18n.t('authentication.button.title'); | ||
} | ||
|
||
getComponent() { | ||
return 'ApiKey'; | ||
} | ||
|
||
getComponentProps() { | ||
return { | ||
description: this.options.description | ||
}; | ||
} | ||
|
||
async logout(/*credentials*/) { | ||
if (this.router.currentRoute.name !== 'logout') { | ||
this.router.push('/auth/logout'); | ||
} | ||
return true; | ||
} | ||
|
||
updateStore(value) { | ||
if (value) { | ||
if (this.options.formatter === 'Bearer') { | ||
value = `Bearer ${value}`; | ||
} | ||
else if (typeof this.options.formatter === 'function') { | ||
value = this.options.formatter(value); | ||
} | ||
} | ||
if (!Utils.hasText(value)) { | ||
value = undefined; | ||
} | ||
|
||
// Set query or request parameters | ||
let key = this.options.name; | ||
if (this.options.in === 'query') { | ||
return { | ||
query: { type: 'private', key, value } | ||
}; | ||
} | ||
else if (this.options.in === 'header') { | ||
return { | ||
header: { key, value } | ||
}; | ||
} | ||
} | ||
|
||
} |
This file contains 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,44 @@ | ||
import Auth from "./index"; | ||
import i18n from '../i18n'; | ||
import Utils from "../utils"; | ||
|
||
export default class BasicAuth extends Auth { | ||
|
||
constructor(options, changeListener, router) { | ||
super(options, changeListener, router); | ||
} | ||
|
||
getComponent() { | ||
return 'Basic'; | ||
} | ||
|
||
getComponentProps() { | ||
return { | ||
description: this.options.description | ||
}; | ||
} | ||
|
||
getButtonTitle() { | ||
return i18n.t('authentication.button.title'); | ||
} | ||
|
||
async logout(/*credentials*/) { | ||
if (this.router.currentRoute.name !== 'logout') { | ||
this.router.push('/auth/logout'); | ||
} | ||
return true; | ||
} | ||
|
||
updateStore(value) { | ||
if (typeof value === 'string' && value.length >= 3) { | ||
value = `Basic ${btoa(value)}`; | ||
} | ||
if (!Utils.hasText(value)) { | ||
value = undefined; | ||
} | ||
return { | ||
header: { key: 'Authorization', value } | ||
}; | ||
} | ||
|
||
} |
Oops, something went wrong.