You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by bh...@apache.org on 2015/08/12 10:42:42 UTC

[1/3] git commit: updated refs/heads/4.5-samlfixes to 1527ad6

Repository: cloudstack
Updated Branches:
  refs/heads/4.5-samlfixes 69f39d533 -> 1527ad696


CLOUDSTACK-8701: Add listandswitchsamlaccount API test and add boundary checks

- Adds unit test for ListAndSwitchSAMLAccountCmd
- Checks and logs in user only if they are enabled
- If saml user switches to a locked account, send appropriate error message

Signed-off-by: Rohit Yadav <ro...@shapeblue.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/1527ad69
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/1527ad69
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/1527ad69

Branch: refs/heads/4.5-samlfixes
Commit: 1527ad6964f240e0c98606510fb1c8806eeb4e04
Parents: 856001d
Author: Rohit Yadav <ro...@shapeblue.com>
Authored: Wed Aug 12 14:04:08 2015 +0530
Committer: Rohit Yadav <ro...@shapeblue.com>
Committed: Wed Aug 12 14:09:36 2015 +0530

----------------------------------------------------------------------
 .../command/ListAndSwitchSAMLAccountCmd.java    |  14 +-
 .../command/SAML2LoginAPIAuthenticatorCmd.java  |  31 +--
 .../ListAndSwitchSAMLAccountCmdTest.java        | 203 +++++++++++++++++++
 3 files changed, 233 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1527ad69/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmd.java
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmd.java b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmd.java
index db0d6dc..80aee1b 100644
--- a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmd.java
+++ b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmd.java
@@ -19,6 +19,7 @@ package org.apache.cloudstack.api.command;
 import com.cloud.api.response.ApiResponseSerializer;
 import com.cloud.domain.Domain;
 import com.cloud.domain.dao.DomainDao;
+import com.cloud.exception.CloudAuthenticationException;
 import com.cloud.user.Account;
 import com.cloud.user.User;
 import com.cloud.user.UserAccount;
@@ -50,6 +51,7 @@ import javax.inject.Inject;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -131,7 +133,14 @@ public class ListAndSwitchSAMLAccountCmd extends BaseCmd implements APIAuthentic
             final User user = _userDao.findByUuid(userUuid);
             final Domain domain = _domainDao.findByUuid(domainUuid);
             final UserAccount nextUserAccount = _accountService.getUserAccountById(user.getId());
-            if (!nextUserAccount.getUsername().equals(currentUserAccount.getUsername())
+            if (nextUserAccount != null && !nextUserAccount.getAccountState().equals(Account.State.enabled.toString())) {
+                throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, _apiServer.getSerializedApiError(ApiErrorCode.PARAM_ERROR.getHttpCode(),
+                        "The requested user account is locked and cannot be switched to, please contact your administrator.",
+                        params, responseType));
+            }
+            if (nextUserAccount == null
+                    || !nextUserAccount.getAccountState().equals(Account.State.enabled.toString())
+                    || !nextUserAccount.getUsername().equals(currentUserAccount.getUsername())
                     || !nextUserAccount.getExternalEntity().equals(currentUserAccount.getExternalEntity())
                     || (nextUserAccount.getDomainId() != domain.getId())
                     || (nextUserAccount.getSource() != User.Source.SAML2)) {
@@ -147,7 +156,8 @@ public class ListAndSwitchSAMLAccountCmd extends BaseCmd implements APIAuthentic
                     resp.sendRedirect(SAML2AuthManager.SAMLCloudStackRedirectionUrl.value());
                     return ApiResponseSerializer.toSerializedString(loginResponse, responseType);
                 }
-            } catch (final Exception ignored) {
+            } catch (CloudAuthenticationException | IOException exception) {
+                s_logger.debug("Failed to switch to request SAML user account due to: " + exception.getMessage());
             }
         } else {
             List<UserAccountVO> switchableAccounts = _userAccountDao.getAllUsersByNameAndEntity(currentUserAccount.getUsername(), currentUserAccount.getExternalEntity());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1527ad69/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmd.java
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmd.java b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmd.java
index 188eb6b..2c1b292 100644
--- a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmd.java
+++ b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmd.java
@@ -17,6 +17,7 @@
 package org.apache.cloudstack.api.command;
 
 import com.cloud.api.response.ApiResponseSerializer;
+import com.cloud.exception.CloudAuthenticationException;
 import com.cloud.user.Account;
 import com.cloud.user.DomainManager;
 import com.cloud.user.UserAccount;
@@ -290,28 +291,32 @@ public class SAML2LoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthent
                 UserAccount userAccount = null;
                 List<UserAccountVO> possibleUserAccounts = _userAccountDao.getAllUsersByNameAndEntity(username, issuer.getValue());
                 if (possibleUserAccounts != null && possibleUserAccounts.size() > 0) {
-                    // By default, log into the first user account
+                    // Log into the first enabled user account
                     // Users can switch to other allowed accounts later
-                    userAccount = possibleUserAccounts.get(0);
+                    for (UserAccountVO possibleUserAccount: possibleUserAccounts) {
+                        if (possibleUserAccount.getAccountState().equals(Account.State.enabled.toString())) {
+                            userAccount = possibleUserAccount;
+                            break;
+                        }
+                    }
                 }
 
                 if (userAccount == null || userAccount.getExternalEntity() == null || !_samlAuthManager.isUserAuthorized(userAccount.getId(), issuer.getValue())) {
                     throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, _apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(),
-                            "Your authenticated user is not authorized, please contact your administrator",
+                            "Your authenticated user is not authorized for SAML Single Sign-On, please contact your administrator",
                             params, responseType));
                 }
 
