Skip to content

Commit

Permalink
Allow custom params for token requests for client_credentials grant
Browse files Browse the repository at this point in the history
  • Loading branch information
mkowa42 committed Apr 5, 2021
1 parent 4f65f7b commit 100fec4
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,15 @@ public class OidcClientConfig extends OidcCommonConfig {

@ConfigGroup
public static class Grant {
public static enum Type {
public enum Type {
/**
* 'client_credentials' grant requiring an OIDC client authentication only
*/
CLIENT_CREDENTIALS,
/**
* 'client_credentials' grant requiring an OIDC client authentication only. A shortcut of
* {@link #CLIENT_CREDENTIALS}.
*/
CLIENT,
/**
* 'password' grant requiring both OIDC client and user ('username' and 'password') authentications
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
Expand All @@ -16,6 +15,7 @@
import io.quarkus.oidc.client.OidcClient;
import io.quarkus.oidc.client.OidcClientConfig;
import io.quarkus.oidc.client.OidcClientConfig.Grant;
import io.quarkus.oidc.client.OidcClientConfig.Grant.Type;
import io.quarkus.oidc.client.OidcClientException;
import io.quarkus.oidc.client.OidcClients;
import io.quarkus.oidc.client.Tokens;
Expand All @@ -25,6 +25,7 @@
import io.quarkus.runtime.TlsConfig;
import io.quarkus.runtime.annotations.Recorder;
import io.quarkus.runtime.configuration.ConfigurationException;
import io.quarkus.runtime.util.StringUtil;
import io.smallrye.mutiny.Uni;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;
Expand Down Expand Up @@ -122,41 +123,53 @@ protected static Uni<OidcClient> createOidcClientUni(OidcClientConfig oidcConfig
tokenRequestUriUni = discoverTokenRequestUri(client, authServerUri.toString(), oidcConfig);
}
return tokenRequestUriUni.onItemOrFailure()
.transform(new BiFunction<String, Throwable, OidcClient>() {
.transform((tokenRequestUri, t) -> {

@Override
public OidcClient apply(String tokenRequestUri, Throwable t) {
if (t != null) {
throw toOidcClientException(authServerUri.toString(), t);
}

if (tokenRequestUri == null) {
throw new ConfigurationException(
"OpenId Connect Provider token endpoint URL is not configured and can not be discovered");
}
MultiMap tokenGrantParams = new MultiMap(io.vertx.core.MultiMap.caseInsensitiveMultiMap());

String grantType = oidcConfig.grant.getType() == Grant.Type.CLIENT
? OidcConstants.CLIENT_CREDENTIALS_GRANT
: OidcConstants.PASSWORD_GRANT;
setGrantClientParams(oidcConfig, tokenGrantParams, grantType);

if (oidcConfig.grant.getType() == Grant.Type.PASSWORD) {
Map<String, String> passwordGrantOptions = oidcConfig.getGrantOptions()
.get(OidcConstants.PASSWORD_GRANT);
tokenGrantParams.add(OidcConstants.PASSWORD_GRANT_USERNAME,
passwordGrantOptions.get(OidcConstants.PASSWORD_GRANT_USERNAME));
tokenGrantParams.add(OidcConstants.PASSWORD_GRANT_PASSWORD,
passwordGrantOptions.get(OidcConstants.PASSWORD_GRANT_PASSWORD));
}

MultiMap commonRefreshGrantParams = new MultiMap(io.vertx.core.MultiMap.caseInsensitiveMultiMap());
setGrantClientParams(oidcConfig, commonRefreshGrantParams, OidcConstants.REFRESH_TOKEN_GRANT);

return new OidcClientImpl(client, tokenRequestUri, grantType, tokenGrantParams,
commonRefreshGrantParams,
oidcConfig);
if (t != null) {
throw toOidcClientException(authServerUri.toString(), t);
}

if (tokenRequestUri == null) {
throw new ConfigurationException(
"OpenId Connect Provider token endpoint URL is not configured and can not be discovered");
}
MultiMap tokenGrantParams = new MultiMap(io.vertx.core.MultiMap.caseInsensitiveMultiMap());

String grantType = (oidcConfig.grant.getType() == Grant.Type.CLIENT
|| oidcConfig.grant.getType() == Grant.Type.CLIENT_CREDENTIALS)
? OidcConstants.CLIENT_CREDENTIALS_GRANT
: OidcConstants.PASSWORD_GRANT;
setGrantClientParams(oidcConfig, tokenGrantParams, grantType);

// Grant.Type.CLIENT_CREDENTIALS is converted to 'client-credentials' by MP-Config,
// but StringUtil.hyphenate() does not replace '_' by '-', so the expected key is 'client_credentials'.
// Therefore, shall we don't allow Grant.Type.CLIENT_CREDENTIALS but only Grant.Type.CLIENT to not further confuse?

String grantOptionsKey = StringUtil.hyphenate(oidcConfig.grant.getType().name());
Map<String, String> grantOptions = oidcConfig.getGrantOptions()
.get(grantOptionsKey);
if (oidcConfig.grant.getType() == Grant.Type.PASSWORD) {

// TODO: Shall we report an error if username and password are not defined?

tokenGrantParams.add(OidcConstants.PASSWORD_GRANT_USERNAME,
grantOptions.get(OidcConstants.PASSWORD_GRANT_USERNAME));
tokenGrantParams.add(OidcConstants.PASSWORD_GRANT_PASSWORD,
grantOptions.get(OidcConstants.PASSWORD_GRANT_PASSWORD));

// TODO: Do we allow extra params in case of password grant-type?

} else if (grantOptions != null && (oidcConfig.grant.getType() == Grant.Type.CLIENT
|| oidcConfig.grant.getType() == Grant.Type.CLIENT_CREDENTIALS)) {
tokenGrantParams.addAll(grantOptions);
}

MultiMap commonRefreshGrantParams = new MultiMap(io.vertx.core.MultiMap.caseInsensitiveMultiMap());
setGrantClientParams(oidcConfig, commonRefreshGrantParams, OidcConstants.REFRESH_TOKEN_GRANT);

return new OidcClientImpl(client, tokenRequestUri, grantType, tokenGrantParams,
commonRefreshGrantParams,
oidcConfig);
});
}

Expand Down

0 comments on commit 100fec4

Please sign in to comment.