Laurens Vrijnsen
2013-03-22 a2ce62e1f360e9cdb2221cfa3b091c02bda857eb
Added enforced HTTP Basic Authentication
2 files added
12 files modified
200 ■■■■■ changed files
src/WEB-INF/web.xml 9 ●●●●● patch | view | raw | blame | history
src/com/gitblit/EnforceAuthenticationFilter.java 90 ●●●●● patch | view | raw | blame | history
src/com/gitblit/wicket/AuthorizationStrategy.java 15 ●●●●● patch | view | raw | blame | history
src/com/gitblit/wicket/GitBlitWebApp.java 2 ●●●●● patch | view | raw | blame | history
src/com/gitblit/wicket/GitBlitWebApp.properties 4 ●●● patch | view | raw | blame | history
src/com/gitblit/wicket/GitBlitWebApp_es.properties 4 ●●● patch | view | raw | blame | history
src/com/gitblit/wicket/GitBlitWebApp_ja.properties 2 ●●●●● patch | view | raw | blame | history
src/com/gitblit/wicket/GitBlitWebApp_ko.properties 4 ●●● patch | view | raw | blame | history
src/com/gitblit/wicket/GitBlitWebApp_nl.properties 2 ●●●●● patch | view | raw | blame | history
src/com/gitblit/wicket/GitBlitWebApp_pl.properties 4 ●●● patch | view | raw | blame | history
src/com/gitblit/wicket/GitBlitWebApp_pt_BR.properties 4 ●●● patch | view | raw | blame | history
src/com/gitblit/wicket/GitBlitWebApp_zh_CN.properties 4 ●●● patch | view | raw | blame | history
src/com/gitblit/wicket/pages/LogoutPage.html 33 ●●●●● patch | view | raw | blame | history
src/com/gitblit/wicket/pages/LogoutPage.java 23 ●●●● patch | view | raw | blame | history
src/WEB-INF/web.xml
@@ -214,6 +214,15 @@
        <filter-name>PagesFilter</filter-name>
        <url-pattern>/pages/*</url-pattern>
    </filter-mapping>
    <filter>
        <filter-name>EnforceAuthenticationFilter</filter-name>
        <filter-class>com.gitblit.EnforceAuthenticationFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>EnforceAuthenticationFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- Wicket Filter -->
src/com/gitblit/EnforceAuthenticationFilter.java
New file
@@ -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
}
src/com/gitblit/wicket/AuthorizationStrategy.java
@@ -15,10 +15,16 @@
 */
package com.gitblit.wicket;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import org.apache.wicket.Component;
import org.apache.wicket.RestartResponseException;
import org.apache.wicket.authorization.IUnauthorizedComponentInstantiationListener;
import org.apache.wicket.authorization.strategies.page.AbstractPageAuthorizationStrategy;
import org.apache.wicket.protocol.http.WebResponse;
import org.apache.wicket.protocol.http.servlet.AbortWithWebErrorCodeException;
import com.gitblit.GitBlit;
import com.gitblit.Keys;
@@ -78,8 +84,17 @@
    @Override
    public void onUnauthorizedInstantiation(Component component) {
        if (component instanceof BasePage) {
            throw new RestartResponseException(RepositoriesPage.class);
        }
        /*** DISABLED CODE ***
        if (component instanceof BasePage) {
            HttpServletResponse response = ((WebResponse)component.getResponse()).getHttpServletResponse();
            response.setHeader("WWW-Authenticate", "Basic realm=test");
            throw new AbortWithWebErrorCodeException(HttpServletResponse.SC_UNAUTHORIZED);
        }
        *** END DISABLED ***/
    }
}
src/com/gitblit/wicket/GitBlitWebApp.java
@@ -40,6 +40,7 @@
import com.gitblit.wicket.pages.GravatarProfilePage;
import com.gitblit.wicket.pages.HistoryPage;
import com.gitblit.wicket.pages.LogPage;
import com.gitblit.wicket.pages.LogoutPage;
import com.gitblit.wicket.pages.LuceneSearchPage;
import com.gitblit.wicket.pages.MarkdownPage;
import com.gitblit.wicket.pages.MetricsPage;
@@ -101,6 +102,7 @@
        mount("/metrics", MetricsPage.class, "r");
        mount("/blame", BlamePage.class, "r", "h", "f");
        mount("/users", UsersPage.class);
        mount("/logout", LogoutPage.class);
        // setup ticket urls
        mount("/tickets", TicketsPage.class, "r");
