Skip to content
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

Add CORS support to OidcSupport (3.x) (#3844) #3871

Merged
merged 1 commit into from
Feb 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/mp/cors/03_configuration-with-cors-mp.adoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////////

Copyright (c) 2020 Oracle and/or its affiliates.
Copyright (c) 2020, 2022 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.
Expand Down Expand Up @@ -44,6 +44,7 @@
:config-table-methods-column-header: Annotation Parameter
:basic-table-intro: The table below lists the parameters for the `@CrossOriginConfig` annotation and the configuration keys that identify the CORS characteristics.
:helidon-variant: MP
:cors-config-key-explanation:

Your application code establishes the CORS behavior of your endpoints using the `@CrossOrigin` annotation.
You and your users can override that behavior, as well as the CORS behavior of the built-in services,
Expand Down
3 changes: 2 additions & 1 deletion docs/se/cors/03_using-configuration.adoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////////

Copyright (c) 2020 Oracle and/or its affiliates.
Copyright (c) 2020, 2022 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.
Expand Down Expand Up @@ -33,6 +33,7 @@
:!cors-config-table-exclude-keys:
:basic-table-intro: The table below lists the configuration keys that identify the CORS characteristics.
:helidon-variant: SE
:cors-config-key-explanation: , identified by a configuration key of your choosing,

You can use configuration in combination with the Helidon CORS SE API to add CORS support to your resources by
replacing some Java code with declarative configuration. This also gives your users a way to override the
Expand Down
9 changes: 6 additions & 3 deletions docs/shared/cors/common_shared.adoc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////////
Copyright (c) 2020 Oracle and/or its affiliates.
Copyright (c) 2020, 2022 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.
Expand Down Expand Up @@ -30,6 +30,7 @@
:common-page-prefix-inc:
:actual-cors-dependency-src:


= CORS Shared content

// tag::cors-intro[]
Expand Down Expand Up @@ -79,10 +80,11 @@ link:{javadoc-base-url-api}/MappedCrossOriginConfig.html[`MappedCrossOriginConfi
//tag::basic-cross-origin-config[]
[[basic-cross-origin-config]]
=== Basic Cross-Origin Configuration
In configuration, Helidon represents basic CORS information as a section, identified by a configuration
key of your choosing, that contains
In configuration, Helidon represents basic CORS information as a section{cors-config-key-explanation} that contains
one or more key/value pairs. Each key-value pair assigns one characteristic of CORS behavior.

//tag::basic-cross-origin-config-no-heading-or-intro[]

[subs=attributes+]
{basic-table-intro}

Expand All @@ -109,6 +111,7 @@ endif::[]
allow-methods: ["PUT", "DELETE"]
...
----
//end::basic-cross-origin-config-no-heading-or-intro[]
//end::basic-cross-origin-config[]


Expand Down
15 changes: 14 additions & 1 deletion docs/shared/security/providers/oidc.adoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////////

Copyright (c) 2018, 2021 Oracle and/or its affiliates.
Copyright (c) 2018, 2022 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.
Expand All @@ -18,6 +18,11 @@

:description: Helidon Security OIDC Provider
:keywords: helidon, security, oidc
:cors-inc: ../../cors/common_shared.adoc
: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',
:common-page-prefix-inc: ../../shared/cors/common_shared.adoc
:cors-config-table-exclude-methods: true

[source,text]
.Provider class name
Expand Down Expand Up @@ -45,6 +50,9 @@ security:
identity-uri: "http://your-tenant.identity-server.com"
frontend-uri: "http://my-service:8080"
audience: "http://my-service"
cors:
allow-origins: ["http://foo.com", "http://there.com"]
allow-methods: ["PUT", "DELETE"]
outbound:
- name: "internal-services"
hosts: ["*.example.org"]
Expand All @@ -68,6 +76,7 @@ an important distinction when more than one provider is used
|`frontend-uri` |{nbsp} |Full URI of this service for redirects back from OIDC server
|`issuer` |`issuer` from OIDC metadata |Issuer of token - each JWT is validated to check the issuer
|`audience` | {nbsp} |Audience of a token - each JWT is validated to check the audience
|`cors` | {nbsp} | Cross-origin resource sharing settings (see <<cors>> below)
|`proxy-protocol` |`http` |Proxy protocol to use when proxy is used
|`proxy-host` |`null` |Proxy host to use. When defined, triggers usage of proxy for HTTP requests
|`proxy-port` |`80` |Port of the proxy server to use
Expand Down Expand Up @@ -142,4 +151,8 @@ introspection endpoint depending on configuration
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

[[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::{cors-inc}[tag=basic-cross-origin-config-no-heading-or-intro]
4 changes: 2 additions & 2 deletions etc/checkstyle-suppressions.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<!--

Copyright (c) 2016, 2021 Oracle and/or its affiliates.
Copyright (c) 2016, 2022 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.
Expand All @@ -27,7 +27,7 @@
files="examples/todo-app/.*"/>

<suppress checks="FileLength"
files="config/config/src/main/java/io/helidon/config/Config.java|integrations/cdi/jpa-cdi/src/main/java/io/helidon/integrations/cdi/jpa/JpaExtension\.java"
files="config/config/src/main/java/io/helidon/config/Config.java|integrations/cdi/jpa-cdi/src/main/java/io/helidon/integrations/cdi/jpa/JpaExtension\.java|security/providers/oidc-common/src/main/java/io/helidon/security/providers/oidc/common/OidcConfig\.java"
lines="1"/>

<!-- Java comments with AsciiDoc tag:: and end:: in import section incorrectly flagged
Expand Down
6 changes: 5 additions & 1 deletion security/providers/oidc-common/pom.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2018, 2021 Oracle and/or its affiliates.
Copyright (c) 2018, 2022 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.
Expand Down Expand Up @@ -58,6 +58,10 @@
<groupId>io.helidon.webclient</groupId>
<artifactId>helidon-webclient-jaxrs</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.webserver</groupId>
<artifactId>helidon-webserver-cors</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.media</groupId>
<artifactId>helidon-media-jsonp</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2021 Oracle and/or its affiliates.
* Copyright (c) 2018, 2022 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.
Expand Down Expand Up @@ -44,6 +44,7 @@
import io.helidon.webclient.WebClient;
import io.helidon.webclient.WebClientRequestBuilder;
import io.helidon.webclient.security.WebClientSecurity;
import io.helidon.webserver.cors.CrossOriginConfig;

import jakarta.json.Json;
import jakarta.json.JsonObject;
Expand Down Expand Up @@ -302,6 +303,11 @@
* <td>{@code false}</td>
* <td>Whether logout support should be enabled. Requires encryption of cookies (and cookies must be used).</td>
* </tr>
* <tr>
* <td>{@code cors}</td>
* <td>&nbsp;</td>
* <td>Cross-origin resource sharing settings. See {@link io.helidon.webserver.cors.CrossOriginConfig}.</td>
* </tr>
* </table>
*/
public final class OidcConfig {
Expand Down Expand Up @@ -367,6 +373,7 @@ public final class OidcConfig {
private final OidcCookieHandler idTokenCookieHandler;
private final URI postLogoutUri;
private final URI logoutEndpointUri;
private final CrossOriginConfig crossOriginConfig;

private OidcConfig(Builder builder) {
this.clientId = builder.clientId;
Expand Down Expand Up @@ -437,6 +444,8 @@ private OidcConfig(Builder builder) {
this.scopeAudience = tmp + "/";
}
}
this.crossOriginConfig = builder.crossOriginConfig;

LOGGER.finest(() -> "OIDC Scope audience: " + scopeAudience);
LOGGER.finest(() -> "Redirect URI with host: " + frontendUri + redirectUri);
}
Expand Down Expand Up @@ -937,6 +946,15 @@ public Duration clientTimeout() {
return clientTimeout;
}

/**
* Cross-origin resource sharing settings.
*
* @return CORS settings
*/
public CrossOriginConfig crossOriginConfig() {
return crossOriginConfig;
}

/**
* Client Authentication methods that are used by Clients to authenticate to the Authorization
* Server when using the Token Endpoint.
Expand Down Expand Up @@ -1071,6 +1089,7 @@ public static class Builder implements io.helidon.common.Builder<Builder, OidcCo
private WebClient webClient;
private Duration clientTimeout = Duration.ofSeconds(DEFAULT_TIMEOUT_SECONDS);
private URI postLogoutUri;
private CrossOriginConfig crossOriginConfig;

@Override
public OidcConfig build() {
Expand Down Expand Up @@ -1280,6 +1299,8 @@ public Builder config(Config config) {

config.get("client-timeout-millis").asLong().ifPresent(this::clientTimeoutMillis);

config.get("cors").as(CrossOriginConfig::create).ifPresent(this::crossOriginConfig);

return this;
}

Expand Down Expand Up @@ -1339,6 +1360,17 @@ public Builder cookieEncryptionEnabledIdToken(boolean cookieEncryptionEnabled) {
return this;
}

/**
* Assign cross-origin resource sharing settings.
*
* @param crossOriginConfig cross-origin settings to apply to the redirect endpoint
* @return updated builder instance
*/
public Builder crossOriginConfig(CrossOriginConfig crossOriginConfig) {
this.crossOriginConfig = crossOriginConfig;
return this;
}

/**
* Whether to enable logout support.
* When logout is enabled, we use two cookies (User token and user ID token) and we expose
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2021 Oracle and/or its affiliates.
* Copyright (c) 2018, 2022 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.
Expand Down Expand Up @@ -36,6 +36,7 @@
requires io.helidon.media.jsonp;
requires io.helidon.common.crypto;
requires static io.helidon.config.metadata;
requires io.helidon.webserver.cors;

// these are deprecated and will be removed in 3.x
requires jersey.client;
Expand Down
6 changes: 5 additions & 1 deletion security/providers/oidc/pom.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

Copyright (c) 2018, 2021 Oracle and/or its affiliates.
Copyright (c) 2018, 2022 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.
Expand Down Expand Up @@ -66,6 +66,10 @@
<groupId>io.helidon.webserver</groupId>
<artifactId>helidon-webserver</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.webserver</groupId>
<artifactId>helidon-webserver-cors</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.config</groupId>
<artifactId>helidon-config</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2021 Oracle and/or its affiliates.
* Copyright (c) 2018, 2022 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.
Expand Down Expand Up @@ -40,6 +40,8 @@
import io.helidon.webserver.ServerRequest;
import io.helidon.webserver.ServerResponse;
import io.helidon.webserver.Service;
import io.helidon.webserver.cors.CorsSupport;
import io.helidon.webserver.cors.CrossOriginConfig;

import jakarta.json.JsonObject;

Expand Down Expand Up @@ -125,12 +127,14 @@ public final class OidcSupport implements Service {
private final OidcCookieHandler tokenCookieHandler;
private final OidcCookieHandler idTokenCookieHandler;
private final boolean enabled;
private final CorsSupport corsSupport;

private OidcSupport(Builder builder) {
this.oidcConfig = builder.oidcConfig;
this.enabled = builder.enabled;
this.tokenCookieHandler = oidcConfig.tokenCookieHandler();
this.idTokenCookieHandler = oidcConfig.idTokenCookieHandler();
this.corsSupport = prepareCrossOriginSupport(oidcConfig.redirectUri(), oidcConfig.crossOriginConfig());
}

/**
Expand Down Expand Up @@ -189,8 +193,14 @@ public static Builder builder() {
@Override
public void update(Routing.Rules rules) {
if (enabled) {
if (corsSupport != null) {
rules.any(oidcConfig.redirectUri(), corsSupport);
}
rules.get(oidcConfig.redirectUri(), this::processOidcRedirect);
if (oidcConfig.logoutEnabled()) {
if (corsSupport != null) {
rules.any(oidcConfig.logoutUri(), corsSupport);
}
rules.get(oidcConfig.logoutUri(), this::processLogout);
}
rules.any(this::addRequestAsHeader);
Expand Down Expand Up @@ -424,6 +434,14 @@ private void processError(ServerRequest req, ServerResponse res) {
res.send("{\"error\": \"" + error + "\", \"error_description\": \"" + errorDescription + "\"}");
}

private CorsSupport prepareCrossOriginSupport(String path, CrossOriginConfig crossOriginConfig) {
return crossOriginConfig == null
? null
: CorsSupport.builder()
.addCrossOrigin(path, crossOriginConfig)
.build();
}

/**
* A fluent API builder for {@link io.helidon.security.providers.oidc.OidcSupport}.
*/
Expand Down
3 changes: 2 additions & 1 deletion security/providers/oidc/src/main/java/module-info.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2021 Oracle and/or its affiliates.
* Copyright (c) 2018, 2022 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.
Expand Down Expand Up @@ -31,6 +31,7 @@
requires io.helidon.security.jwt;
requires io.helidon.webclient;
requires io.helidon.webserver;
requires io.helidon.webserver.cors;
requires io.helidon.security.integration.webserver;
requires static io.helidon.config.metadata;

Expand Down