summaryrefslogtreecommitdiffstats
path: root/src/com/gitblit/AuthenticationFilter.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/gitblit/AuthenticationFilter.java')
-rw-r--r--src/com/gitblit/AuthenticationFilter.java201
1 files changed, 201 insertions, 0 deletions
diff --git a/src/com/gitblit/AuthenticationFilter.java b/src/com/gitblit/AuthenticationFilter.java
new file mode 100644
index 00000000..6b7a0af2
--- /dev/null
+++ b/src/com/gitblit/AuthenticationFilter.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2011 gitblit.com.
+ *
+ * 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.gitblit;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.security.Principal;
+import java.text.MessageFormat;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+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 javax.servlet.http.HttpSession;
+
+import org.eclipse.jgit.util.Base64;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.gitblit.models.UserModel;
+import com.gitblit.utils.StringUtils;
+
+/**
+ * The AuthenticationFilter is a servlet filter that preprocesses requests that
+ * match its url pattern definition in the web.xml file.
+ *
+ * http://en.wikipedia.org/wiki/Basic_access_authentication
+ *
+ * @author James Moger
+ *
+ */
+public abstract class AuthenticationFilter implements Filter {
+
+ protected static final String BASIC = "Basic";
+
+ protected static final String CHALLENGE = BASIC + " realm=\"" + Constants.NAME + "\"";
+
+ protected static final String SESSION_SECURED = "com.gitblit.secured";
+
+ protected transient Logger logger = LoggerFactory.getLogger(getClass());
+
+ /**
+ * doFilter does the actual work of preprocessing the request to ensure that
+ * the user may proceed.
+ *
+ * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
+ * javax.servlet.ServletResponse, javax.servlet.FilterChain)
+ */
+ @Override
+ public abstract void doFilter(final ServletRequest request, final ServletResponse response,
+ final FilterChain chain) throws IOException, ServletException;
+
+ /**
+ * Returns the full relative url of the request.
+ *
+ * @param httpRequest
+ * @return url
+ */
+ protected String getFullUrl(HttpServletRequest httpRequest) {
+ String servletUrl = httpRequest.getContextPath() + httpRequest.getServletPath();
+ String url = httpRequest.getRequestURI().substring(servletUrl.length());
+ String params = httpRequest.getQueryString();
+ if (url.length() > 0 && url.charAt(0) == '/') {
+ url = url.substring(1);
+ }
+ String fullUrl = url + (StringUtils.isEmpty(params) ? "" : ("?" + params));
+ return fullUrl;
+ }
+
+ /**
+ * Returns the user making the request, if the user has authenticated.
+ *
+ * @param httpRequest
+ * @return user
+ */
+ protected UserModel getUser(HttpServletRequest httpRequest) {
+ UserModel user = null;
+ // look for client authorization credentials in header
+ final String authorization = httpRequest.getHeader("Authorization");
+ if (authorization != null && authorization.startsWith(BASIC)) {
+ // Authorization: Basic base64credentials
+ String base64Credentials = authorization.substring(BASIC.length()).trim();
+ String credentials = new String(Base64.decode(base64Credentials),
+ Charset.forName("UTF-8"));
+ // credentials = username:password
+ final String[] values = credentials.split(":");
+
+ if (values.length == 2) {
+ String username = values[0];
+ char[] password = values[1].toCharArray();
+ user = GitBlit.self().authenticate(username, password);
+ if (user != null) {
+ return user;
+ }
+ }
+ if (GitBlit.isDebugMode()) {
+ logger.info(MessageFormat.format("AUTH: invalid credentials ({0})", credentials));
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Taken from Jetty's LoginAuthenticator.renewSessionOnAuthentication()
+ */
+ @SuppressWarnings("unchecked")
+ protected void newSession(HttpServletRequest request, HttpServletResponse response) {
+ HttpSession oldSession = request.getSession(false);
+ if (oldSession != null && oldSession.getAttribute(SESSION_SECURED) == null) {
+ synchronized (this) {
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ Enumeration<String> e = oldSession.getAttributeNames();
+ while (e.hasMoreElements()) {
+ String name = e.nextElement();
+ attributes.put(name, oldSession.getAttribute(name));
+ oldSession.removeAttribute(name);
+ }
+ oldSession.invalidate();
+
+ HttpSession newSession = request.getSession(true);
+ newSession.setAttribute(SESSION_SECURED, Boolean.TRUE);
+ for (Map.Entry<String, Object> entry : attributes.entrySet()) {
+ newSession.setAttribute(entry.getKey(), entry.getValue());
+ }
+ }
+ }
+ }
+
+ /**
+ * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
+ */
+ @Override
+ public void init(final FilterConfig config) throws ServletException {
+ }
+
+ /**
+ * @see javax.servlet.Filter#destroy()
+ */
+ @Override
+ public void destroy() {
+ }
+
+ /**
+ * Wraps a standard HttpServletRequest and overrides user principal methods.
+ */
+ public static class AuthenticatedRequest extends ServletRequestWrapper {
+
+ private UserModel user;
+
+ public AuthenticatedRequest(HttpServletRequest req) {
+ super(req);
+ user = new UserModel("anonymous");
+ }
+
+ UserModel getUser() {
+ return user;
+ }
+
+ void setUser(UserModel user) {
+ this.user = user;
+ }
+
+ @Override
+ public String getRemoteUser() {
+ return user.username;
+ }
+
+ @Override
+ public boolean isUserInRole(String role) {
+ if (role.equals(Constants.ADMIN_ROLE)) {
+ return user.canAdmin;
+ }
+ return user.canAccessRepository(role);
+ }
+
+ @Override
+ public Principal getUserPrincipal() {
+ return user;
+ }
+ }
+} \ No newline at end of file