From a502d96a860456ec5e8c96761db70f7cabb74751 Mon Sep 17 00:00:00 2001 From: Paul Martin <paul@paulsputer.com> Date: Sat, 30 Apr 2016 04:19:14 -0400 Subject: [PATCH] Merge pull request #1073 from gitblit/1062-DocEditorUpdates --- src/main/java/com/gitblit/manager/AuthenticationManager.java | 66 +++++++++++++++++++++++--------- 1 files changed, 47 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/gitblit/manager/AuthenticationManager.java b/src/main/java/com/gitblit/manager/AuthenticationManager.java index 51aa221..4978763 100644 --- a/src/main/java/com/gitblit/manager/AuthenticationManager.java +++ b/src/main/java/com/gitblit/manager/AuthenticationManager.java @@ -41,6 +41,7 @@ import com.gitblit.auth.AuthenticationProvider; import com.gitblit.auth.AuthenticationProvider.UsernamePasswordAuthenticationProvider; import com.gitblit.auth.HtpasswdAuthProvider; +import com.gitblit.auth.HttpHeaderAuthProvider; import com.gitblit.auth.LdapAuthProvider; import com.gitblit.auth.PAMAuthProvider; import com.gitblit.auth.RedmineAuthProvider; @@ -92,6 +93,7 @@ // map of shortcut provider names providerNames = new HashMap<String, Class<? extends AuthenticationProvider>>(); providerNames.put("htpasswd", HtpasswdAuthProvider.class); + providerNames.put("httpheader", HttpHeaderAuthProvider.class); providerNames.put("ldap", LdapAuthProvider.class); providerNames.put("pam", PAMAuthProvider.class); providerNames.put("redmine", RedmineAuthProvider.class); @@ -170,7 +172,11 @@ } /** - * Authenticate a user based on HTTP request parameters. + * Used to handle authentication for page requests. + * + * This allows authentication to occur based on the contents of the request + * itself. If no configured @{AuthenticationProvider}s authenticate succesffully, + * a request for login will be shown. * * Authentication by X509Certificate is tried first and then by cookie. * @@ -185,7 +191,7 @@ /** * Authenticate a user based on HTTP request parameters. * - * Authentication by servlet container principal, X509Certificate, cookie, + * Authentication by custom HTTP header, servlet container principal, X509Certificate, cookie, * and finally BASIC header. * * @param httpRequest @@ -198,7 +204,7 @@ // Check if this request has already been authenticated, and trust that instead of re-processing String reqAuthUser = (String) httpRequest.getAttribute(Constants.ATTRIB_AUTHUSER); if (!StringUtils.isEmpty(reqAuthUser)) { - logger.warn("Called servlet authenticate when request is already authenticated."); + logger.debug("Called servlet authenticate when request is already authenticated."); return userManager.getUserModel(reqAuthUser); } @@ -310,16 +316,25 @@ if (values.length == 2) { String username = values[0]; char[] password = values[1].toCharArray(); - user = authenticate(username, password); + user = authenticate(username, password, httpRequest.getRemoteAddr()); if (user != null) { flagRequest(httpRequest, AuthenticationType.CREDENTIALS, user.username); logger.debug(MessageFormat.format("{0} authenticated by BASIC request header from {1}", user.username, httpRequest.getRemoteAddr())); return validateAuthentication(user, AuthenticationType.CREDENTIALS); - } else { - logger.warn(MessageFormat.format("Failed login attempt for {0}, invalid credentials from {1}", - username, httpRequest.getRemoteAddr())); } + } + } + + // Check each configured AuthenticationProvider + for (AuthenticationProvider ap : authenticationProviders) { + UserModel authedUser = ap.authenticate(httpRequest); + if (null != authedUser) { + flagRequest(httpRequest, ap.getAuthenticationType(), authedUser.username); + logger.debug(MessageFormat.format("{0} authenticated by {1} from {2} for {3}", + authedUser.username, ap.getServiceName(), httpRequest.getRemoteAddr(), + httpRequest.getPathInfo())); + return validateAuthentication(authedUser, ap.getAuthenticationType()); } } return null; @@ -445,12 +460,18 @@ * @return a user object or null */ @Override - public UserModel authenticate(String username, char[] password) { + public UserModel authenticate(String username, char[] password, String remoteIP) { if (StringUtils.isEmpty(username)) { // can not authenticate empty username return null; } + if (username.equalsIgnoreCase(Constants.FEDERATION_USER)) { + // can not authenticate internal FEDERATION_USER at this point + // it must be routed to FederationManager + return null; + } + String usernameDecoded = StringUtils.decodeUsername(username); String pw = new String(password); if (StringUtils.isEmpty(pw)) { @@ -462,22 +483,29 @@ // try local authentication if (user != null && user.isLocalAccount()) { - return authenticateLocal(user, password); - } - - // try registered external authentication providers - for (AuthenticationProvider provider : authenticationProviders) { - if (provider instanceof UsernamePasswordAuthenticationProvider) { - UserModel returnedUser = provider.authenticate(usernameDecoded, password); - if (returnedUser != null) { - // user authenticated - returnedUser.accountType = provider.getAccountType(); - return validateAuthentication(returnedUser, AuthenticationType.CREDENTIALS); + UserModel returnedUser = authenticateLocal(user, password); + if (returnedUser != null) { + // user authenticated + return returnedUser; + } + } else { + // try registered external authentication providers + for (AuthenticationProvider provider : authenticationProviders) { + if (provider instanceof UsernamePasswordAuthenticationProvider) { + UserModel returnedUser = provider.authenticate(usernameDecoded, password); + if (returnedUser != null) { + // user authenticated + returnedUser.accountType = provider.getAccountType(); + return validateAuthentication(returnedUser, AuthenticationType.CREDENTIALS); + } } } } // could not authenticate locally or with a provider + logger.warn(MessageFormat.format("Failed login attempt for {0}, invalid credentials from {1}", username, + remoteIP != null ? remoteIP : "unknown")); + return null; } -- Gitblit v1.9.1