]> source.dussan.org Git - gitblit.git/commitdiff
Added enforced HTTP Basic Authentication
authorLaurens Vrijnsen <laurens.vrijnsen@sioux.eu>
Fri, 22 Mar 2013 11:36:52 +0000 (12:36 +0100)
committerLaurens Vrijnsen <laurens.vrijnsen@sioux.eu>
Fri, 22 Mar 2013 11:36:52 +0000 (12:36 +0100)
14 files changed:
src/WEB-INF/web.xml
src/com/gitblit/EnforceAuthenticationFilter.java [new file with mode: 0644]
src/com/gitblit/wicket/AuthorizationStrategy.java
src/com/gitblit/wicket/GitBlitWebApp.java
src/com/gitblit/wicket/GitBlitWebApp.properties
src/com/gitblit/wicket/GitBlitWebApp_es.properties
src/com/gitblit/wicket/GitBlitWebApp_ja.properties
src/com/gitblit/wicket/GitBlitWebApp_ko.properties
src/com/gitblit/wicket/GitBlitWebApp_nl.properties
src/com/gitblit/wicket/GitBlitWebApp_pl.properties
src/com/gitblit/wicket/GitBlitWebApp_pt_BR.properties
src/com/gitblit/wicket/GitBlitWebApp_zh_CN.properties
src/com/gitblit/wicket/pages/LogoutPage.html [new file with mode: 0644]
src/com/gitblit/wicket/pages/LogoutPage.java

index bdc882a66e7f66cbcffab47800ff20883a1ce32f..a9436886db68072a867bffe9ff9ab96601308cce 100644 (file)
                <filter-name>PagesFilter</filter-name>\r
                <url-pattern>/pages/*</url-pattern>\r
        </filter-mapping>\r
+       \r
+       <filter>\r
+               <filter-name>EnforceAuthenticationFilter</filter-name>\r
+               <filter-class>com.gitblit.EnforceAuthenticationFilter</filter-class>\r
+       </filter>\r
+       <filter-mapping>\r
+        <filter-name>EnforceAuthenticationFilter</filter-name>\r
+        <url-pattern>/*</url-pattern>\r
+    </filter-mapping>\r
 \r
 \r
        <!-- Wicket Filter -->\r
diff --git a/src/com/gitblit/EnforceAuthenticationFilter.java b/src/com/gitblit/EnforceAuthenticationFilter.java
new file mode 100644 (file)
index 0000000..6dc454c
--- /dev/null
@@ -0,0 +1,90 @@
+/**
+ * 
+ */
+package com.gitblit;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.gitblit.models.UserModel;
+
+/**
+ * This filter enforces authentication via HTTP Basic Authentication, if the settings indicate so.
+ * It looks at the settings "web.authenticateViewPages" and "web.enforceHttpBasicAuthentication"; if
+ * both are true, any unauthorized access will be met with a HTTP Basic Authentication header.
+ *
+ * @author Laurens Vrijnsen
+ *
+ */
+public class EnforceAuthenticationFilter implements Filter {
+       
+       protected transient Logger logger = LoggerFactory.getLogger(getClass());
+
+       /* 
+        * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
+        */
+       @Override
+       public void init(FilterConfig filterConfig) throws ServletException {
+               // nothing to be done
+
+       } //init
+       
+
+       /* 
+        * This does the actual filtering: is the user authenticated? If not, enforce HTTP authentication (401)
+        * 
+        * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
+        */
+       @Override
+       public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+               
+               /*
+                * Determine whether to enforce the BASIC authentication:
+                */
+               @SuppressWarnings("static-access")
+               Boolean mustForceAuth = GitBlit.self().getBoolean("web.authenticateViewPages", false)
+                                                               && GitBlit.self().getBoolean("web.enforceHttpBasicAuthentication", false);
+               
+               HttpServletRequest  HttpRequest  = (HttpServletRequest)request;
+               HttpServletResponse HttpResponse = (HttpServletResponse)response; 
+               UserModel user = GitBlit.self().authenticate(HttpRequest);
+               
+               if (mustForceAuth && (user == null)) {
+                       // not authenticated, enforce now:
+                       logger.info(MessageFormat.format("EnforceAuthFilter: user not authenticated for URL {0}!", request.toString()));
+                       @SuppressWarnings("static-access")
+                       String CHALLENGE = MessageFormat.format("Basic realm=\"{0}\"", GitBlit.self().getString("web.siteName",""));
+                       HttpResponse.setHeader("WWW-Authenticate", CHALLENGE);
+                       HttpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+                       return;
+
+               } else {
+                       // user is authenticated, or don't care, continue handling
+                       chain.doFilter( request, response );
+                       
+               } // authenticated
+       } // doFilter
+
+       
+       /* 
+        * @see javax.servlet.Filter#destroy()
+        */
+       @Override
+       public void destroy() {
+               // Nothing to be done
+
+       } // destroy
+
+}
index 21bd1b70fb2a6446b27bdfc582d9e202d242b7c3..51183a2a7c9b4cac44011a52d47ced51cd32b24a 100644 (file)
  */\r
 package com.gitblit.wicket;\r
 \r
