Using MicrosoftAzureActiveDirectory20Api from scribejava-apis * Using MicrosoftAzureActiveDirectory20Api from scribejava-apis, this is intended to be used with Microsoft Azure oauth v2. * If Google OAuth plugin is set to use a tenant other than common, organizations or consumers the token will be validated that they are originating from the same tenant that is configured in the Gerrit OAuth plugin. Change-Id: Id293be463281fc8fa34af5edf61e774b207dcc21
diff --git a/BUILD b/BUILD index b5d591b..0d2e0e4 100644 --- a/BUILD +++ b/BUILD
@@ -22,6 +22,7 @@ deps = [ "@commons-codec//jar:neverlink", "@jackson-databind//jar", + "@scribejava-apis//jar", "@scribejava-core//jar", ], ) @@ -32,6 +33,7 @@ tags = ["oauth"], deps = [ ":oauth__plugin_test_deps", + "@scribejava-apis//jar", "@scribejava-core//jar", ], )
diff --git a/external_plugin_deps.bzl b/external_plugin_deps.bzl index 4615c8d..ffe8a31 100644 --- a/external_plugin_deps.bzl +++ b/external_plugin_deps.bzl
@@ -2,12 +2,18 @@ def external_plugin_deps(omit_commons_codec = True): JACKSON_VERS = "2.10.2" + SCRIBEJAVA_VERS = "6.9.0" maven_jar( name = "scribejava-core", - artifact = "com.github.scribejava:scribejava-core:6.9.0", + artifact = "com.github.scribejava:scribejava-core:" + SCRIBEJAVA_VERS, sha1 = "ed761f450d8382f75787e8fee9ae52e7ec768747", ) maven_jar( + name = "scribejava-apis", + artifact = "com.github.scribejava:scribejava-apis:" + SCRIBEJAVA_VERS, + sha1 = "a374c7a36533e58e53b42b584a8b3751ab1e13c4", + ) + maven_jar( name = "jackson-annotations", artifact = "com.fasterxml.jackson.core:jackson-annotations:" + JACKSON_VERS, sha1 = "3a13b6105946541b8d4181a0506355b5fae63260",
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/Office365Api.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/Office365Api.java deleted file mode 100644 index 4a3d0e1..0000000 --- a/src/main/java/com/googlesource/gerrit/plugins/oauth/Office365Api.java +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright (C) 2018 The Android Open Source Project -// -// 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 com.googlesource.gerrit.plugins.oauth; - -import com.github.scribejava.core.builder.api.DefaultApi20; -import com.github.scribejava.core.oauth2.clientauthentication.ClientAuthentication; -import com.github.scribejava.core.oauth2.clientauthentication.RequestBodyAuthenticationScheme; - -public class Office365Api extends DefaultApi20 { - public static final String DEFAULT_TENANT = "organizations"; - - private final String tenant; - - public Office365Api() { - this(DEFAULT_TENANT); - } - - public Office365Api(String tenant) { - this.tenant = tenant; - } - - @Override - public String getAccessTokenEndpoint() { - return endpointFor("token"); - } - - @Override - public String getAuthorizationBaseUrl() { - return endpointFor("authorize"); - } - - private String endpointFor(String suffix) { - return String.format("https://login.microsoftonline.com/%s/oauth2/v2.0/%s", tenant, suffix); - } - - @Override - public ClientAuthentication getClientAuthentication() { - return RequestBodyAuthenticationScheme.instance(); - } -}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/Office365OAuthService.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/Office365OAuthService.java index 3df8937..bdafd92 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/oauth/Office365OAuthService.java +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/Office365OAuthService.java
@@ -16,6 +16,7 @@ import static com.google.gerrit.json.OutputFormat.JSON; +import com.github.scribejava.apis.MicrosoftAzureActiveDirectory20Api; import com.github.scribejava.core.builder.ServiceBuilder; import com.github.scribejava.core.exceptions.OAuthException; import com.github.scribejava.core.model.OAuth2AccessToken; @@ -24,6 +25,7 @@ import com.github.scribejava.core.model.Verb; import com.github.scribejava.core.oauth.OAuth20Service; import com.google.common.base.CharMatcher; +import com.google.common.collect.ImmutableSet; import com.google.gerrit.extensions.annotations.PluginName; import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider; import com.google.gerrit.extensions.auth.oauth.OAuthToken; @@ -54,6 +56,9 @@ private static final String PROTECTED_RESOURCE_URL = "https://graph.microsoft.com/v1.0/me"; private static final String SCOPE = "openid offline_access https://graph.microsoft.com/user.readbasic.all"; + private static final String DEFAULT_TENANT = "organizations"; + private static final ImmutableSet<String> TENANTS_WITHOUT_VALIDATION = + ImmutableSet.<String>builder().add(DEFAULT_TENANT).add("common").add("consumers").build(); private final OAuth20Service service; private final Gson gson; private final String canonicalWebUrl; @@ -69,14 +74,14 @@ PluginConfig cfg = cfgFactory.getFromGerritConfig(pluginName + CONFIG_SUFFIX); this.canonicalWebUrl = CharMatcher.is('/').trimTrailingFrom(urlProvider.get()) + "/"; this.useEmailAsUsername = cfg.getBoolean(InitOAuth.USE_EMAIL_AS_USERNAME, false); - this.tenant = cfg.getString(InitOAuth.TENANT, Office365Api.DEFAULT_TENANT); + this.tenant = cfg.getString(InitOAuth.TENANT, DEFAULT_TENANT); this.clientId = cfg.getString(InitOAuth.CLIENT_ID); this.service = new ServiceBuilder(cfg.getString(InitOAuth.CLIENT_ID)) .apiSecret(cfg.getString(InitOAuth.CLIENT_SECRET)) .callback(canonicalWebUrl + "oauth") .defaultScope(SCOPE) - .build(new Office365Api(tenant)); + .build(MicrosoftAzureActiveDirectory20Api.custom(tenant)); this.gson = JSON.newGson(); if (log.isDebugEnabled()) { log.debug("OAuth2: canonicalWebUrl={}", canonicalWebUrl); @@ -87,11 +92,10 @@ @Override public OAuthUserInfo getUserInfo(OAuthToken token) throws IOException { - // ?: Have we set a custom tenant, if so we should validate that the token is issued by the same - // tenant as - // we have set. - if (!tenant.equals(Office365Api.DEFAULT_TENANT)) { - // -> Yes, we are using a non-default tenant so we should validate that is delegated from the + // ?: Have we set a custom tenant and is this a tenant other than the one set in + // TENANTS_WITHOUT_VALIDATION + if (!TENANTS_WITHOUT_VALIDATION.contains(tenant)) { + // -> Yes, we are using a tenant that should be validated, so verify that is issued for the // same one that we // have set. String tid = getTokenJson(token.getToken()).get("tid").getAsString();
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md index 98b0b56..fec6ecb 100644 --- a/src/main/resources/Documentation/config.md +++ b/src/main/resources/Documentation/config.md
@@ -241,14 +241,13 @@ ``` ####Tenant -By default, the Gerrit OAuth plugin is using the tenant `organizations`. A specific tenant can be set -by using the option `tenant`. +The Gerrit OAuth plugin is default set to use the tenant `organizations` but a specific tenant can be used by +the option `tenant`. If a tenant other than `common`, `organizations` or `consumers` is used then the tokens will be +validated that they are originating from the same tenant that is configured in the Gerrit OAuth plugin. +See [https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-protocols-oidc#fetch-the-openid-connect-metadata-document](Microsoft identity platform and OpenID Connect protocol) ``` plugin.gerrit-oauth-provider-office365-oauth.tenant = <tenant to use> ``` -If a specific tenant is set Gerrit OAuth plugin will inspect the token and validate that this is -originating from the Azure AD with the tenant specified in the option. - -By default, all tokens will be checked that they contain the client_id set +Regardless of tenant all tokens will be checked that they contain the client_id set in the Gerrit OAuth plugin.
diff --git a/src/test/java/com/googlesource/gerrit/plugins/oauth/Office365ApiTest.java b/src/test/java/com/googlesource/gerrit/plugins/oauth/Office365ApiTest.java index 6bcf313..a725167 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/oauth/Office365ApiTest.java +++ b/src/test/java/com/googlesource/gerrit/plugins/oauth/Office365ApiTest.java
@@ -16,16 +16,17 @@ import static com.google.common.truth.Truth.assertThat; +import com.github.scribejava.apis.MicrosoftAzureActiveDirectory20Api; import com.github.scribejava.core.extractors.OAuth2AccessTokenJsonExtractor; import org.junit.Before; import org.junit.Test; public class Office365ApiTest { - private Office365Api api; + private MicrosoftAzureActiveDirectory20Api api; @Before public void setUp() { - api = new Office365Api(); + api = MicrosoftAzureActiveDirectory20Api.instance(); } @Test