| /* | |
| * 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.security.Principal; | |
| 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.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 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; | |
| /** | |
| * Allow the filter to require a client certificate to continue processing. | |
| * | |
| * @return true, if a client certificate is required | |
| */ | |
| protected boolean requiresClientCertificate() { | |
| return false; | |
| } | |
| /** | |
| * 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 = GitBlit.self().authenticate(httpRequest, requiresClientCertificate()); | |
| return user; | |
| } | |
| /** | |
| * 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"); | |
| user.isAuthenticated = false; | |
| } | |
| 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(); | |
| } | |
| // Gitblit does not currently use actual roles in the traditional | |
| // servlet container sense. That is the reason this is marked | |
| // deprecated, but I may want to revisit this. | |
| return user.canAccessRepository(role); | |
| } | |
| @Override | |
| public Principal getUserPrincipal() { | |
| return user; | |
| } | |
| } | |
| } |