ApiServlet: use the new and refactored authentication mechanism Signed-off-by: Rohit Yadav <rohit.ya...@shapeblue.com>
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/68be7db0 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/68be7db0 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/68be7db0 Branch: refs/heads/auth-refactor Commit: 68be7db0fec9d1506847096589cccfd5acfe3565 Parents: e30ee73 Author: Rohit Yadav <rohit.ya...@shapeblue.com> Authored: Tue Aug 12 07:34:35 2014 +0200 Committer: Rohit Yadav <rohit.ya...@shapeblue.com> Committed: Tue Aug 12 09:19:43 2014 +0200 ---------------------------------------------------------------------- server/src/com/cloud/api/ApiServlet.java | 251 +++++++------------------- 1 file changed, 62 insertions(+), 189 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/68be7db0/server/src/com/cloud/api/ApiServlet.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/ApiServlet.java b/server/src/com/cloud/api/ApiServlet.java old mode 100755 new mode 100644 index e78bf38..5a8cf94 --- a/server/src/com/cloud/api/ApiServlet.java +++ b/server/src/com/cloud/api/ApiServlet.java @@ -16,12 +16,22 @@ // under the License. package com.cloud.api; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; +import com.cloud.api.auth.APIAuthenticationManager; +import com.cloud.api.auth.APIAuthenticationType; +import com.cloud.api.auth.APIAuthenticator; +import com.cloud.user.Account; +import com.cloud.user.AccountService; +import com.cloud.user.User; +import com.cloud.utils.StringUtils; +import com.cloud.utils.db.EntityManager; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.context.CallContext; +import org.apache.cloudstack.managed.context.ManagedContext; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; +import org.springframework.web.context.support.SpringBeanAutowiringSupport; import javax.inject.Inject; import javax.servlet.ServletConfig; @@ -30,24 +40,11 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; - -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; -import org.springframework.web.context.support.SpringBeanAutowiringSupport; - -import org.apache.cloudstack.api.ApiConstants; -import org.apache.cloudstack.api.ApiErrorCode; -import org.apache.cloudstack.api.BaseCmd; -import org.apache.cloudstack.api.ServerApiException; -import org.apache.cloudstack.context.CallContext; -import org.apache.cloudstack.managed.context.ManagedContext; - -import com.cloud.exception.CloudAuthenticationException; -import com.cloud.user.Account; -import com.cloud.user.AccountService; -import com.cloud.user.User; -import com.cloud.utils.StringUtils; -import com.cloud.utils.db.EntityManager; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.HashMap; +import java.util.Map; @Component("apiServlet") @SuppressWarnings("serial") @@ -63,6 +60,8 @@ public class ApiServlet extends HttpServlet { EntityManager _entityMgr; @Inject ManagedContext _managedContext; + @Inject + APIAuthenticationManager _authManager; public ApiServlet() { } @@ -121,8 +120,9 @@ public class ApiServlet extends HttpServlet { } void processRequestInContext(final HttpServletRequest req, final HttpServletResponse resp) { + final String remoteAddress = req.getRemoteAddr(); final StringBuilder auditTrailSb = new StringBuilder(128); - auditTrailSb.append(" ").append(req.getRemoteAddr()); + auditTrailSb.append(" ").append(remoteAddress); auditTrailSb.append(" -- ").append(req.getMethod()).append(' '); // get the response format since we'll need it in a couple of places String responseType = BaseCmd.RESPONSE_TYPE_XML; @@ -151,107 +151,56 @@ public class ApiServlet extends HttpServlet { final Object[] commandObj = params.get(ApiConstants.COMMAND); if (commandObj != null) { - final String command = (String)commandObj[0]; - if ("logout".equalsIgnoreCase(command)) { - // if this is just a logout, invalidate the session and return - if (session != null) { - final Long userId = (Long)session.getAttribute("userid"); - final Account account = (Account)session.getAttribute("accountobj"); - Long accountId = null; - if (account != null) { - accountId = account.getId(); - } - auditTrailSb.insert(0, "(userId=" + userId + " accountId=" + accountId + " sessionId=" + session.getId() + ")"); - if (userId != null) { - _apiServer.logoutUser(userId); - } - try { - session.invalidate(); - } catch (final IllegalStateException ise) { - } - } - auditTrailSb.append("command=logout"); - auditTrailSb.append(" ").append(HttpServletResponse.SC_OK); - writeResponse(resp, getLogoutSuccessResponse(responseType), HttpServletResponse.SC_OK, responseType); - return; - } else if ("login".equalsIgnoreCase(command)) { - auditTrailSb.append("command=login"); - // if this is a login, authenticate the user and return - if (session != null) { - try { - session.invalidate(); - } catch (final IllegalStateException ise) { - } - } - session = req.getSession(true); - final String[] username = (String[])params.get(ApiConstants.USERNAME); - final String[] password = (String[])params.get(ApiConstants.PASSWORD); - String[] domainIdArr = (String[])params.get(ApiConstants.DOMAIN_ID); + final String command = (String) commandObj[0]; - if (domainIdArr == null) { - domainIdArr = (String[])params.get(ApiConstants.DOMAIN__ID); - } - final String[] domainName = (String[])params.get(ApiConstants.DOMAIN); - Long domainId = null; - if ((domainIdArr != null) && (domainIdArr.length > 0)) { - try { - //check if UUID is passed in for domain - domainId = _apiServer.fetchDomainId(domainIdArr[0]); - if (domainId == null) { - domainId = Long.parseLong(domainIdArr[0]); + APIAuthenticator apiAuthenticator = _authManager.getAPIAuthenticator(command); + if (apiAuthenticator != null) { + auditTrailSb.append("command="); + auditTrailSb.append(command); + + int httpResponseCode = HttpServletResponse.SC_OK; + String responseString = null; + + if (apiAuthenticator.getAPIType() == APIAuthenticationType.LOGIN_API) { + if (session != null) { + try { + session.invalidate(); + } catch (final IllegalStateException ise) { } - auditTrailSb.append(" domainid=" + domainId);// building the params for POST call - } catch (final NumberFormatException e) { - s_logger.warn("Invalid domain id entered by user"); - auditTrailSb.append(" " + HttpServletResponse.SC_UNAUTHORIZED + " " + "Invalid domain id entered, please enter a valid one"); - final String serializedResponse = - _apiServer.getSerializedApiError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid domain id entered, please enter a valid one", params, - responseType); - writeResponse(resp, serializedResponse, HttpServletResponse.SC_UNAUTHORIZED, responseType); } + session = req.getSession(true); + } + + try { + responseString = apiAuthenticator.authenticate(command, params, session, remoteAddress, responseType, auditTrailSb); + } catch (ServerApiException e) { + httpResponseCode = e.getErrorCode().getHttpCode(); + responseString = e.getMessage(); + s_logger.debug("Authentication failure: " + e.getMessage()); } - String domain = null; - if (domainName != null) { - domain = domainName[0]; - auditTrailSb.append(" domain=" + domain); - if (domain != null) { - // ensure domain starts with '/' and ends with '/' - if (!domain.endsWith("/")) { - domain += '/'; + if (apiAuthenticator.getAPIType() == APIAuthenticationType.LOGOUT_API) { + if (session != null) { + final Long userId = (Long) session.getAttribute("userid"); + final Account account = (Account) session.getAttribute("accountobj"); + Long accountId = null; + if (account != null) { + accountId = account.getId(); } - if (!domain.startsWith("/")) { - domain = "/" + domain; + auditTrailSb.insert(0, "(userId=" + userId + " accountId=" + accountId + " sessionId=" + session.getId() + ")"); + if (userId != null) { + _apiServer.logoutUser(userId); } - } - } - - if (username != null) { - final String pwd = ((password == null) ? null : password[0]); - try { - _apiServer.loginUser(session, username[0], pwd, domainId, domain, req.getRemoteAddr(), params); - auditTrailSb.insert(0, "(userId=" + session.getAttribute("userid") + " accountId=" + ((Account)session.getAttribute("accountobj")).getId() + - " sessionId=" + session.getId() + ")"); - final String loginResponse = getLoginSuccessResponse(session, responseType); - writeResponse(resp, loginResponse, HttpServletResponse.SC_OK, responseType); - return; - } catch (final CloudAuthenticationException ex) { - // TODO: fall through to API key, or just fail here w/ auth error? (HTTP 401) try { session.invalidate(); - } catch (final IllegalStateException ise) { + } catch (final IllegalStateException ignored) { } - - auditTrailSb.append(" " + ApiErrorCode.ACCOUNT_ERROR + " " + ex.getMessage() != null ? ex.getMessage() - : "failed to authenticate user, check if username/password are correct"); - final String serializedResponse = - _apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(), ex.getMessage() != null ? ex.getMessage() - : "failed to authenticate user, check if username/password are correct", params, responseType); - writeResponse(resp, serializedResponse, ApiErrorCode.ACCOUNT_ERROR.getHttpCode(), responseType); - return; } } + writeResponse(resp, responseString, httpResponseCode, responseType); + return; } } + auditTrailSb.append(req.getQueryString()); final boolean isNew = ((session == null) ? true : session.isNew()); @@ -371,80 +320,4 @@ public class ApiServlet extends HttpServlet { } } - @SuppressWarnings("rawtypes") - String getLoginSuccessResponse(final HttpSession session, final String responseType) { - final StringBuilder sb = new StringBuilder(); - final int inactiveInterval = session.getMaxInactiveInterval(); - - final String user_UUID = (String)session.getAttribute("user_UUID"); - session.removeAttribute("user_UUID"); - - final String domain_UUID = (String)session.getAttribute("domain_UUID"); - session.removeAttribute("domain_UUID"); - - if (BaseCmd.RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { - sb.append("{ \"loginresponse\" : { "); - final Enumeration attrNames = session.getAttributeNames(); - if (attrNames != null) { - sb.append("\"timeout\" : \"").append(inactiveInterval).append("\""); - while (attrNames.hasMoreElements()) { - final String attrName = (String)attrNames.nextElement(); - if ("userid".equalsIgnoreCase(attrName)) { - sb.append(", \"" + attrName + "\" : \"" + user_UUID + "\""); - } else if ("domainid".equalsIgnoreCase(attrName)) { - sb.append(", \"" + attrName + "\" : \"" + domain_UUID + "\""); - } else { - final Object attrObj = session.getAttribute(attrName); - if ((attrObj instanceof String) || (attrObj instanceof Long)) { - sb.append(", \"" + attrName + "\" : \"" + attrObj.toString() + "\""); - } - } - } - } - sb.append(" } }"); - } else { - sb.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"); - sb.append("<loginresponse cloud-stack-version=\"").append(ApiDBUtils.getVersion()).append("\">"); - sb.append("<timeout>").append(inactiveInterval).append("</timeout>"); - final Enumeration attrNames = session.getAttributeNames(); - if (attrNames != null) { - while (attrNames.hasMoreElements()) { - final String attrName = (String)attrNames.nextElement(); - if (ApiConstants.USER_ID.equalsIgnoreCase(attrName)) { - sb.append("<").append(attrName).append(">") - .append(user_UUID).append("</") - .append(attrName).append(">"); - } else if ("domainid".equalsIgnoreCase(attrName)) { - sb.append("<").append(attrName).append(">") - .append(domain_UUID).append("</") - .append(attrName).append(">"); - } else { - final Object attrObj = session.getAttribute(attrName); - if (attrObj instanceof String || attrObj instanceof Long || attrObj instanceof Short) { - sb.append("<").append(attrName).append(">") - .append(attrObj.toString()).append("</") - .append(attrName).append(">"); - } - } - } - } - - sb.append("</loginresponse>"); - } - return sb.toString(); - } - - private String getLogoutSuccessResponse(final String responseType) { - final StringBuilder sb = new StringBuilder(); - if (BaseCmd.RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { - sb.append("{ \"logoutresponse\" : { \"description\" : \"success\" } }"); - } else { - sb.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"); - sb.append("<logoutresponse cloud-stack-version=\"").append(ApiDBUtils.getVersion()).append("\">"); - sb.append("<description>success</description>"); - sb.append("</logoutresponse>"); - } - return sb.toString(); - } - }