Merge pull request #6621 from eclipse/jetty-10.0.x-6617-openidBasicAuth

Issue #6617 - add support for the client_secret_basic authentication method
This commit is contained in:
Lachlan 2021-08-19 16:19:15 +10:00 committed by GitHub
commit c150ce6859
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 5 deletions

View File

@ -26,6 +26,7 @@
<Arg><Property name="jetty.openid.provider.tokenEndpoint"/></Arg>
<Arg><Property name="jetty.openid.clientId"/></Arg>
<Arg><Property name="jetty.openid.clientSecret"/></Arg>
<Arg><Property name="jetty.openid.authMethod" default="client_secret_post"/></Arg>
<Arg><Ref refid="HttpClient"/></Arg>
<Call name="addScopes">
<Arg>

View File

@ -42,3 +42,6 @@ etc/jetty-openid.xml
## True if all certificates should be trusted by the default SslContextFactory
# jetty.openid.sslContextFactory.trustAll=false
## What authentication method to use with the Token Endpoint (client_secret_post, client_secret_basic).
# jetty.openid.authMethod=client_secret_post

View File

@ -45,6 +45,7 @@ public class OpenIdConfiguration extends ContainerLifeCycle
private final String clientId;
private final String clientSecret;
private final List<String> scopes = new ArrayList<>();
private final String authMethod;
private String authEndpoint;
private String tokenEndpoint;
@ -70,6 +71,22 @@ public class OpenIdConfiguration extends ContainerLifeCycle
*/
public OpenIdConfiguration(String issuer, String authorizationEndpoint, String tokenEndpoint,
String clientId, String clientSecret, HttpClient httpClient)
{
this(issuer, authorizationEndpoint, tokenEndpoint, clientId, clientSecret, "client_secret_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;
@ -77,6 +94,7 @@ public class OpenIdConfiguration extends ContainerLifeCycle
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");
@ -177,6 +195,11 @@ public class OpenIdConfiguration extends ContainerLifeCycle
return tokenEndpoint;
}
public String getAuthMethod()
{
return authMethod;
}
public void addScopes(String... scopes)
{
if (scopes != null)

View File

@ -14,13 +14,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.FormRequestContent;
import org.eclipse.jetty.util.Fields;
import org.eclipse.jetty.util.ajax.JSON;
@ -168,14 +171,27 @@ public class OpenIdCredentials implements Serializable
{
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");
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());
}
FormRequestContent formContent = new FormRequestContent(fields);
Request request = configuration.getHttpClient().POST(configuration.getTokenEndpoint())
.body(formContent)
.timeout(10, TimeUnit.SECONDS);
request = request.body(formContent).timeout(10, TimeUnit.SECONDS);
ContentResponse response = request.send();
String responseBody = response.getContentAsString();
if (LOG.isDebugEnabled())