+import java.io.IOException;\r
+\r
+import javax.servlet.http.HttpServletResponse;\r
+\r
 import org.apache.wicket.Component;\r
 import org.apache.wicket.RestartResponseException;\r
 import org.apache.wicket.authorization.IUnauthorizedComponentInstantiationListener;\r
 import org.apache.wicket.authorization.strategies.page.AbstractPageAuthorizationStrategy;\r
+import org.apache.wicket.protocol.http.WebResponse;\r
+import org.apache.wicket.protocol.http.servlet.AbortWithWebErrorCodeException;\r
 \r
 import com.gitblit.GitBlit;\r
 import com.gitblit.Keys;\r
@@ -78,8 +84,17 @@ public class AuthorizationStrategy extends AbstractPageAuthorizationStrategy imp
 \r
        @Override\r
        public void onUnauthorizedInstantiation(Component component) {\r
+               \r
                if (component instanceof BasePage) {\r
                        throw new RestartResponseException(RepositoriesPage.class);\r
                }\r
+               /*** DISABLED CODE ***\r
+               if (component instanceof BasePage) {\r
+                       HttpServletResponse response = ((WebResponse)component.getResponse()).getHttpServletResponse();\r
+                       response.setHeader("WWW-Authenticate", "Basic realm=test");\r
+                       throw new AbortWithWebErrorCodeException(HttpServletResponse.SC_UNAUTHORIZED);\r
+                       \r
+               } \r
+               *** END DISABLED ***/\r
        }\r
 }\r
index 4e32daac89c2f0771a5f7c366680bec5fb15eaae..2300d0ff30beeea03410d50b229032b4b71b3bae 100644 (file)
@@ -40,6 +40,7 @@ import com.gitblit.wicket.pages.GitSearchPage;
 import com.gitblit.wicket.pages.GravatarProfilePage;\r
 import com.gitblit.wicket.pages.HistoryPage;\r
 import com.gitblit.wicket.pages.LogPage;\r
+import com.gitblit.wicket.pages.LogoutPage;\r
 import com.gitblit.wicket.pages.LuceneSearchPage;\r
 import com.gitblit.wicket.pages.MarkdownPage;\r
 import com.gitblit.wicket.pages.MetricsPage;\r