-                if (userAccount != null) {
-                    try {
-                        if (_apiServer.verifyUser(userAccount.getId())) {
-                            LoginCmdResponse loginResponse = (LoginCmdResponse) _apiServer.loginUser(session, userAccount.getUsername(), userAccount.getUsername() + userAccount.getSource().toString(),
-                                    userAccount.getDomainId(), null, remoteAddress, params);
-                            SAMLUtils.setupSamlUserCookies(loginResponse, resp);
-                            resp.sendRedirect(SAML2AuthManager.SAMLCloudStackRedirectionUrl.value());
-                            return ApiResponseSerializer.toSerializedString(loginResponse, responseType);
-                        }
-                    } catch (final Exception ignored) {
+                try {
+                    if (_apiServer.verifyUser(userAccount.getId())) {
+                        LoginCmdResponse loginResponse = (LoginCmdResponse) _apiServer.loginUser(session, userAccount.getUsername(), userAccount.getUsername() + userAccount.getSource().toString(),
+                                userAccount.getDomainId(), null, remoteAddress, params);
+                        SAMLUtils.setupSamlUserCookies(loginResponse, resp);
+                        resp.sendRedirect(SAML2AuthManager.SAMLCloudStackRedirectionUrl.value());
+                        return ApiResponseSerializer.toSerializedString(loginResponse, responseType);
                     }
+                } catch (CloudAuthenticationException | IOException exception) {
+                    s_logger.debug("SAML Login failed to log in the user due to: " + exception.getMessage());
                 }
             }
         } catch (IOException e) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1527ad69/plugins/user-authenticators/saml2/test/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmdTest.java
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/saml2/test/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmdTest.java b/plugins/user-authenticators/saml2/test/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmdTest.java
new file mode 100644
index 0000000..df175e6
--- /dev/null
+++ b/plugins/user-authenticators/saml2/test/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmdTest.java
@@ -0,0 +1,203 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cloudstack.api.command;
+
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountService;
+import com.cloud.user.User;
+import com.cloud.user.UserAccountVO;
+import com.cloud.user.UserVO;
+import com.cloud.user.dao.UserAccountDao;
+import com.cloud.user.dao.UserDao;
+import com.cloud.utils.HttpUtils;
+import junit.framework.TestCase;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ApiServerService;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.auth.APIAuthenticationType;
+import org.apache.cloudstack.api.response.LoginCmdResponse;
+import org.apache.cloudstack.saml.SAML2AuthManager;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ListAndSwitchSAMLAccountCmdTest extends TestCase {
+    @Mock
+    ApiServerService apiServer;
+
+    @Mock
+    SAML2AuthManager samlAuthManager;
+
+    @Mock
+    AccountService accountService;
+
+    @Mock
+    UserAccountDao userAccountDao;
+
+    @Mock
+    UserDao userDao;
+
+    @Mock
+    DomainDao domainDao;
+
+    @Mock
+    HttpSession session;
+
+    @Mock
+    HttpServletResponse resp;
+
+    @Mock
+    HttpServletRequest req;
+
+    @Test
+    public void testListAndSwitchSAMLAccountCmd() throws Exception {
+        // Setup
+        final Map<String, Object[]> params = new HashMap<String, Object[]>();
+        final String sessionKeyValue = "someSessionIDValue";
+        Mockito.when(session.getAttribute(ApiConstants.SESSIONKEY)).thenReturn(sessionKeyValue);
+        Mockito.when(session.getAttribute("userid")).thenReturn(2L);
+        params.put(ApiConstants.USER_ID, new String[]{"2"});
+        params.put(ApiConstants.DOMAIN_ID, new String[]{"1"});
+        Mockito.when(userDao.findByUuid(Mockito.anyString())).thenReturn(new UserVO(2L));
+        DomainVO domainFaked = new DomainVO();
+        //domainFaked.setId(1L);
+        Mockito.when(domainDao.findByUuid(Mockito.anyString())).thenReturn(domainFaked);
+
+        // Mock/field setup
+        ListAndSwitchSAMLAccountCmd cmd = new ListAndSwitchSAMLAccountCmd();
+        Field apiServerField = ListAndSwitchSAMLAccountCmd.class.getDeclaredField("_apiServer");
+        apiServerField.setAccessible(true);
+        apiServerField.set(cmd, apiServer);
+
+        Field managerField = ListAndSwitchSAMLAccountCmd.class.getDeclaredField("_samlAuthManager");
+        managerField.setAccessible(true);
+        managerField.set(cmd, samlAuthManager);
+
+        Field accountServiceField = BaseCmd.class.getDeclaredField("_accountService");
+        accountServiceField.setAccessible(true);
+        accountServiceField.set(cmd, accountService);
+
+        Field userAccountDaoField = ListAndSwitchSAMLAccountCmd.class.getDeclaredField("_userAccountDao");
+        userAccountDaoField.setAccessible(true);
+        userAccountDaoField.set(cmd, userAccountDao);
+
+        Field userDaoField = ListAndSwitchSAMLAccountCmd.class.getDeclaredField("_userDao");
+        userDaoField.setAccessible(true);
+        userDaoField.set(cmd, userDao);
+
+        Field domainDaoField = ListAndSwitchSAMLAccountCmd.class.getDeclaredField("_domainDao");
+        domainDaoField.setAccessible(true);
+        domainDaoField.set(cmd, domainDao);
+
+        // invalid session test
+        try {
+            cmd.authenticate("command", params, null, "random", HttpUtils.RESPONSE_TYPE_JSON, new StringBuilder(), req, resp);
+        } catch (ServerApiException exception) {
+            assertEquals(exception.getErrorCode(), ApiErrorCode.UNAUTHORIZED);
+        } finally {
+            Mockito.verify(accountService, Mockito.times(0)).getUserAccountById(Mockito.anyLong());
+        }
+
+        // invalid sessionkey value test
+        params.put(ApiConstants.SESSIONKEY, new String[]{"someOtherValue"});
+        try {
+            Mockito.when(session.isNew()).thenReturn(false);
+            cmd.authenticate("command", params, session, "random", HttpUtils.RESPONSE_TYPE_JSON, new StringBuilder(), req, resp);
+        } catch (ServerApiException exception) {
+            assertEquals(exception.getErrorCode(), ApiErrorCode.UNAUTHORIZED);
+        } finally {
+            Mockito.verify(accountService, Mockito.times(0)).getUserAccountById(Mockito.anyLong());
+        }
+
+        // valid sessionkey value test
+        params.put(ApiConstants.SESSIONKEY, new String[]{sessionKeyValue});
+        try {
+            cmd.authenticate("command", params, session, "random", HttpUtils.RESPONSE_TYPE_JSON, new StringBuilder(), req, resp);
+        } catch (ServerApiException exception) {
+            assertEquals(exception.getErrorCode(), ApiErrorCode.ACCOUNT_ERROR);
+        } finally {
+            Mockito.verify(accountService, Mockito.times(1)).getUserAccountById(Mockito.anyLong());
+        }
+
+        // valid sessionkey, invalid useraccount type (non-saml) value test
+        UserAccountVO mockedUserAccount = new UserAccountVO();
+        mockedUserAccount.setId(2L);
+        mockedUserAccount.setAccountState(Account.State.enabled.toString());
+        mockedUserAccount.setUsername("someUsername");
+        mockedUserAccount.setExternalEntity("some IDP ID");
+        mockedUserAccount.setDomainId(0L);
+        mockedUserAccount.setSource(User.Source.UNKNOWN);
+        Mockito.when(accountService.getUserAccountById(Mockito.anyLong())).thenReturn(mockedUserAccount);
+        try {
+            cmd.authenticate("command", params, session, "random", HttpUtils.RESPONSE_TYPE_JSON, new StringBuilder(), req, resp);
+        } catch (ServerApiException exception) {
+            assertEquals(exception.getErrorCode(), ApiErrorCode.ACCOUNT_ERROR);
+        } finally {
+            // accountService should have been called twice by now, for this case and the case above
+            Mockito.verify(accountService, Mockito.times(2)).getUserAccountById(Mockito.anyLong());
+        }
+
+        // all valid test
+        mockedUserAccount.setSource(User.Source.SAML2);
+        Mockito.when(accountService.getUserAccountById(Mockito.anyLong())).thenReturn(mockedUserAccount);
+        Mockito.when(apiServer.verifyUser(Mockito.anyLong())).thenReturn(true);
+        LoginCmdResponse loginCmdResponse = new LoginCmdResponse();
+        loginCmdResponse.setUserId("1");
+        loginCmdResponse.setDomainId("1");
+        loginCmdResponse.setType("1");
+        loginCmdResponse.setUsername("userName");
+        loginCmdResponse.setAccount("someAccount");
+        loginCmdResponse.setFirstName("firstName");
+        loginCmdResponse.setLastName("lastName");
+        loginCmdResponse.setSessionKey("newSessionKeyString");
+        Mockito.when(apiServer.loginUser(Mockito.any(HttpSession.class), Mockito.anyString(), Mockito.anyString(),
+                Mockito.anyLong(), Mockito.anyString(), Mockito.anyString(), Mockito.anyMap())).thenReturn(loginCmdResponse);
+        try {
+            cmd.authenticate("command", params, session, "random", HttpUtils.RESPONSE_TYPE_JSON, new StringBuilder(), req, resp);
+        } catch (ServerApiException exception) {
+            fail("SAML list and switch account API failed to pass for all valid data: " + exception.getMessage());
+        } finally {
+            //Mockito.verify(resp, Mockito.times(1)).sendRedirect(Mockito.anyString());
+            // accountService should have been called 4 times by now, for this case twice and 2 for cases above
+            Mockito.verify(accountService, Mockito.times(4)).getUserAccountById(Mockito.anyLong());
+        }
+    }
+
+    @Test
+    public void testGetAPIType() {
+        Assert.assertTrue(new ListAndSwitchSAMLAccountCmd().getAPIType() == APIAuthenticationType.READONLY_API);
+    }
+
+}


