diff options
author | James Moger <james.moger@gitblit.com> | 2012-12-03 16:59:17 -0500 |
---|---|---|
committer | James Moger <james.moger@gitblit.com> | 2012-12-03 16:59:17 -0500 |
commit | 37fa664c58df034607edf2485a1414b3417b2755 (patch) | |
tree | 206e27ae15c4c7303bf5b3d2277c281e28210f06 /src/com/gitblit | |
parent | 58d93319bd870c93d16764b86a4163ac2d1f0561 (diff) | |
download | gitblit-37fa664c58df034607edf2485a1414b3417b2755.tar.gz gitblit-37fa664c58df034607edf2485a1414b3417b2755.zip |
Consolidate authentication techniques and support container principals (issue-68)
Diffstat (limited to 'src/com/gitblit')
-rw-r--r-- | src/com/gitblit/AuthenticationFilter.java | 43 | ||||
-rw-r--r-- | src/com/gitblit/Constants.java | 2 | ||||
-rw-r--r-- | src/com/gitblit/GitBlit.java | 103 |
3 files changed, 90 insertions, 58 deletions
diff --git a/src/com/gitblit/AuthenticationFilter.java b/src/com/gitblit/AuthenticationFilter.java index 64aa4411..eb6e95b7 100644 --- a/src/com/gitblit/AuthenticationFilter.java +++ b/src/com/gitblit/AuthenticationFilter.java @@ -16,9 +16,7 @@ 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;
@@ -37,7 +35,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory;
import com.gitblit.models.UserModel;
-import com.gitblit.utils.Base64;
import com.gitblit.utils.StringUtils;
/**
@@ -51,9 +48,7 @@ import com.gitblit.utils.StringUtils; */
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 CHALLENGE = "Basic realm=\"" + Constants.NAME + "\"";
protected static final String SESSION_SECURED = "com.gitblit.secured";
@@ -103,40 +98,8 @@ public abstract class AuthenticationFilter implements Filter { * @return user
*/
protected UserModel getUser(HttpServletRequest httpRequest) {
- UserModel user = null;
- // try request authentication
- user = GitBlit.self().authenticate(httpRequest);
- if (user != null) {
- return user;
- } else if (requiresClientCertificate()) {
- // http request does not have a valid certificate
- // and the filter requires one
- return 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(":",2);
-
- 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;
+ UserModel user = GitBlit.self().authenticate(httpRequest, requiresClientCertificate());
+ return user;
}
/**
diff --git a/src/com/gitblit/Constants.java b/src/com/gitblit/Constants.java index 4669c4c9..d152651b 100644 --- a/src/com/gitblit/Constants.java +++ b/src/com/gitblit/Constants.java @@ -399,7 +399,7 @@ public class Constants { }
public static enum AuthenticationType {
- CREDENTIALS, COOKIE, CERTIFICATE;
+ CREDENTIALS, COOKIE, CERTIFICATE, CONTAINER;
public boolean isStandard() {
return ordinal() <= COOKIE.ordinal();
diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java index 69135c49..02906ee9 100644 --- a/src/com/gitblit/GitBlit.java +++ b/src/com/gitblit/GitBlit.java @@ -24,6 +24,8 @@ import java.io.InputStreamReader; import java.lang.reflect.Field;
import java.net.URI;
import java.net.URISyntaxException;
+import java.nio.charset.Charset;
+import java.security.Principal;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
@@ -98,6 +100,7 @@ import com.gitblit.models.SettingModel; import com.gitblit.models.TeamModel;
import com.gitblit.models.UserModel;
import com.gitblit.utils.ArrayUtils;
+import com.gitblit.utils.Base64;
import com.gitblit.utils.ByteFormat;
import com.gitblit.utils.ContainerUtils;
import com.gitblit.utils.DeepCopier;
@@ -567,6 +570,20 @@ public class GitBlit implements ServletContextListener { * @return a user object or null
*/
public UserModel authenticate(HttpServletRequest httpRequest) {
+ return authenticate(httpRequest, false);
+ }
+
+ /**
+ * Authenticate a user based on HTTP request parameters.
+ *
+ * Authentication by X509Certificate, servlet container principal, cookie,
+ * and BASIC header.
+ *
+ * @param httpRequest
+ * @param requiresCertificate
+ * @return a user object or null
+ */
+ public UserModel authenticate(HttpServletRequest httpRequest, boolean requiresCertificate) {
// try to authenticate by certificate
boolean checkValidity = settings.getBoolean(Keys.git.enforceCertificateValidity, true);
String [] oids = getStrings(Keys.git.certificateUsernameOIDs).toArray(new String[0]);
@@ -574,39 +591,85 @@ public class GitBlit implements ServletContextListener { if (model != null) {
// grab real user model and preserve certificate serial number
UserModel user = getUserModel(model.username);
+ X509Metadata metadata = HttpUtils.getCertificateMetadata(httpRequest);
if (user != null) {
- RequestCycle requestCycle = RequestCycle.get();
- if (requestCycle != null) {
- // flag the Wicket session, if this is a Wicket request
- GitBlitWebSession session = GitBlitWebSession.get();
- session.authenticationType = AuthenticationType.CERTIFICATE;
- }
- X509Metadata metadata = HttpUtils.getCertificateMetadata(httpRequest);
+ flagWicketSession(AuthenticationType.CERTIFICATE);
logger.info(MessageFormat.format("{0} authenticated by client certificate {1} from {2}",
user.username, metadata.serialNumber, httpRequest.getRemoteAddr()));
return user;
+ } else {
+ logger.warn(MessageFormat.format("Failed to find UserModel for {0}, attempted client certificate ({1}) authentication from {2}",
+ model.username, metadata.serialNumber, httpRequest.getRemoteAddr()));
+ }
+ }
+
+ if (requiresCertificate) {
+ // caller requires client certificate authentication (e.g. git servlet)
+ return null;
+ }
+
+ // try to authenticate by servlet container principal
+ Principal principal = httpRequest.getUserPrincipal();
+ if (principal != null) {
+ UserModel user = getUserModel(principal.getName());
+ if (user != null) {
+ flagWicketSession(AuthenticationType.CONTAINER);
+ logger.info(MessageFormat.format("{0} authenticated by servlet container principal from {1}",
+ user.username, httpRequest.getRemoteAddr()));
+ return user;
+ } else {
+ logger.warn(MessageFormat.format("Failed to find UserModel for {0}, attempted servlet container authentication from {1}",
+ principal.getName(), httpRequest.getRemoteAddr()));
}
}
// try to authenticate by cookie
- Cookie[] cookies = httpRequest.getCookies();
- if (allowCookieAuthentication() && cookies != null && cookies.length > 0) {
- // Grab cookie from Browser Session
- UserModel user = authenticate(cookies);
+ if (allowCookieAuthentication()) {
+ UserModel user = authenticate(httpRequest.getCookies());
if (user != null) {
- RequestCycle requestCycle = RequestCycle.get();
- if (requestCycle != null) {
- // flag the Wicket session, if this is a Wicket request
- GitBlitWebSession session = GitBlitWebSession.get();
- session.authenticationType = AuthenticationType.COOKIE;
- }
+ flagWicketSession(AuthenticationType.COOKIE);
logger.info(MessageFormat.format("{0} authenticated by cookie from {1}",
user.username, httpRequest.getRemoteAddr()));
return user;
}
}
+
+ // try to authenticate by BASIC
+ 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(":",2);
+
+ if (values.length == 2) {
+ String username = values[0];
+ char[] password = values[1].toCharArray();
+ UserModel user = authenticate(username, password);
+ if (user != null) {
+ flagWicketSession(AuthenticationType.CREDENTIALS);
+ logger.info(MessageFormat.format("{0} authenticated by BASIC request header from {1}",
+ user.username, httpRequest.getRemoteAddr()));
+ return user;
+ } else {
+ logger.warn(MessageFormat.format("Failed login attempt for {0}, invalid credentials ({1}) from {2}",
+ username, credentials, httpRequest.getRemoteAddr()));
+ }
+ }
+ }
return null;
}
+
+ protected void flagWicketSession(AuthenticationType authenticationType) {
+ RequestCycle requestCycle = RequestCycle.get();
+ if (requestCycle != null) {
+ // flag the Wicket session, if this is a Wicket request
+ GitBlitWebSession session = GitBlitWebSession.get();
+ session.authenticationType = authenticationType;
+ }
+ }
/**
* Open a file resource using the Servlet container.
@@ -693,6 +756,9 @@ public class GitBlit implements ServletContextListener { * @return true if successful
*/
public boolean deleteUser(String username) {
+ if (StringUtils.isEmpty(username)) {
+ return false;
+ }
return userService.deleteUser(username);
}
@@ -704,6 +770,9 @@ public class GitBlit implements ServletContextListener { * @return a user object or null
*/
public UserModel getUserModel(String username) {
+ if (StringUtils.isEmpty(username)) {
+ return null;
+ }
UserModel user = userService.getUserModel(username);
return user;
}
|