@@ -101,6 +102,7 @@ public class GitBlitWebApp extends WebApplication {
                mount("/metrics", MetricsPage.class, "r");\r
                mount("/blame", BlamePage.class, "r", "h", "f");\r
                mount("/users", UsersPage.class);\r
+               mount("/logout", LogoutPage.class);\r
 \r
                // setup ticket urls\r
                mount("/tickets", TicketsPage.class, "r");\r
index a993f9f15816e8e496d7fb1128d311ebb51834f8..7a2b1bb3e2e205fc4149a548df4fdd646fa791b4 100644 (file)
@@ -442,4 +442,6 @@ gb.siteName = site name
 gb.siteNameDescription = short, descriptive name of your server \r
 gb.excludeFromActivity = exclude from activity page\r
 gb.isSparkleshared = repository is Sparkleshared\r
-gb.owners = owners
\ No newline at end of file
+gb.owners = owners\r
+gb.sessionEnded = Session has been closed\r
+gb.closeBrowser = Please close the browser to properly end the session.
\ No newline at end of file
index 64c9ca13bd87a6b30d5b31cab7c8f48c2ba0b9a0..210a75f9cd717d8a88e7536342b536ac89f9f126 100644 (file)
@@ -440,4 +440,6 @@ gb.sslCertificateGeneratedRestart = Certificado SSL generado correctamente para
 gb.validity = Vigencia\r
 gb.siteName = Nombre del sitio\r
 gb.siteNameDescription = Nombre corto y descriptivo de tu servidor \r
-gb.excludeFromActivity = Excluir de la p\u00E1gina de actividad
\ No newline at end of file
+gb.excludeFromActivity = Excluir de la p\u00E1gina de actividad\r
+gb.sessionEnded = La sesi\u00F3n ha sido cerrada\r
+gb.closeBrowser = Porfavor cierre el navegador para terminar correctamente la sesi\u00F3n.
\ No newline at end of file
index 086df7b7d8e814dafbf661a984bad1bf8843483c..d0234f871f6a340953caeba7ad23444f79f255d0 100755 (executable)
@@ -314,3 +314,5 @@ gb.authorizationControl = \u6a29\u9650\u5236\u5fa1
 gb.allowAuthenticatedDescription = \u5168\u3066\u306e\u8a8d\u8a3c\u6e08\u307f\u30e6\u30fc\u30b6\u30fc\u3078\u30a2\u30af\u30bb\u30b9\u3092\u8a31\u53ef\u3059\u308b\r
 gb.allowNamedDescription = \u6307\u5b9a\u3057\u305f\u540d\u524d\u306e\u30e6\u30fc\u30b6\u30fc/\u30c1\u30fc\u30e0\u3078\u30a2\u30af\u30bb\u30b9\u3092\u8a31\u53ef\u3059\u308b\r
 gb.markdownFailure = Markdown \u306e\u30d1\u30fc\u30b9\u306b\u5931\u6557\u3057\u307e\u3057\u305f!\r
+gb.sessionEnded = Session has been closed\r
+gb.closeBrowser = Please close the browser to properly end the session.\r
index 18eda26c74b677b3f5adbd96e93924e4a2b195e7..42915df81313d5312eb5012386613d7b1b9f9776 100644 (file)
@@ -440,4 +440,6 @@ gb.sslCertificateGeneratedRestart = {0} \uC744(\uB97C) \uC704\uD55C \uC0C8 \uC11
 gb.validity = \uC720\uD6A8\uC131
 gb.siteName = \uC0AC\uC774\uD2B8 \uC774\uB984
 gb.siteNameDescription = \uC11C\uBC84\uC758 \uC9E6\uC740 \uC124\uBA85\uC774 \uD3EC\uD568\uB41C \uC774\uB984
-gb.excludeFromActivity = \uC561\uD2F0\uBE44\uD2F0 \uD398\uC774\uC9C0\uC5D0\uC11C \uC81C\uC678
\ No newline at end of file
+gb.excludeFromActivity = \uC561\uD2F0\uBE44\uD2F0 \uD398\uC774\uC9C0\uC5D0\uC11C \uC81C\uC678
+gb.sessionEnded = Session has been closed
+gb.closeBrowser = Please close the browser to properly end the session.
index 5471ad8a6cf9c457c1f038b79c4cc6845032dd64..f1281e149b5ef1ca34586f09df263f08a6d93948 100644 (file)
@@ -441,3 +441,5 @@ gb.validity = geldigheid
 gb.siteName = site naam\r
 gb.siteNameDescription = korte, verduidelijkende naam van deze server\r
 gb.excludeFromActivity = sluit uit van activiteitspagina\r
+gb.sessionEnded = Sessie is afgesloten\r
+gb.closeBrowser = Sluit de browser af om de sessie helemaal te beeindigen.
\ No newline at end of file
index 82ffa635ba8489cd8d9b2b09f9545f4aef248ad2..b75e8f81adb5cfbe8d618af2c48071573ae271bc 100644 (file)
@@ -318,4 +318,6 @@ gb.clearCache = Wyczy\u015B\u0107 cache
 gb.projects = Projekty
 gb.project = Projekt
 gb.allProjects = Wszystkie projekty
-gb.copyToClipboard = Kopiuj do schowka
\ No newline at end of file
+gb.copyToClipboard = Kopiuj do schowka
+gb.sessionEnded = Session has been closed
+gb.closeBrowser = Please close the browser to properly end the session.
\ No newline at end of file
index efe286cd889134dd8289eda708732fd4f006f418..a02d2ffac5b70e893bb38d8f78267e13d94dec06 100644 (file)
@@ -442,4 +442,6 @@ gb.siteName = nome do site
 gb.siteNameDescription = breve, mas ainda assim um nome descritivo para seu servidor\r
 gb.excludeFromActivity = excluir da página de atividades\r
 gb.isSparkleshared = repositório é Sparkleshared\r
-gb.owners = proprietários
\ No newline at end of file
+gb.owners = proprietários\r
+gb.sessionEnded = Session has been closed\r
+gb.closeBrowser = Please close the browser to properly end the session.
\ No newline at end of file
index b5715850ed7ecca4a9962848fcda5190bbecb27f..96e2067b2fd467637b6b240d205db5f0e7305da9 100644 (file)
@@ -441,4 +441,6 @@ gb.validity = \u5408\u6cd5\u6027
 gb.siteName = \u7f51\u7ad9\u540d\u79f0
 gb.siteNameDescription = \u60a8\u7684\u670d\u52a1\u5668\u7684\u7b80\u8981\u63cf\u8ff0
 gb.excludeFromActivity = \u4ece\u6d3b\u52a8\u9875\u9762\u6392\u9664
-gb.isSparkleshared = repository is Sparkleshared
\ No newline at end of file
+gb.isSparkleshared = repository is Sparkleshared
+gb.sessionEnded = Session has been closed
+gb.closeBrowser = Please close the browser to properly end the session.
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/pages/LogoutPage.html b/src/com/gitblit/wicket/pages/LogoutPage.html
new file mode 100644 (file)
index 0000000..d407783
--- /dev/null
@@ -0,0 +1,33 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"  
+      xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd"  
+      xml:lang="en"  
+      lang="en"> 
+<body>
+<wicket:extend>
+       <div class="navbar navbar-fixed-top">
+               <div class="navbar-inner">
+                       <div class="container">
+                               <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
+                               <span class="icon-bar"></span>
+                               <span class="icon-bar"></span>
+                               <span class="icon-bar"></span>
+                       </a>
+                               <a class="brand" wicket:id="rootLink">
+                                       <img src="gitblt_25_white.png" width="79" height="25" alt="gitblit" class="logo"/>
+                               </a>
+                               
+                       </div>
+               </div>
+       </div>
+                               
+       <!-- subclass content -->
+       <div class="container">
+               <div style="text-align:center" wicket:id="feedback">[Feedback Panel]</div>
+               
+               <h1><wicket:message key="gb.sessionEnded">[Session has ended]</wicket:message></h1>
+               <p><wicket:message key="gb.closeBrowser">[Please close the browser]</wicket:message></p>
+       </div>
+</wicket:extend>
+</body>
+</html>
\ No newline at end of file
index 4690ad11d6cf17e7b1383f45eb408d025b6c2f5d..982de0ecad1872b598c9ec3d4dbf0b913cacf656 100644 (file)
 package com.gitblit.wicket.pages;\r
 \r
 import org.apache.wicket.markup.html.WebPage;\r
+import org.apache.wicket.protocol.http.WebRequest;\r
 import org.apache.wicket.protocol.http.WebResponse;\r
 \r
 import com.gitblit.GitBlit;\r
 import com.gitblit.models.UserModel;\r
 import com.gitblit.wicket.GitBlitWebSession;\r
 \r
-public class LogoutPage extends WebPage {\r
+public class LogoutPage extends BasePage {\r
 \r
        public LogoutPage() {\r
+               super();\r
                GitBlitWebSession session = GitBlitWebSession.get();\r
                UserModel user = session.getUser();\r
                GitBlit.self().setCookie((WebResponse) getResponse(), null);\r
                GitBlit.self().logout(user);\r
                session.invalidate();           \r
-               setRedirect(true);\r
-               setResponsePage(getApplication().getHomePage());\r
-       }\r
+               \r
+               /*\r
+                * Now check whether the authentication was realized via the Authorization in the header.\r
+                * If so, it is likely to be cached by the browser, and cannot be undone. Effectively, this means\r
+                * that you cannot log out...\r
+                */\r
+               if ( ((WebRequest)getRequest()).getHttpServletRequest().getHeader("Authorization") != null ) {\r
+                       // authentication will be done via this route anyway, show a page to close the browser:\r
+                       // this will be done by Wicket.\r
+                       setupPage(null, getString("gb.logout"));\r
+                       \r
+               } else {\r
+                       setRedirect(true);\r
+                       setResponsePage(getApplication().getHomePage());\r
+               } // not via WWW-Auth\r
+       } // LogoutPage\r
 }
\ No newline at end of file