includes.security.providers.oidc.adoc Maven / Gradle / Ivy
///////////////////////////////////////////////////////////////////////////////
Copyright (c) 2018, 2024 Oracle and/or its affiliates.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
///////////////////////////////////////////////////////////////////////////////
ifndef::rootdir[:rootdir: {docdir}/../../..]
:basic-table-intro: The table below lists the configuration keys that identify the CORS characteristics.
:cors-config-key-explanation: , identified with the configuration key 'cors',
:cors-config-table-exclude-methods: true
:feature-name: OIDC Security Provider
include::{rootdir}/config/io_helidon_security_providers_oidc_OidcProvider.adoc[leveloffset=+2,tag=config]
=== Example code
See the link:{helidon-github-tree-url}/examples/security/idcs-login[example] on GitHub.
[source,yaml]
.Configuration example
----
security:
providers:
- oidc:
client-id: "client-id-of-this-service"
client-secret: "${CLEAR=changeit}"
identity-uri: "https://your-tenant.identity-server.com"
frontend-uri: "http://my-service:8080"
audience: "http://my-service"
cors:
allow-origins: ["https://foo.com", "https://there.com"]
allow-methods: ["PUT", "DELETE"]
outbound:
- name: "internal-services"
hosts: ["*.example.org"]
outbound-token:
header: "X-Internal-Auth"
----
[[oidc-workflow]]
=== How does it work?
At Helidon startup, if OIDC provider is configured, the following will happen:
1. `client-id`, `client-secret`, and `identityUri` are validated - these must provide values
2. Unless all resources are configured as local resources, the provider attempts
to contact the `oidc-metadata.resource` endpoint to retrieve all endpoints
At runtime, depending on configuration...
If a request comes without a token or with insufficient scopes:
1. If `redirect` is set to `true` (default), request is redirected to the authorization
endpoint of the identity server. If set to false, `401` is returned
2. User authenticates against the identity server
3. The identity server redirects back to Helidon service with a code
4. Helidon service contacts the identity server's token endpoint, to exchange the code
for a JWT
5. The JWT is stored in a cookie (if cookie support is enabled, which it is by default)
6. Helidon service redirects to original endpoint (on itself)
Helidon obtains a token from request (from cookie, header, or query parameter):
1. Token is parsed as a singed JWT
2. We validate the JWT signature either against local JWK or against the identity server's
introspection endpoint depending on configuration
3. We validate the issuer and audience of the token if it matches the configured values
4. A subject is created from the JWT, including scopes from the token
5. We validate that we have sufficient scopes to proceed, and return `403` if not
6. Handling is returned to security to process other security providers
[[tenant-enable]]
=== Multiple tenants
The OIDC provider also supports multiple tenants. To enable this feature, it is required to do several steps.
1. To enable the default multi-tenant support, add the `multi-tenant: true` option to the
OIDC provider configuration
2. Specify the desired way to provide the tenant name. This step is done over adding
the `tenant-id-style` configuration option. For more information, see the table below
3. Add the tenants section to the OIDC provider configuration
[source, yaml]
----
tenants:
- name: "example-tenant"
# ... tenant configuration options
----
There are four ways to provide the required tenant information to Helidon by default.
.Possible `tenant-id-style` configuration options
[cols="2,4a,3a"]
|===
|key |description |additional config options
|`host-header` |Tenant configuration will be selected based on your host present in the `Host` header value. |{nbsp}
|`domain`
|Similar to the `host-header` style, but now the tenant name is identified just as
a part of the host name. By default, it selects the third domain level.
Example: Host header value from inbound request is `my.helidon.com` -> domain level 3 is `my`,
domain level 2 is `helidon` and domain level 1 is `com`.
|[source, yaml]
----
tenant-id-domain-level:
----
|`token-handler`
|The tenant name information is expected to be provided through the configured custom header value.
|[source, yaml]
----
tenant-id-handler:
header: "my-custom-header"
----
|`none`|No tenant name finding is used. Default tenant name `@default` is used instead.|
|===
You can also implement a custom way of discovering the tenant name and tenant configuration.
The custom tenant name discovery from request can be done by implementing SPI:
`io.helidon.security.providers.oidc.common.spi.TenantIdProvider`
and the custom tenant configuration discovery can be provided by implementing SPI:
`io.helidon.security.providers.oidc.common.spi.TenantConfigProvider`
==== Available tenant config options
include::{rootdir}/config/io_helidon_security_providers_oidc_common_TenantConfig.adoc[leveloffset=+3,tag=config]
==== How does that work?
Multi-tenant support requires to obtain tenant name from the incoming request. OIDC configuration is selected
based on the received tenant name. The way this tenant name has to be provided is configured via `tenant-id-style`
configuration. See <> for more information. After matching tenant configuration
with the received name, the rest of the OIDC flow if exactly the same as in <>.
Base OIDC configuration is treated as a default tenant, which is used, if no tenant name is provided. This default
tenant is having `@default` name specified.
It is also important to note, that each tenant configuration is based on the default tenant configuration (base OIDC configuration),
and therefore its configuration do not need to change all the properties, if they do not differ from the base OIDC
configuration.
[[cors]]
== CORS Settings
As an experimental feature, you can set up cross-origin handling for the redirect and logout endpoints in an optional `cors` block inside the `oidc` configuration.
include::{rootdir}/includes/cors.adoc[tag=basic-cross-origin-config-no-heading-or-intro]
© 2015 - 2025 Weber Informatics LLC | Privacy Policy