[2/3] git commit: updated refs/heads/4.5-samlfixes to 1527ad6

Posted by bh...@apache.org.
engine: fix accountState setter name

Signed-off-by: Rohit Yadav <ro...@shapeblue.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/856001d3
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/856001d3
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/856001d3

Branch: refs/heads/4.5-samlfixes
Commit: 856001d3600305c82af5948061e6fe43cc2c4a76
Parents: 0887f64
Author: Rohit Yadav <ro...@shapeblue.com>
Authored: Wed Aug 12 14:03:17 2015 +0530
Committer: Rohit Yadav <ro...@shapeblue.com>
Committed: Wed Aug 12 14:09:36 2015 +0530

----------------------------------------------------------------------
 engine/schema/src/com/cloud/user/UserAccountVO.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/856001d3/engine/schema/src/com/cloud/user/UserAccountVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/user/UserAccountVO.java b/engine/schema/src/com/cloud/user/UserAccountVO.java
index 80ee873..5ce0eb7 100644
--- a/engine/schema/src/com/cloud/user/UserAccountVO.java
+++ b/engine/schema/src/com/cloud/user/UserAccountVO.java
@@ -251,7 +251,7 @@ public class UserAccountVO implements UserAccount, InternalIdentity {
         return accountState;
     }
 
