--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.authentication;
+
+import javax.annotation.CheckForNull;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.sonar.api.platform.Server;
+import org.sonar.api.server.authentication.IdentityProvider;
+import org.sonar.api.web.ServletFilter;
+
+import static com.google.common.base.Strings.isNullOrEmpty;
+import static java.lang.String.format;
+import static org.sonar.server.authentication.AuthenticationError.handleError;
+
+public abstract class AuthenticationFilter extends ServletFilter {
+ static final String CALLBACK_PATH = "/oauth2/callback/";
+ private final IdentityProviderRepository identityProviderRepository;
+ private final Server server;
+
+ public AuthenticationFilter(Server server, IdentityProviderRepository identityProviderRepository) {
+ this.server = server;
+ this.identityProviderRepository = identityProviderRepository;
+ }
+
+ /**
+ * @return the {@link IdentityProvider} for the key extracted in the request if is exists, or {@code null}, in which
+ * case the request is fully handled and caller should not handle it
+ */
+ @CheckForNull
+ IdentityProvider resolveProviderOrHandleResponse(HttpServletRequest request, HttpServletResponse response, String path) {
+ String requestUri = request.getRequestURI();
+ String providerKey = extractKeyProvider(requestUri, server.getContextPath() + path);
+ if (providerKey == null) {
+ handleError(response, "No provider key found in URI");
+ return null;
+ }
+ try {
+ return identityProviderRepository.getEnabledByKey(providerKey);
+ } catch (Exception e) {
+ handleError(e, response, format("Failed to retrieve IdentityProvider for key '%s'", providerKey));
+ return null;
+ }
+ }
+
+ @CheckForNull
+ private static String extractKeyProvider(String requestUri, String context) {
+ if (requestUri.contains(context)) {
+ String key = requestUri.replace(context, "");
+ if (!isNullOrEmpty(key)) {
+ return key;
+ }
+ }
+ return null;
+ }
+}
package org.sonar.server.authentication;
import java.io.IOException;
-import javax.annotation.CheckForNull;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import org.sonar.api.server.authentication.IdentityProvider;
import org.sonar.api.server.authentication.OAuth2IdentityProvider;
import org.sonar.api.server.authentication.UnauthorizedException;
-import org.sonar.api.web.ServletFilter;
import org.sonar.server.authentication.event.AuthenticationEvent;
import org.sonar.server.authentication.event.AuthenticationException;
-import static com.google.common.base.Strings.isNullOrEmpty;
import static java.lang.String.format;
import static org.sonar.server.authentication.AuthenticationError.handleAuthenticationError;
import static org.sonar.server.authentication.AuthenticationError.handleError;
import static org.sonar.server.authentication.event.AuthenticationEvent.Source;
-public class InitFilter extends ServletFilter {
+public class InitFilter extends AuthenticationFilter {
private static final String INIT_CONTEXT = "/sessions/init/";
- private final IdentityProviderRepository identityProviderRepository;
private final BaseContextFactory baseContextFactory;
private final OAuth2ContextFactory oAuth2ContextFactory;
- private final Server server;
private final AuthenticationEvent authenticationEvent;
public InitFilter(IdentityProviderRepository identityProviderRepository, BaseContextFactory baseContextFactory,
OAuth2ContextFactory oAuth2ContextFactory, Server server, AuthenticationEvent authenticationEvent) {
- this.identityProviderRepository = identityProviderRepository;
+ super(server, identityProviderRepository);
this.baseContextFactory = baseContextFactory;
this.oAuth2ContextFactory = oAuth2ContextFactory;
- this.server = server;
this.authenticationEvent = authenticationEvent;
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
- IdentityProvider provider = resolveProviderOrHandleResponse(httpRequest, httpResponse);
+ IdentityProvider provider = resolveProviderOrHandleResponse(httpRequest, httpResponse, INIT_CONTEXT);
if (provider != null) {
handleProvider(httpRequest, httpResponse, provider);
}
}
- @CheckForNull
- private IdentityProvider resolveProviderOrHandleResponse(HttpServletRequest request, HttpServletResponse response) {
- String requestURI = request.getRequestURI();
- String providerKey = extractKeyProvider(requestURI, server.getContextPath() + INIT_CONTEXT);
- if (providerKey == null) {
- handleError(response, "No provider key found in URI");
- return null;
- }
- try {
- return identityProviderRepository.getEnabledByKey(providerKey);
- } catch (Exception e) {
- handleError(e, response, format("Failed to retrieve IdentityProvider for key '%s'", providerKey));
- return null;
- }
- }
-
- @CheckForNull
- private static String extractKeyProvider(String requestUri, String context) {
- if (requestUri.contains(context)) {
- String key = requestUri.replace(context, "");
- if (!isNullOrEmpty(key)) {
- return key;
- }
- }
- return null;
- }
-
private void handleProvider(HttpServletRequest request, HttpServletResponse response, IdentityProvider provider) {
try {
if (provider instanceof BaseIdentityProvider) {
import org.sonar.api.server.authentication.OAuth2IdentityProvider;
import org.sonar.api.server.authentication.UnauthorizedException;
import org.sonar.api.server.authentication.UserIdentity;
-import org.sonar.api.web.ServletFilter;
import org.sonar.server.authentication.event.AuthenticationEvent;
import org.sonar.server.authentication.event.AuthenticationException;
-import static com.google.common.base.Strings.isNullOrEmpty;
import static java.lang.String.format;
import static org.sonar.server.authentication.AuthenticationError.handleAuthenticationError;
import static org.sonar.server.authentication.AuthenticationError.handleError;
import static org.sonar.server.authentication.event.AuthenticationEvent.Source;
-public class OAuth2CallbackFilter extends ServletFilter {
+public class OAuth2CallbackFilter extends AuthenticationFilter {
- public static final String CALLBACK_PATH = "/oauth2/callback/";
-
- private final IdentityProviderRepository identityProviderRepository;
private final OAuth2ContextFactory oAuth2ContextFactory;
- private final Server server;
private final AuthenticationEvent authenticationEvent;
public OAuth2CallbackFilter(IdentityProviderRepository identityProviderRepository, OAuth2ContextFactory oAuth2ContextFactory,
Server server, AuthenticationEvent authenticationEvent) {
- this.identityProviderRepository = identityProviderRepository;
+ super(server, identityProviderRepository);
this.oAuth2ContextFactory = oAuth2ContextFactory;
- this.server = server;
this.authenticationEvent = authenticationEvent;
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
- IdentityProvider provider = resolveProviderOrHandleResponse(httpRequest, httpResponse);
+ IdentityProvider provider = resolveProviderOrHandleResponse(httpRequest, httpResponse, CALLBACK_PATH);
if (provider != null) {
handleProvider(httpRequest, (HttpServletResponse) response, provider);
}
}
- @CheckForNull
- private IdentityProvider resolveProviderOrHandleResponse(HttpServletRequest request, HttpServletResponse response) {
- String requestUri = request.getRequestURI();
- String providerKey = extractKeyProvider(requestUri, server.getContextPath() + CALLBACK_PATH);
- if (providerKey == null) {
- handleError(response, "No provider key found in URI");
- return null;
- }
- try {
- return identityProviderRepository.getEnabledByKey(providerKey);
- } catch (Exception e) {
- handleError(e, response, format("Failed to retrieve IdentityProvider for key '%s'", providerKey));
- return null;
- }
- }
-
- @CheckForNull
- private static String extractKeyProvider(String requestUri, String context) {
- if (requestUri.contains(context)) {
- String key = requestUri.replace(context, "");
- if (!isNullOrEmpty(key)) {
- return key;
- }
- }
- return null;
- }
-
private void handleProvider(HttpServletRequest request, HttpServletResponse response, IdentityProvider provider) {
try {
if (provider instanceof OAuth2IdentityProvider) {
public void verifyState(HttpServletRequest request, HttpServletResponse response, OAuth2IdentityProvider provider) {
Cookie cookie = findCookie(CSRF_STATE_COOKIE, request)
- .orElseThrow(() -> AuthenticationException.newBuilder()
+ .orElseThrow(AuthenticationException.newBuilder()
.setSource(Source.oauth2(provider))
- .setMessage(format("Cookie '%s' is missing", CSRF_STATE_COOKIE))
- .build());
+ .setMessage(format("Cookie '%s' is missing", CSRF_STATE_COOKIE))::build);
String hashInCookie = cookie.getValue();
// remove cookie
assertError("Unsupported IdentityProvider class: class org.sonar.server.authentication.InitFilterTest$UnsupportedIdentityProvider");
verifyZeroInteractions(authenticationEvent);
-
}
@Test