diff --git a/examples/security/oidc/README.md b/examples/security/oidc/README.md
new file mode 100644
index 00000000000..404a55c3fe0
--- /dev/null
+++ b/examples/security/oidc/README.md
@@ -0,0 +1,23 @@
+Security integration with OIDC
+===================
+
+This example demonstrates integration with OIDC (Open ID Connect) providers.
+
+Contents
+--------
+MP example that integrates with an OIDC provider.
+
+To configure this example, you need to replace the following:
+1. src/main/resources/application.yaml - set security.properties.oidc-* to your tenant and application configuration
+
+Running the Example
+-------------------
+
+Run the "OidcMain" class for file configuration based example.
+
+
+Local configuration
+------------------
+The example is already set up to read
+`${user.home}/helidon/conf/examples.yaml` to override defaults configured
+in `application.yaml`.
diff --git a/examples/security/oidc/pom.xml b/examples/security/oidc/pom.xml
new file mode 100644
index 00000000000..a2b64c9ea6d
--- /dev/null
+++ b/examples/security/oidc/pom.xml
@@ -0,0 +1,59 @@
+
+
+
+
+ 4.0.0
+
+ io.helidon.examples.security
+ helidon-examples-security-project
+ 1.0.4-SNAPSHOT
+
+
+ oidc-login
+ Helidon Security Examples OIDC
+
+
+ Example of login using (any) OIDC provider.
+
+
+
+ io.helidon.security.examples.oidc.OidcMain
+
+
+
+
+
+ io.helidon.microprofile.bundles
+ helidon-microprofile-1.2
+ ${project.version}
+
+
+
+ io.helidon.microprofile
+ helidon-microprofile-security
+ ${project.version}
+
+
+ io.helidon.microprofile
+ helidon-microprofile-oidc
+ ${project.version}
+
+
+
+
\ No newline at end of file
diff --git a/examples/security/oidc/src/main/java/io/helidon/security/examples/oidc/OidcMain.java b/examples/security/oidc/src/main/java/io/helidon/security/examples/oidc/OidcMain.java
new file mode 100644
index 00000000000..9fad47cd20d
--- /dev/null
+++ b/examples/security/oidc/src/main/java/io/helidon/security/examples/oidc/OidcMain.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ *
+ * 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.
+ */
+package io.helidon.security.examples.oidc;
+
+import java.io.IOException;
+import java.util.logging.LogManager;
+
+import io.helidon.config.Config;
+import io.helidon.microprofile.server.Server;
+
+import static io.helidon.config.ConfigSources.classpath;
+import static io.helidon.config.ConfigSources.file;
+
+/**
+ * Main class for MP.
+ */
+public final class OidcMain {
+ private OidcMain() {
+ }
+
+ /**
+ * Start the application.
+ * @param args ignored.
+ * @throws IOException in case the logging configuration fails
+ */
+ public static void main(String[] args) throws IOException {
+ LogManager.getLogManager().readConfiguration(OidcMain.class.getResourceAsStream("/logging.properties"));
+
+ Server server = Server.builder()
+ .config(buildConfig())
+ .build()
+ .start();
+
+ System.out.println("http://localhost:" + server.port() + "/test");
+ }
+
+ private static Config buildConfig() {
+ return Config.builder()
+ .sources(
+ // you can use this file to override the defaults that are built-in
+ file(System.getProperty("user.home") + "/helidon/conf/examples.yaml").optional(),
+ // in jar file (see src/main/resources/application.yaml)
+ classpath("application.yaml"))
+ .build();
+ }
+}
diff --git a/examples/security/oidc/src/main/java/io/helidon/security/examples/oidc/OidcResource.java b/examples/security/oidc/src/main/java/io/helidon/security/examples/oidc/OidcResource.java
new file mode 100644
index 00000000000..9a059c8fbdd
--- /dev/null
+++ b/examples/security/oidc/src/main/java/io/helidon/security/examples/oidc/OidcResource.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ *
+ * 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.
+ */
+
+package io.helidon.security.examples.oidc;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.Context;
+
+import io.helidon.security.SecurityContext;
+import io.helidon.security.annotations.Authenticated;
+
+/**
+ * A simple JAX-RS resource with a single GET method.
+ */
+@Path("/test")
+public class OidcResource {
+
+ /**
+ * Hello world using security context.
+ * @param securityContext context as established during login
+ * @return a string with current username
+ */
+ @Authenticated
+ @GET
+ public String getIt(@Context SecurityContext securityContext) {
+ return "Hello " + securityContext.userName();
+ }
+
+}
diff --git a/examples/security/oidc/src/main/java/io/helidon/security/examples/oidc/OidcTestApplication.java b/examples/security/oidc/src/main/java/io/helidon/security/examples/oidc/OidcTestApplication.java
new file mode 100644
index 00000000000..172efe55b14
--- /dev/null
+++ b/examples/security/oidc/src/main/java/io/helidon/security/examples/oidc/OidcTestApplication.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ *
+ * 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.
+ */
+
+package io.helidon.security.examples.oidc;
+
+import java.util.Set;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+
+import io.helidon.common.CollectionsHelper;
+
+/**
+ * A simple JAX-rs application that just returns the single {@link io.helidon.security.examples.oidc.OidcResource resource}.
+ */
+@ApplicationScoped
+@ApplicationPath("/")
+public class OidcTestApplication extends Application {
+
+ @Override
+ public Set> getClasses() {
+ return CollectionsHelper.setOf(OidcResource.class);
+ }
+}
diff --git a/examples/security/oidc/src/main/java/io/helidon/security/examples/oidc/package-info.java b/examples/security/oidc/src/main/java/io/helidon/security/examples/oidc/package-info.java
new file mode 100644
index 00000000000..98d86de2055
--- /dev/null
+++ b/examples/security/oidc/src/main/java/io/helidon/security/examples/oidc/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ *
+ * 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.
+ */
+/**
+ * An OIDC (Open ID Connect) example.
+ */
+package io.helidon.security.examples.oidc;
diff --git a/examples/security/oidc/src/main/resources/META-INF/beans.xml b/examples/security/oidc/src/main/resources/META-INF/beans.xml
new file mode 100644
index 00000000000..30696f939e8
--- /dev/null
+++ b/examples/security/oidc/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/security/oidc/src/main/resources/application.yaml b/examples/security/oidc/src/main/resources/application.yaml
new file mode 100644
index 00000000000..ec96813ccd5
--- /dev/null
+++ b/examples/security/oidc/src/main/resources/application.yaml
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+#
+# 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.
+#
+
+server:
+ port: 7987
+security:
+ config.require-encryption: false
+ properties:
+ # this should be defined by the identity server
+ oidc-identity-uri: "https://tenant.some-server.com/oauth2/default"
+ # when you create a new client in identity server configuration, you should get a client id and a client secret
+ oidc-client-id: "some client id"
+ oidc-client-secret: "some client secret"
+ # issuer of the tokens - identity server specific (maybe even configurable)
+ oidc-issuer: "https://tenant.some-server.com/oauth2/default"
+ # audience of the tokens - identity server specific (usually configurable)
+ oidc-audience: "configured audience"
+ # The frontend URI defines the possible load balancer address
+ # The redirect URI used is ${frontend-uri}${redirect-uri}
+ # Webserver is by default listening on /oidc/redirect - this can be modified by `redirect-uri` option in oidc configuration
+ frontend-uri: "http://localhost:7987"
+ providers:
+ - abac:
+ - oidc:
+ # use a custom name, so it does not clash with other examples
+ cookie-name: "OIDC_EXAMPLE_COOKIE"
+ # support for "Authorization" header with bearer token
+ header-use: true
+ # the default redirect-uri, where the webserver listens on redirects from identity server
+ redirect-uri: "/oidc/redirect"
+ issuer: "${ALIAS=security.properties.oidc-issuer}"
+ audience: "${ALIAS=security.properties.oidc-audience}"
+ client-id: "${ALIAS=security.properties.oidc-client-id}"
+ client-secret: "${ALIAS=security.properties.oidc-client-secret}"
+ identity-uri: "${ALIAS=security.properties.oidc-identity-uri}"
+ frontend-uri: "${ALIAS=security.properties.frontend-uri}"
\ No newline at end of file
diff --git a/examples/security/oidc/src/main/resources/logging.properties b/examples/security/oidc/src/main/resources/logging.properties
new file mode 100644
index 00000000000..61f225dd918
--- /dev/null
+++ b/examples/security/oidc/src/main/resources/logging.properties
@@ -0,0 +1,26 @@
+#
+# Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+#
+# 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.
+#
+
+handlers = java.util.logging.ConsoleHandler
+
+java.util.logging.ConsoleHandler.level = FINEST
+java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
+java.util.logging.SimpleFormatter.format = [%1$tc] %4$s: %2$s - %5$s %6$s%n
+
+.level = INFO
+io.helidon.config.level = WARNING
+# io.helidon.security.providers.oidc.level = FINEST
+AUDIT.level=FINEST
diff --git a/examples/security/pom.xml b/examples/security/pom.xml
index d984b0eaf7d..ec4c1e656c7 100644
--- a/examples/security/pom.xml
+++ b/examples/security/pom.xml
@@ -45,6 +45,7 @@
attribute-based-access-control
idcs-login
outbound-override
+ oidc
diff --git a/security/providers/oidc/src/main/java/io/helidon/security/providers/oidc/OidcSupport.java b/security/providers/oidc/src/main/java/io/helidon/security/providers/oidc/OidcSupport.java
index 43e4c3ff4a0..5fa9874c318 100644
--- a/security/providers/oidc/src/main/java/io/helidon/security/providers/oidc/OidcSupport.java
+++ b/security/providers/oidc/src/main/java/io/helidon/security/providers/oidc/OidcSupport.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -177,6 +177,7 @@ private void processCode(String code, ServerRequest req, ServerResponse res) {
MultivaluedHashMap formValues = new MultivaluedHashMap<>();
formValues.putSingle("grant_type", "authorization_code");
formValues.putSingle("code", code);
+ formValues.putSingle("redirect_uri", oidcConfig.redirectUriWithHost());
Response response = oidcConfig.tokenEndpoint().request()
.accept(MediaType.APPLICATION_JSON_TYPE)