-    public void setAccountDisabled(String accountState) {
+    public void setAccountState(String accountState) {
         this.accountState = accountState;
     }
 


[3/3] git commit: updated refs/heads/4.5-samlfixes to 1527ad6

Posted by bh...@apache.org.
utils: add HttpUtils test

Signed-off-by: Rohit Yadav <ro...@shapeblue.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/0887f64e
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/0887f64e
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/0887f64e

Branch: refs/heads/4.5-samlfixes
Commit: 0887f64e451c6afe5f15e203a0c7d66f27c9b29d
Parents: 69f39d5
Author: Rohit Yadav <ro...@shapeblue.com>
Authored: Wed Aug 12 14:02:57 2015 +0530
Committer: Rohit Yadav <ro...@shapeblue.com>
Committed: Wed Aug 12 14:09:36 2015 +0530

----------------------------------------------------------------------
 utils/src/com/cloud/utils/HttpUtils.java      | 32 +++++---
 utils/test/com/cloud/utils/HttpUtilsTest.java | 94 ++++++++++++++++++++++
 2 files changed, 113 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0887f64e/utils/src/com/cloud/utils/HttpUtils.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/HttpUtils.java b/utils/src/com/cloud/utils/HttpUtils.java
index 379b117..d2e844a 100644
--- a/utils/src/com/cloud/utils/HttpUtils.java
+++ b/utils/src/com/cloud/utils/HttpUtils.java
@@ -52,18 +52,6 @@ public class HttpUtils {
         }
     }
 
