You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AuthenticationFilter.java 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /*
  2. * Copyright 2011 gitblit.com.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.gitblit.servlet;
  17. import java.io.IOException;
  18. import java.security.Principal;
  19. import java.util.Enumeration;
  20. import java.util.HashMap;
  21. import java.util.Map;
  22. import javax.servlet.Filter;
  23. import javax.servlet.FilterChain;
  24. import javax.servlet.FilterConfig;
  25. import javax.servlet.ServletException;
  26. import javax.servlet.ServletRequest;
  27. import javax.servlet.ServletResponse;
  28. import javax.servlet.http.HttpServletRequest;
  29. import javax.servlet.http.HttpServletRequestWrapper;
  30. import javax.servlet.http.HttpServletResponse;
  31. import javax.servlet.http.HttpSession;
  32. import org.slf4j.Logger;
  33. import org.slf4j.LoggerFactory;
  34. import com.gitblit.Constants;
  35. import com.gitblit.manager.IAuthenticationManager;
  36. import com.gitblit.models.UserModel;
  37. import com.gitblit.utils.DeepCopier;
  38. import com.gitblit.utils.StringUtils;
  39. /**
  40. * The AuthenticationFilter is a servlet filter that preprocesses requests that
  41. * match its url pattern definition in the web.xml file.
  42. *
  43. * http://en.wikipedia.org/wiki/Basic_access_authentication
  44. *
  45. * @author James Moger
  46. *
  47. */
  48. public abstract class AuthenticationFilter implements Filter {
  49. protected static final String CHALLENGE = "Basic realm=\"" + Constants.NAME + "\"";
  50. protected static final String SESSION_SECURED = "com.gitblit.secured";
  51. protected transient Logger logger = LoggerFactory.getLogger(getClass());
  52. protected final IAuthenticationManager authenticationManager;
  53. protected AuthenticationFilter(IAuthenticationManager authenticationManager) {
  54. this.authenticationManager = authenticationManager;
  55. }
  56. /**
  57. * doFilter does the actual work of preprocessing the request to ensure that
  58. * the user may proceed.
  59. *
  60. * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
  61. * javax.servlet.ServletResponse, javax.servlet.FilterChain)
  62. */
  63. @Override
  64. public abstract void doFilter(final ServletRequest request, final ServletResponse response,
  65. final FilterChain chain) throws IOException, ServletException;
  66. /**
  67. * Allow the filter to require a client certificate to continue processing.
  68. *
  69. * @return true, if a client certificate is required
  70. */
  71. protected boolean requiresClientCertificate() {
  72. return false;
  73. }
  74. /**
  75. * Returns the full relative url of the request.
  76. *
  77. * @param httpRequest
  78. * @return url
  79. */
  80. protected String getFullUrl(HttpServletRequest httpRequest) {
  81. String servletUrl = httpRequest.getContextPath() + httpRequest.getServletPath();
  82. String url = httpRequest.getRequestURI().substring(servletUrl.length());
  83. String params = httpRequest.getQueryString();
  84. if (url.length() > 0 && url.charAt(0) == '/') {
  85. url = url.substring(1);
  86. }
  87. String fullUrl = url + (StringUtils.isEmpty(params) ? "" : ("?" + params));
  88. return fullUrl;
  89. }
  90. /**
  91. * Returns the user making the request, if the user has authenticated.
  92. *
  93. * @param httpRequest
  94. * @return user
  95. */
  96. protected UserModel getUser(HttpServletRequest httpRequest) {
  97. UserModel user = authenticationManager.authenticate(httpRequest, requiresClientCertificate());
  98. return user;
  99. }
  100. /**
  101. * Taken from Jetty's LoginAuthenticator.renewSessionOnAuthentication()
  102. */
  103. protected void newSession(HttpServletRequest request, HttpServletResponse response) {
  104. HttpSession oldSession = request.getSession(false);
  105. if (oldSession != null && oldSession.getAttribute(SESSION_SECURED) == null) {
  106. synchronized (this) {
  107. Map<String, Object> attributes = new HashMap<String, Object>();
  108. Enumeration<String> e = oldSession.getAttributeNames();
  109. while (e.hasMoreElements()) {
  110. String name = e.nextElement();
  111. attributes.put(name, oldSession.getAttribute(name));
  112. oldSession.removeAttribute(name);
  113. }
  114. oldSession.invalidate();
  115. HttpSession newSession = request.getSession(true);
  116. newSession.setAttribute(SESSION_SECURED, Boolean.TRUE);
  117. for (Map.Entry<String, Object> entry : attributes.entrySet()) {
  118. newSession.setAttribute(entry.getKey(), entry.getValue());
  119. }
  120. }
  121. }
  122. }
  123. /**
  124. * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
  125. */
  126. @Override
  127. public void init(final FilterConfig config) throws ServletException {
  128. }
  129. /**
  130. * @see javax.servlet.Filter#destroy()
  131. */
  132. @Override
  133. public void destroy() {
  134. }
  135. /**
  136. * Wraps a standard HttpServletRequest and overrides user principal methods.
  137. */
  138. public static class AuthenticatedRequest extends HttpServletRequestWrapper {
  139. private UserModel user;
  140. public AuthenticatedRequest(HttpServletRequest req) {
  141. super(req);
  142. user = DeepCopier.copy(UserModel.ANONYMOUS);
  143. }
  144. UserModel getUser() {
  145. return user;
  146. }
  147. void setUser(UserModel user) {
  148. this.user = user;
  149. }
  150. @Override
  151. public String getRemoteUser() {
  152. return user.username;
  153. }
  154. @Override
  155. public boolean isUserInRole(String role) {
  156. if (role.equals(Constants.ADMIN_ROLE)) {
  157. return user.canAdmin();
  158. }
  159. // Gitblit does not currently use actual roles in the traditional
  160. // servlet container sense. That is the reason this is marked
  161. // deprecated, but I may want to revisit this.
  162. return user.canAccessRepository(role);
  163. }
  164. @Override
  165. public Principal getUserPrincipal() {
  166. return user;
  167. }
  168. }
  169. }