diff --git a/jetty-openid/src/main/config/etc/jetty-openid.xml b/jetty-openid/src/main/config/etc/jetty-openid.xml index 1daa662318c5..d11b935730ff 100644 --- a/jetty-openid/src/main/config/etc/jetty-openid.xml +++ b/jetty-openid/src/main/config/etc/jetty-openid.xml @@ -16,6 +16,7 @@ + diff --git a/jetty-openid/src/main/config/modules/openid.mod b/jetty-openid/src/main/config/modules/openid.mod index fde0b9882e18..2c2072bb9008 100644 --- a/jetty-openid/src/main/config/modules/openid.mod +++ b/jetty-openid/src/main/config/modules/openid.mod @@ -1,7 +1,7 @@ # DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html [description] -Adds OpenId Connect authentication. +Adds OpenId Connect authentication to the server. [depend] security @@ -41,4 +41,7 @@ etc/jetty-openid.xml # jetty.openid.authenticateNewUsers=false ## True if all certificates should be trusted by the default SslContextFactory -# jetty.openid.sslContextFactory.trustAll=false \ No newline at end of file +# jetty.openid.sslContextFactory.trustAll=false + +## What authentication method to use with the Token Endpoint (client_secret_post, client_secret_basic). +# jetty.openid.basicAuth=client_secret_post \ No newline at end of file diff --git a/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdConfiguration.java b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdConfiguration.java index 5e266fdc4225..626e41ebe800 100644 --- a/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdConfiguration.java +++ b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdConfiguration.java @@ -48,6 +48,7 @@ public class OpenIdConfiguration extends ContainerLifeCycle private final String clientId; private final String clientSecret; private final List scopes = new ArrayList<>(); + private final String authMethod; private String authEndpoint; private String tokenEndpoint; @@ -73,6 +74,22 @@ public OpenIdConfiguration(String provider, String clientId, String clientSecret */ public OpenIdConfiguration(String issuer, String authorizationEndpoint, String tokenEndpoint, String clientId, String clientSecret, HttpClient httpClient) + { + this(issuer, authorizationEndpoint, tokenEndpoint, clientId, clientSecret, "post", httpClient); + } + + /** + * Create an OpenID configuration for a specific OIDC provider. + * @param issuer The URL of the OpenID provider. + * @param authorizationEndpoint the URL of the OpenID provider's authorization endpoint if configured. + * @param tokenEndpoint the URL of the OpenID provider's token endpoint if configured. + * @param clientId OAuth 2.0 Client Identifier valid at the Authorization Server. + * @param clientSecret The client secret known only by the Client and the Authorization Server. + * @param authMethod Authentication method to use with the Token Endpoint. + * @param httpClient The {@link HttpClient} instance to use. + */ + public OpenIdConfiguration(String issuer, String authorizationEndpoint, String tokenEndpoint, + String clientId, String clientSecret, String authMethod, HttpClient httpClient) { this.issuer = issuer; this.clientId = clientId; @@ -80,6 +97,7 @@ public OpenIdConfiguration(String issuer, String authorizationEndpoint, String t this.authEndpoint = authorizationEndpoint; this.tokenEndpoint = tokenEndpoint; this.httpClient = httpClient != null ? httpClient : newHttpClient(); + this.authMethod = authMethod; if (this.issuer == null) throw new IllegalArgumentException("Issuer was not configured"); @@ -179,6 +197,11 @@ public String getTokenEndpoint() return tokenEndpoint; } + public String getAuthMethod() + { + return authMethod; + } + public void addScopes(String... scopes) { if (scopes != null) diff --git a/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdCredentials.java b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdCredentials.java index 622595ded24c..7076a19fc08c 100644 --- a/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdCredentials.java +++ b/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdCredentials.java @@ -19,13 +19,16 @@ package org.eclipse.jetty.security.openid; import java.io.Serializable; +import java.net.URI; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.client.api.Authentication; import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.client.util.BasicAuthentication; import org.eclipse.jetty.client.util.FormContentProvider; import org.eclipse.jetty.util.Fields; import org.eclipse.jetty.util.ajax.JSON; @@ -173,14 +176,27 @@ private Map claimAuthCode(OpenIdConfiguration configuration) thr { Fields fields = new Fields(); fields.add("code", authCode); - fields.add("client_id", configuration.getClientId()); - fields.add("client_secret", configuration.getClientSecret()); fields.add("redirect_uri", redirectUri); fields.add("grant_type", "authorization_code"); - FormContentProvider formContentProvider = new FormContentProvider(fields); - Request request = configuration.getHttpClient().POST(configuration.getTokenEndpoint()) - .content(formContentProvider) - .timeout(10, TimeUnit.SECONDS); + + Request request = configuration.getHttpClient().POST(configuration.getTokenEndpoint()); + switch (configuration.getAuthMethod()) + { + case "client_secret_basic": + URI uri = URI.create(configuration.getTokenEndpoint()); + Authentication.Result authentication = new BasicAuthentication.BasicResult(uri, configuration.getClientId(), configuration.getClientSecret()); + authentication.apply(request); + break; + case "client_secret_post": + fields.add("client_id", configuration.getClientId()); + fields.add("client_secret", configuration.getClientSecret()); + break; + default: + throw new IllegalStateException(configuration.getAuthMethod()); + } + + FormContentProvider formContent = new FormContentProvider(fields); + request = request.content(formContent).timeout(10, TimeUnit.SECONDS); ContentResponse response = request.send(); String responseBody = response.getContentAsString(); if (LOG.isDebugEnabled())