src/com/gitblit/wicket/GitBlitWebApp.properties
@@ -442,4 +442,6 @@
gb.siteNameDescription = short, descriptive name of your server 
gb.excludeFromActivity = exclude from activity page
gb.isSparkleshared = repository is Sparkleshared
gb.owners = owners
gb.owners = owners
gb.sessionEnded = Session has been closed
gb.closeBrowser = Please close the browser to properly end the session.
src/com/gitblit/wicket/GitBlitWebApp_es.properties
@@ -440,4 +440,6 @@
gb.validity = Vigencia
gb.siteName = Nombre del sitio
gb.siteNameDescription = Nombre corto y descriptivo de tu servidor 
gb.excludeFromActivity = Excluir de la p\u00E1gina de actividad
gb.excludeFromActivity = Excluir de la p\u00E1gina de actividad
gb.sessionEnded = La sesi\u00F3n ha sido cerrada
gb.closeBrowser = Porfavor cierre el navegador para terminar correctamente la sesi\u00F3n.
src/com/gitblit/wicket/GitBlitWebApp_ja.properties
@@ -314,3 +314,5 @@
gb.allowAuthenticatedDescription = \u5168\u3066\u306e\u8a8d\u8a3c\u6e08\u307f\u30e6\u30fc\u30b6\u30fc\u3078\u30a2\u30af\u30bb\u30b9\u3092\u8a31\u53ef\u3059\u308b
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
gb.markdownFailure = Markdown \u306e\u30d1\u30fc\u30b9\u306b\u5931\u6557\u3057\u307e\u3057\u305f!
gb.sessionEnded = Session has been closed
gb.closeBrowser = Please close the browser to properly end the session.
src/com/gitblit/wicket/GitBlitWebApp_ko.properties
@@ -440,4 +440,6 @@
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
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.
src/com/gitblit/wicket/GitBlitWebApp_nl.properties
@@ -441,3 +441,5 @@
gb.siteName = site naam
gb.siteNameDescription = korte, verduidelijkende naam van deze server
gb.excludeFromActivity = sluit uit van activiteitspagina
gb.sessionEnded = Sessie is afgesloten
gb.closeBrowser = Sluit de browser af om de sessie helemaal te beeindigen.
src/com/gitblit/wicket/GitBlitWebApp_pl.properties
@@ -318,4 +318,6 @@
gb.projects = Projekty
gb.project = Projekt
gb.allProjects = Wszystkie projekty
gb.copyToClipboard = Kopiuj do schowka
gb.copyToClipboard = Kopiuj do schowka
gb.sessionEnded = Session has been closed
gb.closeBrowser = Please close the browser to properly end the session.
src/com/gitblit/wicket/GitBlitWebApp_pt_BR.properties
@@ -442,4 +442,6 @@
gb.siteNameDescription = breve, mas ainda assim um nome descritivo para seu servidor
gb.excludeFromActivity = excluir da página de atividades
gb.isSparkleshared = repositório é Sparkleshared
gb.owners = proprietários
gb.owners = proprietários
gb.sessionEnded = Session has been closed
gb.closeBrowser = Please close the browser to properly end the session.
src/com/gitblit/wicket/GitBlitWebApp_zh_CN.properties
@@ -441,4 +441,6 @@
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
gb.isSparkleshared = repository is Sparkleshared
gb.sessionEnded = Session has been closed
gb.closeBrowser = Please close the browser to properly end the session.
src/com/gitblit/wicket/pages/LogoutPage.html
New file
@@ -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>
src/com/gitblit/wicket/pages/LogoutPage.java
@@ -16,21 +16,36 @@
package com.gitblit.wicket.pages;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.protocol.http.WebRequest;
import org.apache.wicket.protocol.http.WebResponse;
import com.gitblit.GitBlit;
import com.gitblit.models.UserModel;
import com.gitblit.wicket.GitBlitWebSession;
public class LogoutPage extends WebPage {
public class LogoutPage extends BasePage {
    public LogoutPage() {
        super();
        GitBlitWebSession session = GitBlitWebSession.get();
        UserModel user = session.getUser();
        GitBlit.self().setCookie((WebResponse) getResponse(), null);
        GitBlit.self().logout(user);
        session.invalidate();        
        setRedirect(true);
        setResponsePage(getApplication().getHomePage());
    }
        /*
         * Now check whether the authentication was realized via the Authorization in the header.
         * If so, it is likely to be cached by the browser, and cannot be undone. Effectively, this means
         * that you cannot log out...
         */
        if ( ((WebRequest)getRequest()).getHttpServletRequest().getHeader("Authorization") != null ) {
            // authentication will be done via this route anyway, show a page to close the browser:
            // this will be done by Wicket.
            setupPage(null, getString("gb.logout"));
        } else {
            setRedirect(true);
            setResponsePage(getApplication().getHomePage());
        } // not via WWW-Auth
    } // LogoutPage
}