From 3774b5abb3140d307ec96eb4c62aa6694e07118f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Thu, 20 Dec 2018 10:05:17 +0100 Subject: [PATCH] Do not send basic auth for /repo requests from web browser This fixes the basic auth popups in browsers after session timeout and reload in browsers "inside" of repositories. --- .../scm/web/filter/AuthenticationFilter.java | 3 +- .../main/java/sonia/scm/ScmServletModule.java | 4 -- ...tpProtocolServletAuthenticationFilter.java | 50 +++++++++++++++++++ .../web/security/ApiAuthenticationFilter.java | 5 ++ 4 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 scm-webapp/src/main/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilter.java diff --git a/scm-core/src/main/java/sonia/scm/web/filter/AuthenticationFilter.java b/scm-core/src/main/java/sonia/scm/web/filter/AuthenticationFilter.java index ffe6ecc787..81afa04a67 100644 --- a/scm-core/src/main/java/sonia/scm/web/filter/AuthenticationFilter.java +++ b/scm-core/src/main/java/sonia/scm/web/filter/AuthenticationFilter.java @@ -70,7 +70,6 @@ import javax.servlet.http.HttpServletResponse; * @author Sebastian Sdorra * @since 2.0.0 */ -@Singleton public class AuthenticationFilter extends HttpFilter { @@ -128,7 +127,7 @@ public class AuthenticationFilter extends HttpFilter } else if (subject.isAuthenticated()) { - logger.trace("user is allready authenticated"); + logger.trace("user is already authenticated"); processChain(request, response, chain, subject); } else if (isAnonymousAccessEnabled()) diff --git a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java index d7846dbac5..7c7dec47ff 100644 --- a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java +++ b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java @@ -112,9 +112,7 @@ import sonia.scm.util.ScmConfigurationUtil; import sonia.scm.web.UserAgentParser; import sonia.scm.web.cgi.CGIExecutorFactory; import sonia.scm.web.cgi.DefaultCGIExecutorFactory; -import sonia.scm.web.filter.AuthenticationFilter; import sonia.scm.web.filter.LoggingFilter; -import sonia.scm.web.protocol.HttpProtocolServlet; import sonia.scm.web.security.AdministrationContext; import sonia.scm.web.security.DefaultAdministrationContext; @@ -315,8 +313,6 @@ public class ScmServletModule extends ServletModule bind(TemplateEngineFactory.class); bind(ObjectMapper.class).toProvider(ObjectMapperProvider.class); - filter(HttpProtocolServlet.PATTERN).through(AuthenticationFilter.class); - // bind events // bind(LastModifiedUpdateListener.class); diff --git a/scm-webapp/src/main/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilter.java b/scm-webapp/src/main/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilter.java new file mode 100644 index 0000000000..77683bd6be --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilter.java @@ -0,0 +1,50 @@ +package sonia.scm.web.filter; + +import sonia.scm.Priority; +import sonia.scm.PushStateDispatcher; +import sonia.scm.config.ScmConfiguration; +import sonia.scm.filter.Filters; +import sonia.scm.filter.WebElement; +import sonia.scm.util.HttpUtil; +import sonia.scm.web.UserAgent; +import sonia.scm.web.UserAgentParser; +import sonia.scm.web.WebTokenGenerator; +import sonia.scm.web.protocol.HttpProtocolServlet; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Set; + +import static sonia.scm.util.HttpUtil.AUTHENTICATION_REALM; +import static sonia.scm.util.HttpUtil.HEADER_WWW_AUTHENTICATE; + +@Priority(Filters.PRIORITY_AUTHENTICATION) +@WebElement(value = HttpProtocolServlet.PATTERN) +public class HttpProtocolServletAuthenticationFilter extends AuthenticationFilter { + + private final PushStateDispatcher dispatcher; + private final UserAgentParser userAgentParser; + + @Inject + public HttpProtocolServletAuthenticationFilter( + ScmConfiguration configuration, + Set tokenGenerators, + PushStateDispatcher dispatcher, + UserAgentParser userAgentParser) { + super(configuration, tokenGenerators); + this.dispatcher = dispatcher; + this.userAgentParser = userAgentParser; + } + + @Override + protected void sendUnauthorizedError(HttpServletRequest request, HttpServletResponse response) throws IOException { + UserAgent userAgent = userAgentParser.parse(request); + if (userAgent.isBrowser()) { + dispatcher.dispatch(request, response, request.getRequestURI()); + } else { + HttpUtil.sendUnauthorized(request, response); + } + } +} diff --git a/scm-webapp/src/main/java/sonia/scm/web/security/ApiAuthenticationFilter.java b/scm-webapp/src/main/java/sonia/scm/web/security/ApiAuthenticationFilter.java index c2444b43f5..b0d492be60 100644 --- a/scm-webapp/src/main/java/sonia/scm/web/security/ApiAuthenticationFilter.java +++ b/scm-webapp/src/main/java/sonia/scm/web/security/ApiAuthenticationFilter.java @@ -127,4 +127,9 @@ public class ApiAuthenticationFilter extends AuthenticationFilter { chain.doFilter(request, response); } + + @Override + protected void sendUnauthorizedError(HttpServletRequest request, HttpServletResponse response) throws IOException { + + } }