-    public static String findCookie(final Cookie[] cookies, final String key) {
-        if (cookies == null || key == null || key.isEmpty()) {
-            return null;
-        }
-        for (Cookie cookie: cookies) {
-            if (cookie != null && cookie.getName().equals(key)) {
-                return cookie.getValue();
-            }
-        }
-        return null;
-    }
-
     public static void writeHttpResponse(final HttpServletResponse resp, final String response,
                                          final Integer responseCode, final String responseType, final String jsonContentType) {
         try {
@@ -92,10 +80,28 @@ public class HttpUtils {
         }
     }
 
+    public static String findCookie(final Cookie[] cookies, final String key) {
+        if (cookies == null || key == null || key.isEmpty()) {
+            return null;
+        }
+        for (Cookie cookie: cookies) {
+            if (cookie != null && cookie.getName().equals(key)) {
+                return cookie.getValue();
+            }
+        }
+        return null;
+    }
+
     public static boolean validateSessionKey(final HttpSession session, final Map<String, Object[]> params, final Cookie[] cookies, final String sessionKeyString) {
+        if (session == null || sessionKeyString == null) {
+            return false;
+        }
         final String sessionKey = (String) session.getAttribute(sessionKeyString);
         final String sessionKeyFromCookie = HttpUtils.findCookie(cookies, sessionKeyString);
-        final String[] sessionKeyFromParams = (String[]) params.get(sessionKeyString);
+        String[] sessionKeyFromParams = null;
+        if (params != null) {
+            sessionKeyFromParams = (String[]) params.get(sessionKeyString);
+        }
         if ((sessionKey == null)
                 || (sessionKeyFromParams == null && sessionKeyFromCookie == null)
                 || (sessionKeyFromParams != null && !sessionKey.equals(sessionKeyFromParams[0]))

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0887f64e/utils/test/com/cloud/utils/HttpUtilsTest.java
----------------------------------------------------------------------
diff --git a/utils/test/com/cloud/utils/HttpUtilsTest.java b/utils/test/com/cloud/utils/HttpUtilsTest.java
new file mode 100644
index 0000000..e10a5a3
--- /dev/null
+++ b/utils/test/com/cloud/utils/HttpUtilsTest.java
@@ -0,0 +1,94 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.cloud.utils;
+
+import org.junit.Test;
+import org.springframework.mock.web.MockHttpSession;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpSession;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+public class HttpUtilsTest {
+
+    @Test
+    public void findCookieTest() {
+        Cookie[] cookies = null;
+        String cookieName = null;
+
+        // null test
+        assertNull(HttpUtils.findCookie(cookies, cookieName));
+        cookieName = "";
+        assertNull(HttpUtils.findCookie(cookies, cookieName));
+
+        // value test
+        cookieName = "daakuBandar";
+        cookies = new Cookie[]{new Cookie(cookieName, "someValue")};
+        assertNull(HttpUtils.findCookie(cookies, "aalasiLangur"));
+        assertNotNull(HttpUtils.findCookie(cookies, cookieName));
+    }
+
+    @Test
+    public void validateSessionKeyTest() {
+        HttpSession session = null;
+        Map<String, Object[]> params = null;
+        String sessionKeyString = null;
+        Cookie[] cookies = null;
+        final String sessionKeyValue = "randomUniqueSessionID";
+
+        // session and sessionKeyString null test
+        assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString));
+        sessionKeyString =  "sessionkey";
+        assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString));
+
+        // param and cookie null test
+        session = new MockHttpSession();
+        session.setAttribute(sessionKeyString, sessionKeyValue);
+        assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString));
+
+        // param null, cookies not null test
+        params = null;
+        cookies = new Cookie[]{new Cookie(sessionKeyString, sessionKeyValue)};
+        assertFalse(HttpUtils.validateSessionKey(session, params, cookies, "randomString"));
+        assertTrue(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString));
+
+        // param not null, cookies null test
+        params = new HashMap<String, Object[]>();
+        params.put(sessionKeyString, new String[]{"randomString"});
+        cookies = null;
+        assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString));
+        params.put(sessionKeyString, new String[]{sessionKeyValue});
+        assertTrue(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString));
+
+        // both param and cookies not null test
+        params = new HashMap<String, Object[]>();
+        cookies = new Cookie[]{new Cookie(sessionKeyString, sessionKeyValue)};
+        params.put(sessionKeyString, new String[]{"incorrectValue"});
+        assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString));
+        params.put(sessionKeyString, new String[]{sessionKeyValue});
+        assertTrue(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString));
+    }
+}