From 22ce98537a82e709d50d70ac12d51e89b63df426 Mon Sep 17 00:00:00 2001
From: Piotr Gawron <piotr.gawron@uni.lu>
Date: Tue, 20 Feb 2018 08:43:41 +0100
Subject: [PATCH] minerva session id is provided as a spring security session
 id and is stored via spring

---
 .../mapviewer/api/users/UserController.java   |  83 +--
 .../mapviewer/services/impl/UserService.java  |  78 ++-
 .../services/interfaces/IUserService.java     | 500 +++++++++---------
 .../services/view/AuthenticationToken.java    |  58 +-
 .../java/lcsb/mapviewer/bean/UserBean.java    |   5 -
 .../security/MvSecurityServiceImpl.java       |  87 +--
 web/src/main/webapp/WEB-INF/web.xml           |   3 +
 web/src/main/webapp/login.xhtml               |  26 +-
 8 files changed, 440 insertions(+), 400 deletions(-)

diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/users/UserController.java b/rest-api/src/main/java/lcsb/mapviewer/api/users/UserController.java
index f9bec121f2..508fa68941 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/users/UserController.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/users/UserController.java
@@ -1,7 +1,6 @@
 package lcsb.mapviewer.api.users;
 
 import java.io.IOException;
-import java.util.Calendar;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -13,8 +12,12 @@ import javax.servlet.http.HttpServletResponse;
 import org.apache.log4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.MediaType;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.session.SessionRegistry;
+import org.springframework.security.web.authentication.WebAuthenticationDetails;
 import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
 import org.springframework.util.MultiValueMap;
 import org.springframework.web.bind.annotation.CookieValue;
@@ -50,34 +53,36 @@ public class UserController extends BaseController {
   @Autowired
   private UserRestImpl userRest;
 
+  @Autowired
+  private AuthenticationProvider authenticationProvider;
+
+  @Autowired
+  private SessionRegistry sessionRegistry;
+
   @RequestMapping(value = "/doLogin", method = { RequestMethod.GET, RequestMethod.POST }, produces = {
       MediaType.APPLICATION_JSON_VALUE })
   public Map<String, Object> login(//
       @RequestParam(value = "login", defaultValue = Configuration.ANONYMOUS_LOGIN) String login, //
-      @RequestParam(value = "password", required = false) String password, //
-      HttpServletResponse response //
+      @RequestParam(value = "password", defaultValue = "") String password, //
+      HttpServletResponse response, //
+      HttpServletRequest request//
   ) throws SecurityException, IOException {
-    AuthenticationToken token = userService.login(login, password);
+    AuthenticationToken token = userService.login(login, password, request.getSession().getId());
     if (token == null) {
       throw new SecurityException("Invalid credentials");
     } else {
+      UsernamePasswordAuthenticationToken springToken = new UsernamePasswordAuthenticationToken(login, password);
+      springToken.setDetails(new WebAuthenticationDetails(request));
+      Authentication authentication = this.authenticationProvider.authenticate(springToken);
+      SecurityContextHolder.getContext().setAuthentication(authentication);
+      sessionRegistry.registerNewSession(request.getSession().getId(), authentication.getPrincipal());
+      
       Map<String, Object> result = new HashMap<>();
-      final Boolean useSecureCookie = false;
-      final int expiryTime = (int) (token.getExpires().getTimeInMillis() - Calendar.getInstance().getTimeInMillis())
-          / 1000;
-      final String cookiePath = "/";
-
-      Cookie cookie = new Cookie("MINERVA_AUTH_TOKEN", token.getId());
 
-      cookie.setSecure(useSecureCookie);
-      cookie.setMaxAge(expiryTime);
-      cookie.setPath(cookiePath);
-
-			response.addCookie(cookie);
-			result.put("info", "Login successful. TOKEN returned as a cookie");
-			return result;
-		}
-	}
+      result.put("info", "Login successful. TOKEN returned as a cookie");
+      return result;
+    }
+  }
 
   @RequestMapping(value = "/users/{login:.+}", method = { RequestMethod.GET }, produces = {
       MediaType.APPLICATION_JSON_VALUE })
@@ -126,15 +131,13 @@ public class UserController extends BaseController {
   public Map<String, String> logout(@CookieValue(value = Configuration.AUTH_TOKEN) String token,
       HttpServletRequest request, HttpServletResponse response //
   ) throws SecurityException, IOException {
-    //spring logout
+    // spring logout
     Authentication auth = SecurityContextHolder.getContext().getAuthentication();
     logger.debug("LOGOUT");
     logger.debug(auth);
-    if (auth != null){
-        new SecurityContextLogoutHandler().logout(request, response, auth);
+    if (auth != null) {
+      new SecurityContextLogoutHandler().logout(request, response, auth);
     }
-    //our session manager logout
-    userService.logout(token);
 
     Map<String, String> result = new HashMap<>();
     result.put("status", "OK");
@@ -148,24 +151,26 @@ public class UserController extends BaseController {
     cookie.setMaxAge(0);
     cookie.setPath(cookiePath);
 
-		response.addCookie(cookie);
-        result.put("status", "OK");
-		return result;
-	}
+    response.addCookie(cookie);
+    result.put("status", "OK");
+    return result;
+  }
 
-  @RequestMapping(value = "/users/{login:.+}", method = { RequestMethod.PATCH }, produces = { MediaType.APPLICATION_JSON_VALUE })
+  @RequestMapping(value = "/users/{login:.+}", method = { RequestMethod.PATCH }, produces = {
+      MediaType.APPLICATION_JSON_VALUE })
   public Map<String, Object> updateUser(//
-          @RequestBody String body, //
-          @PathVariable(value = "login") String login, //
-          @CookieValue(value = Configuration.AUTH_TOKEN) String token //
+      @RequestBody String body, //
+      @PathVariable(value = "login") String login, //
+      @CookieValue(value = Configuration.AUTH_TOKEN) String token //
   ) throws SecurityException, QueryException, IOException {
-      Map<String, Object> node = parseBody(body);
-      Map<String, Object> data = getData(node, "user");
-      return userRest.updateUser(token, login, data);
+    Map<String, Object> node = parseBody(body);
+    Map<String, Object> data = getData(node, "user");
+    return userRest.updateUser(token, login, data);
   }
 
-  @RequestMapping(value = "/users/{login:.+}", method = { RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE })
-  public Map<String, Object>  addOverlay(//
+  @RequestMapping(value = "/users/{login:.+}", method = { RequestMethod.POST }, produces = {
+      MediaType.APPLICATION_JSON_VALUE })
+  public Map<String, Object> addOverlay(//
       @RequestBody MultiValueMap<String, Object> formData, //
       @PathVariable(value = "login") String login, //
       @CookieValue(value = Configuration.AUTH_TOKEN) String token //
@@ -174,7 +179,8 @@ public class UserController extends BaseController {
 
   }
 
-  @RequestMapping(value = "/users/{login:.+}", method = { RequestMethod.DELETE }, produces = { MediaType.APPLICATION_JSON_VALUE })
+  @RequestMapping(value = "/users/{login:.+}", method = { RequestMethod.DELETE }, produces = {
+      MediaType.APPLICATION_JSON_VALUE })
   public Map<String, Object> removeProject(//
       @PathVariable(value = "login") String login, //
       @CookieValue(value = Configuration.AUTH_TOKEN) String token //
@@ -183,7 +189,6 @@ public class UserController extends BaseController {
 
   }
 
-
   /**
    * @return the userService
    * @see #userService
diff --git a/service/src/main/java/lcsb/mapviewer/services/impl/UserService.java b/service/src/main/java/lcsb/mapviewer/services/impl/UserService.java
index f2bbf63c14..5a72274aa3 100644
--- a/service/src/main/java/lcsb/mapviewer/services/impl/UserService.java
+++ b/service/src/main/java/lcsb/mapviewer/services/impl/UserService.java
@@ -1,15 +1,20 @@
 package lcsb.mapviewer.services.impl;
 
 import java.awt.Color;
+import java.math.BigInteger;
+import java.security.SecureRandom;
 import java.util.ArrayList;
-import java.util.Calendar;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Random;
 
 import org.apache.log4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.security.core.session.SessionInformation;
+import org.springframework.security.core.session.SessionRegistry;
 import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -78,6 +83,9 @@ public class UserService implements IUserService {
   @Autowired
   private PrivilegeDao privilegeDao;
 
+  @Autowired
+  private SessionRegistry sessionRegistry;
+
   /**
    * Factory object for {@link UserView} elements.
    */
@@ -97,42 +105,23 @@ public class UserService implements IUserService {
   private ILogService logService;
 
   /**
-   * Service used for accessing confguration parameters.
+   * Service used for accessing configuration parameters.
    */
   @Autowired
   private IConfigurationService configurationService;
 
   @Override
   public AuthenticationToken login(String login, String password) {
-    User user = userDao.getUserByLoginAndPassword(login, password);
-    if (Configuration.ANONYMOUS_LOGIN.equals(login)) {
-      user = getUserByLogin(Configuration.ANONYMOUS_LOGIN);
-    }
-    if (user != null) {
-      int count = 0;
-      synchronized (authenticationTokens) {
-        count = authenticationTokens.size();
-      }
-
-      if (count > 1000) {
-        clearAuthenticationTokens();
-      }
-      AuthenticationToken authenticationToken = new AuthenticationToken();
-      synchronized (authenticationTokens) {
-        authenticationTokens.put(authenticationToken.getId(), authenticationToken);
-        authenticatedUsers.put(authenticationToken, user);
-      }
-      return authenticationToken;
-    } else {
-      return null;
-    }
+    Random random = new SecureRandom();
+    String id = new BigInteger(130, random).toString(32);
+    return this.login(login, password, id);
   }
 
   private void clearAuthenticationTokens() {
     synchronized (authenticationTokens) {
       List<String> toRemove = new ArrayList<>();
       for (AuthenticationToken token : authenticationTokens.values()) {
-        if (token.getExpires().before(Calendar.getInstance())) {
+        if (isSessionExpired(token)) {
           toRemove.add(token.getId());
         }
       }
@@ -522,7 +511,7 @@ public class UserService implements IUserService {
   @Override
   public User getUserByToken(AuthenticationToken token) {
     User result = null;
-    if (Calendar.getInstance().before(token.getExpires())) {
+    if (!isSessionExpired(token)) {
       synchronized (authenticationTokens) {
         result = authenticatedUsers.get(token);
       }
@@ -544,13 +533,22 @@ public class UserService implements IUserService {
     if (result == null) {
       throw new InvalidTokenException("Token string is invalid");
     }
-    if (result.getExpires().before(Calendar.getInstance())) {
+    if (isSessionExpired(result)) {
       logout(result);
       throw new AuthenticationTokenExpireException("Token validity expired");
     }
     return result;
   }
 
+  private boolean isSessionExpired(AuthenticationToken result) {
+    SessionInformation sessionData = sessionRegistry.getSessionInformation(result.getId());
+    if (sessionData == null) {
+      logger.debug("No session data for token id: " + result.getId());
+      return true;
+    }
+    return sessionData.isExpired();
+  }
+
   @Override
   public void logout(AuthenticationToken token) {
     synchronized (authenticationTokens) {
@@ -664,4 +662,30 @@ public class UserService implements IUserService {
     return userHasPrivilege(getUserByToken(token), type);
   }
 
+  @Override
+  public AuthenticationToken login(String login, String password, String id) {
+    User user = userDao.getUserByLoginAndPassword(login, password);
+    if (user == null && Configuration.ANONYMOUS_LOGIN.equals(login) && "".equals(password)) {
+      user = getUserByLogin(Configuration.ANONYMOUS_LOGIN);
+    }
+    if (user != null) {
+      int count = 0;
+      synchronized (authenticationTokens) {
+        count = authenticationTokens.size();
+      }
+
+      if (count > 1000) {
+        clearAuthenticationTokens();
+      }
+      AuthenticationToken authenticationToken = new AuthenticationToken(id);
+      synchronized (authenticationTokens) {
+        authenticationTokens.put(authenticationToken.getId(), authenticationToken);
+        authenticatedUsers.put(authenticationToken, user);
+      }
+      return authenticationToken;
+    } else {
+      return null;
+    }
+  }
+
 }
diff --git a/service/src/main/java/lcsb/mapviewer/services/interfaces/IUserService.java b/service/src/main/java/lcsb/mapviewer/services/interfaces/IUserService.java
index 72aa5851f1..5cc8b181b2 100644
--- a/service/src/main/java/lcsb/mapviewer/services/interfaces/IUserService.java
+++ b/service/src/main/java/lcsb/mapviewer/services/interfaces/IUserService.java
@@ -15,256 +15,258 @@ import lcsb.mapviewer.services.view.UserView;
  * Service that manages users.
  * 
  * @author Piotr Gawron
- *  
+ * 
  */
 public interface IUserService {
-	/**
-	 * Check if its possible to login using given login and password.
-	 * 
-	 * @param login
-	 *          user login
-	 * @param password
-	 *          plan password
-	 * @return {@link AuthenticationToken} if credentials are valid,
-	 *         <code>null</code> otherwise
-	 */
-	AuthenticationToken login(String login, String password);
-
-	/**
-	 * Returns user by login.
-	 * 
-	 * @param login
-	 *          user login
-	 * @return user if the login is valid, <code>null</code> otherwise
-	 */
-	User getUserByLogin(String login);
-
-	/**
-	 * Checks if user has a given privilege.
-	 * 
-	 * @param user
-	 *          user for which the check is performed
-	 * @param type
-	 *          type of the privilege
-	 * @return <code>true</code> if user has privilege, <code>false</code>
-	 *         otherwise
-	 */
-    boolean userHasPrivilege(User user, PrivilegeType type);
-    
-    boolean userHasPrivilege(String token, PrivilegeType type) throws SecurityException;
-
-	/**
-	 * Returns level of the user privilege.
-	 * 
-	 * @param user
-	 *          user for which the check is performed
-	 * @param type
-	 *          type of the privilege
-	 * @return level of the privilege
-	 */
-	int getUserPrivilegeLevel(User user, PrivilegeType type);
-
-	/**
-	 * Checks if user has a given privilege on the object.
-	 * 
-	 * @param user
-	 *          user for which the check is performed
-	 * @param type
-	 *          type of the privilege
-	 * @param object
-	 *          object of the privilege
-	 * @return <code>true</code> if user has privilege, <code>false</code>
-	 *         otherwise
-	 */
-	boolean userHasPrivilege(User user, PrivilegeType type, Object object);
-
-	/**
-	 * Returns level of the user privilege.
-	 * 
-	 * @param object
-	 *          object of the privilege
-	 * @param user
-	 *          user for which the check is performed
-	 * @param type
-	 *          type of the privilege
-	 * @return level of the privilege
-	 */
-	int getUserPrivilegeLevel(User user, PrivilegeType type, Object object);
-
-	/**
-	 * Sets the user privilege.
-	 * 
-	 * @param user
-	 *          user for whom the privilege should be granted/dropped
-	 * @param privilege
-	 *          user privilege
-	 */
-	void setUserPrivilege(User user, BasicPrivilege privilege);
-
-	/**
-	 * Adds user to the system.
-	 * 
-	 * @param user
-	 *          user to be added
-	 */
-	void addUser(User user);
-
-	/**
-	 * Updates user in the system.
-	 * 
-	 * @param user
-	 *          user to be updated
-	 */
-	void updateUser(User user);
-
-	/**
-	 * Removes user from the system.
-	 * 
-	 * @param user
-	 *          user to be removed
-	 */
-	void deleteUser(User user);
-
-	/**
-	 * Returns user by the database identifier.
-	 * 
-	 * @param id
-	 *          database identifier
-	 * @return user for the given identifier, null if user doesn't exist
-	 * 
-	 */
-	User getUserById(int id);
-
-	/**
-	 * Returns user views for all users.
-	 * 
-	 * @return list of user {@link lcsb.mapviewer.services.view.AbstractView
-	 *         views} for all users
-	 */
-	List<UserView> getAllUserRows();
-
-	/**
-	 * @param user
-	 *          user that will have view.
-	 * @return view for one user.
-	 */
-	UserView getUserRow(User user);
-
-	/**
-	 * Updates user from user {@link lcsb.mapviewer.services.view.AbstractView
-	 * view}.
-	 * 
-	 * @param selectedUser
-	 *          user {@link lcsb.mapviewer.services.view.AbstractView view} to
-	 *          update
-	 */
-	void updateUser(UserView selectedUser);
-
-	/**
-	 * Removes user based on user {@link lcsb.mapviewer.services.view.AbstractView
-	 * view}.
-	 * 
-	 * @param selectedUser
-	 *          user {@link lcsb.mapviewer.services.view.AbstractView view} to be
-	 *          removed
-	 */
-	void deleteUser(UserView selectedUser);
-
-	/**
-	 * Creates empty view.
-	 * 
-	 * @return empty user {@link lcsb.mapviewer.services.view.AbstractView view} .
-	 */
-	UserView createEmptyUserRow();
-
-	/**
-	 * Drops privileges for every user on the given object and type.
-	 * 
-	 * @param type
-	 *          type of privilege that should be dropped
-	 * @param objectId
-	 *          identifier of the object to which privileges should be dropped
-	 */
-	void dropPrivilegesForObjectType(PrivilegeType type, int objectId);
-
-	/**
-	 * Adds user from user view.
-	 * 
-	 * @param selectedUser
-	 *          user view representation that should be added
-	 */
-	void addUser(UserView selectedUser);
-
-	/**
-	 * Adds privilege to the user.
-	 * 
-	 * @param user
-	 *          user to which privilege should be added
-	 * @param type
-	 *          type of the privilege
-	 */
-	void setUserPrivilege(User user, PrivilegeType type, Integer value);
-
-	/**
-	 * Updates users from list of user
-	 * {@link lcsb.mapviewer.services.view.AbstractView view}.
-	 * 
-	 * @param users
-	 *          user {@link lcsb.mapviewer.services.view.AbstractView views} to
-	 *          update
-	 */
-	void updateUsers(Collection<UserView> users);
-
-	/**
-	 * @param password
-	 *          input password
-	 * @return encoded password
-	 */
-	String encodePassword(String password);
-
-	/**
-	 * Returns {@link User} for given "name surname" string.
-	 * 
-	 * @param nameSurnameString
-	 *          string identifying user with name and surname separated by single
-	 *          space
-	 * @return {@link User} for given "name surname" string
-	 */
-	User getUserByNameSurname(String nameSurnameString);
-
-	/**
-	 * Returns {@link ColorExtractor} that transform overlay values into colors
-	 * for given user.
-	 * 
-	 * @param user
-	 *          {@link User} for which {@link ColorExtractor} will be obtained
-	 * @return {@link ColorExtractor} that transform overlay values into colors
-	 *         for given user
-	 */
-	ColorExtractor getColorExtractorForUser(User user);
-
-	User getUserByToken(AuthenticationToken token);
-
-	User getUserByToken(String token) throws SecurityException;
-
-	AuthenticationToken getToken(String token) throws SecurityException;
-
-	boolean userHasPrivilege(AuthenticationToken token, PrivilegeType type, Object object);
-
-	void logout(String tokenString) throws SecurityException;
-
-	void logout(AuthenticationToken token);
-
-	boolean userHasPrivilege(AuthenticationToken token, PrivilegeType addMap);
-
-	User getUserById(String creatorId, AuthenticationToken authenticationToken) throws SecurityException;
-
-	List<User> getUsers(AuthenticationToken token) throws SecurityException;
-
-	void setUserPrivilege(User modifiedUser, PrivilegeType type, Object privilegeToSet, AuthenticationToken authenticationToken) throws SecurityException;
-
-	void setUserPrivilege(User modifiedUser, PrivilegeType type, Object privilegeToSet, Integer objectId, AuthenticationToken authenticationToken) throws SecurityException;
-
-	void updateUser(User modifiedUser, AuthenticationToken authenticationToken) throws SecurityException;
+  /**
+   * Check if its possible to login using given login and password.
+   * 
+   * @param login
+   *          user login
+   * @param password
+   *          plan password
+   * @return {@link AuthenticationToken} if credentials are valid,
+   *         <code>null</code> otherwise
+   */
+  AuthenticationToken login(String login, String password);
+
+  /**
+   * Returns user by login.
+   * 
+   * @param login
+   *          user login
+   * @return user if the login is valid, <code>null</code> otherwise
+   */
+  User getUserByLogin(String login);
+
+  /**
+   * Checks if user has a given privilege.
+   * 
+   * @param user
+   *          user for which the check is performed
+   * @param type
+   *          type of the privilege
+   * @return <code>true</code> if user has privilege, <code>false</code> otherwise
+   */
+  boolean userHasPrivilege(User user, PrivilegeType type);
+
+  boolean userHasPrivilege(String token, PrivilegeType type) throws SecurityException;
+
+  /**
+   * Returns level of the user privilege.
+   * 
+   * @param user
+   *          user for which the check is performed
+   * @param type
+   *          type of the privilege
+   * @return level of the privilege
+   */
+  int getUserPrivilegeLevel(User user, PrivilegeType type);
+
+  /**
+   * Checks if user has a given privilege on the object.
+   * 
+   * @param user
+   *          user for which the check is performed
+   * @param type
+   *          type of the privilege
+   * @param object
+   *          object of the privilege
+   * @return <code>true</code> if user has privilege, <code>false</code> otherwise
+   */
+  boolean userHasPrivilege(User user, PrivilegeType type, Object object);
+
+  /**
+   * Returns level of the user privilege.
+   * 
+   * @param object
+   *          object of the privilege
+   * @param user
+   *          user for which the check is performed
+   * @param type
+   *          type of the privilege
+   * @return level of the privilege
+   */
+  int getUserPrivilegeLevel(User user, PrivilegeType type, Object object);
+
+  /**
+   * Sets the user privilege.
+   * 
+   * @param user
+   *          user for whom the privilege should be granted/dropped
+   * @param privilege
+   *          user privilege
+   */
+  void setUserPrivilege(User user, BasicPrivilege privilege);
+
+  /**
+   * Adds user to the system.
+   * 
+   * @param user
+   *          user to be added
+   */
+  void addUser(User user);
+
+  /**
+   * Updates user in the system.
+   * 
+   * @param user
+   *          user to be updated
+   */
+  void updateUser(User user);
+
+  /**
+   * Removes user from the system.
+   * 
+   * @param user
+   *          user to be removed
+   */
+  void deleteUser(User user);
+
+  /**
+   * Returns user by the database identifier.
+   * 
+   * @param id
+   *          database identifier
+   * @return user for the given identifier, null if user doesn't exist
+   * 
+   */
+  User getUserById(int id);
+
+  /**
+   * Returns user views for all users.
+   * 
+   * @return list of user {@link lcsb.mapviewer.services.view.AbstractView views}
+   *         for all users
+   */
+  List<UserView> getAllUserRows();
+
+  /**
+   * @param user
+   *          user that will have view.
+   * @return view for one user.
+   */
+  UserView getUserRow(User user);
+
+  /**
+   * Updates user from user {@link lcsb.mapviewer.services.view.AbstractView
+   * view}.
+   * 
+   * @param selectedUser
+   *          user {@link lcsb.mapviewer.services.view.AbstractView view} to
+   *          update
+   */
+  void updateUser(UserView selectedUser);
+
+  /**
+   * Removes user based on user {@link lcsb.mapviewer.services.view.AbstractView
+   * view}.
+   * 
+   * @param selectedUser
+   *          user {@link lcsb.mapviewer.services.view.AbstractView view} to be
+   *          removed
+   */
+  void deleteUser(UserView selectedUser);
+
+  /**
+   * Creates empty view.
+   * 
+   * @return empty user {@link lcsb.mapviewer.services.view.AbstractView view} .
+   */
+  UserView createEmptyUserRow();
+
+  /**
+   * Drops privileges for every user on the given object and type.
+   * 
+   * @param type
+   *          type of privilege that should be dropped
+   * @param objectId
+   *          identifier of the object to which privileges should be dropped
+   */
+  void dropPrivilegesForObjectType(PrivilegeType type, int objectId);
+
+  /**
+   * Adds user from user view.
+   * 
+   * @param selectedUser
+   *          user view representation that should be added
+   */
+  void addUser(UserView selectedUser);
+
+  /**
+   * Adds privilege to the user.
+   * 
+   * @param user
+   *          user to which privilege should be added
+   * @param type
+   *          type of the privilege
+   */
+  void setUserPrivilege(User user, PrivilegeType type, Integer value);
+
+  /**
+   * Updates users from list of user
+   * {@link lcsb.mapviewer.services.view.AbstractView view}.
+   * 
+   * @param users
+   *          user {@link lcsb.mapviewer.services.view.AbstractView views} to
+   *          update
+   */
+  void updateUsers(Collection<UserView> users);
+
+  /**
+   * @param password
+   *          input password
+   * @return encoded password
+   */
+  String encodePassword(String password);
+
+  /**
+   * Returns {@link User} for given "name surname" string.
+   * 
+   * @param nameSurnameString
+   *          string identifying user with name and surname separated by single
+   *          space
+   * @return {@link User} for given "name surname" string
+   */
+  User getUserByNameSurname(String nameSurnameString);
+
+  /**
+   * Returns {@link ColorExtractor} that transform overlay values into colors for
+   * given user.
+   * 
+   * @param user
+   *          {@link User} for which {@link ColorExtractor} will be obtained
+   * @return {@link ColorExtractor} that transform overlay values into colors for
+   *         given user
+   */
+  ColorExtractor getColorExtractorForUser(User user);
+
+  User getUserByToken(AuthenticationToken token);
+
+  User getUserByToken(String token) throws SecurityException;
+
+  AuthenticationToken getToken(String token) throws SecurityException;
+
+  boolean userHasPrivilege(AuthenticationToken token, PrivilegeType type, Object object);
+
+  void logout(String tokenString) throws SecurityException;
+
+  void logout(AuthenticationToken token);
+
+  boolean userHasPrivilege(AuthenticationToken token, PrivilegeType addMap);
+
+  User getUserById(String creatorId, AuthenticationToken authenticationToken) throws SecurityException;
+
+  List<User> getUsers(AuthenticationToken token) throws SecurityException;
+
+  void setUserPrivilege(User modifiedUser, PrivilegeType type, Object privilegeToSet,
+      AuthenticationToken authenticationToken) throws SecurityException;
+
+  void setUserPrivilege(User modifiedUser, PrivilegeType type, Object privilegeToSet, Integer objectId,
+      AuthenticationToken authenticationToken) throws SecurityException;
+
+  void updateUser(User modifiedUser, AuthenticationToken authenticationToken) throws SecurityException;
+
+  AuthenticationToken login(String login, String password, String id);
 
 }
diff --git a/service/src/main/java/lcsb/mapviewer/services/view/AuthenticationToken.java b/service/src/main/java/lcsb/mapviewer/services/view/AuthenticationToken.java
index 91c065e193..0c82659040 100644
--- a/service/src/main/java/lcsb/mapviewer/services/view/AuthenticationToken.java
+++ b/service/src/main/java/lcsb/mapviewer/services/view/AuthenticationToken.java
@@ -4,38 +4,40 @@ import java.math.BigInteger;
 import java.security.SecureRandom;
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
-import java.util.Random;
 
 public class AuthenticationToken {
-	private String	 id;
-	private Calendar expires;
+  private String id;
+//  private Calendar expires;
 
-	public AuthenticationToken() {
-		Random random = new SecureRandom();
-		id = new BigInteger(130, random).toString(32);
-		expires = Calendar.getInstance();
-		expires.add(Calendar.HOUR, 2);
-	}
+  public AuthenticationToken() {
+    this(new BigInteger(130, new SecureRandom()).toString(32));
+  }
 
-	/**
-	 * @return the id
-	 * @see #id
-	 */
-	public String getId() {
-		return id;
-	}
+  public AuthenticationToken(String id) {
+    this.id = id;
+//    expires = Calendar.getInstance();
+//    expires.add(Calendar.HOUR, 2);
+  }
 
-	/**
-	 * @return the expires
-	 * @see #expires
-	 */
-	public Calendar getExpires() {
-		return expires;
-	}
-
-	@Override
-	public String toString() {
-		return getId() + ", expirese: " + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX").format(expires.getTime());
-	}
+  /**
+   * @return the id
+   * @see #id
+   */
+  public String getId() {
+    return id;
+  }
 
+//  /**
+//   * @return the expires
+//   * @see #expires
+//   */
+//  public Calendar getExpires() {
+//    return expires;
+//  }
+//
+//  @Override
+//  public String toString() {
+//    return getId() + ", expirese: " + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX").format(expires.getTime());
+//  }
+//
 }
diff --git a/web/src/main/java/lcsb/mapviewer/bean/UserBean.java b/web/src/main/java/lcsb/mapviewer/bean/UserBean.java
index 7d5f68b00d..39c957b917 100644
--- a/web/src/main/java/lcsb/mapviewer/bean/UserBean.java
+++ b/web/src/main/java/lcsb/mapviewer/bean/UserBean.java
@@ -583,11 +583,6 @@ public class UserBean extends AbstractManagedBean {
 		if (authenticationToken == null) {
 			authenticationToken = getUserService().login(Configuration.ANONYMOUS_LOGIN, "");
 		}
-		Calendar now = Calendar.getInstance();
-		now.add(Calendar.MINUTE, -1);
-		if (authenticationToken.getExpires().before(now)) {
-			authenticationToken = getUserService().login(Configuration.ANONYMOUS_LOGIN, "");
-		}
 		return authenticationToken;
 	}
 
diff --git a/web/src/main/java/lcsb/mapviewer/security/MvSecurityServiceImpl.java b/web/src/main/java/lcsb/mapviewer/security/MvSecurityServiceImpl.java
index 9e8f207ce3..b06ff12e10 100644
--- a/web/src/main/java/lcsb/mapviewer/security/MvSecurityServiceImpl.java
+++ b/web/src/main/java/lcsb/mapviewer/security/MvSecurityServiceImpl.java
@@ -1,8 +1,5 @@
 package lcsb.mapviewer.security;
 
-import lcsb.mapviewer.common.Configuration;
-import lcsb.mapviewer.services.interfaces.IUserService;
-
 import org.apache.log4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.core.authority.AuthorityUtils;
@@ -10,8 +7,12 @@ import org.springframework.security.core.userdetails.User;
 import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.core.userdetails.UserDetailsService;
 import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.transaction.annotation.Transactional;
 
+import lcsb.mapviewer.common.Configuration;
+import lcsb.mapviewer.services.interfaces.IUserService;
+
 /**
  * Spring implementation of class accessing user details.
  * 
@@ -20,49 +21,53 @@ import org.springframework.transaction.annotation.Transactional;
  */
 @Transactional(readOnly = false)
 public class MvSecurityServiceImpl implements UserDetailsService {
-	/**
-	 * Default class logger.
-	 */
-	@SuppressWarnings("unused")
-	private static Logger logger = Logger.getLogger(MvSecurityServiceImpl.class);
+  /**
+   * Default class logger.
+   */
+  @SuppressWarnings("unused")
+  private static Logger logger = Logger.getLogger(MvSecurityServiceImpl.class);
+
+  /**
+   * Service used for accessing user data.
+   */
+  @Autowired
+  private IUserService userService;
 
-	/**
-	 * Service used for accessing user data.
-	 */
-	@Autowired
-	private IUserService	userService;
+  @Autowired
+  private PasswordEncoder passwordEncoder;
 
-	@Override
-	public UserDetails loadUserByUsername(String login) {
-		if (login.equals(Configuration.ANONYMOUS_LOGIN)) {
-			throw new UsernameNotFoundException("Guest account is disabled.");
-		}
+  @Override
+  public UserDetails loadUserByUsername(String login) {
+    logger.debug(login);
+    if (login == null || login.trim().isEmpty() || login.equals(Configuration.ANONYMOUS_LOGIN)) {
+      return new User(login, passwordEncoder.encode(""), AuthorityUtils.commaSeparatedStringToAuthorityList(""));
+    }
 
-		lcsb.mapviewer.model.user.User user;
-		user = userService.getUserByLogin(login);
-		if (user == null) {
-			throw new UsernameNotFoundException("Invalid username or password.");
-		}
-		StringBuilder credentials = new StringBuilder();
+    lcsb.mapviewer.model.user.User user = userService.getUserByLogin(login);
+    if (user == null) {
+      throw new UsernameNotFoundException("Invalid username or password.");
+    }
+    StringBuilder credentials = new StringBuilder();
 
-		return new User(user.getLogin(), user.getCryptedPassword(), AuthorityUtils.commaSeparatedStringToAuthorityList(credentials.toString()));
-	}
+    return new User(user.getLogin(), user.getCryptedPassword(),
+        AuthorityUtils.commaSeparatedStringToAuthorityList(credentials.toString()));
+  }
 
-	/**
-	 * @return the userService
-	 * @see #userService
-	 */
-	public IUserService getUserService() {
-		return userService;
-	}
+  /**
+   * @return the userService
+   * @see #userService
+   */
+  public IUserService getUserService() {
+    return userService;
+  }
 
-	/**
-	 * @param userService
-	 *          the userService to set
-	 * @see #userService
-	 */
-	public void setUserService(IUserService userService) {
-		this.userService = userService;
-	}
+  /**
+   * @param userService
+   *          the userService to set
+   * @see #userService
+   */
+  public void setUserService(IUserService userService) {
+    this.userService = userService;
+  }
 
 }
diff --git a/web/src/main/webapp/WEB-INF/web.xml b/web/src/main/webapp/WEB-INF/web.xml
index 8bc3a2044e..9753c6e538 100644
--- a/web/src/main/webapp/WEB-INF/web.xml
+++ b/web/src/main/webapp/WEB-INF/web.xml
@@ -185,6 +185,9 @@
   <session-config>
     <session-timeout>120</session-timeout>
     <tracking-mode>COOKIE</tracking-mode>
+    <cookie-config>
+			<name>MINERVA_AUTH_TOKEN</name><!-- default is jsessionid -->
+		</cookie-config>
   </session-config>
   <filter>
     <filter-name>cssContentTypeFix</filter-name>
diff --git a/web/src/main/webapp/login.xhtml b/web/src/main/webapp/login.xhtml
index d2464a754b..c97f8449ee 100644
--- a/web/src/main/webapp/login.xhtml
+++ b/web/src/main/webapp/login.xhtml
@@ -10,7 +10,6 @@
 <h:head>
     <title>minerva - Authorization form</title>
     <link rel="shortcut icon" href="./resources/images/favicon.png" type="image/png"/>
-    <ui:include src="/WEB-INF/components/admin/statistics.xhtml"/>
 
     <script src="https://maps.google.com/maps/api/js?libraries=drawing&amp;v=3.26" type="text/javascript"/>
 
@@ -20,9 +19,6 @@
     <script src="https://cdn.datatables.net/1.10.13/js/jquery.dataTables.min.js"></script>
 
 
-    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.13/css/jquery.dataTables.min.css"/>
-    <link rel="stylesheet" type="text/css" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"/>
-
 
     <h:outputScript library="js" name="minerva.js"/>
 
@@ -61,7 +57,11 @@
                     e.preventDefault();
                     return login().then(function () {
                         loggedIn = true;
-                        $('#login').click();
+                        if (fromPage!==undefined) {
+                            window.location.href = fromPage;
+                        } else {
+                            window.location.href = minerva.ServerConnector.getServerBaseUrl();
+                        }
                     }, function (error) {
                         if (error.constructor.name === "InvalidCredentialsError") {
                             minerva.GuiConnector.alert("invalid credentials");
@@ -71,6 +71,11 @@
                     });
                 }
             });
+            $('#go_to_map_button').click(function (e) {
+		return minerva.ServerConnector.getProjectId().then(function(projectId){
+		window.location.href='#{request.contextPath}/?id='+projectId;
+	});
+	    });
         }
         function requestAccount() {
         	var email, content; 
@@ -99,14 +104,14 @@
 
             <h:panelGrid columns="2" styleClass="loginDataPanelGrid">
                 <label for="username" class="labelText">LOGIN: </label>
-                <h:inputText id="username" name="username" value="#{userMB.login}" class="minerva-input-text"/>
+                <h:inputText id="username" name="username" class="minerva-input-text"/>
 
                 <label for="password" class="labelText">PASSWORD: </label>
-                <h:inputSecret id="password" name="password" value="#{userMB.password}" type="password"
+                <h:inputSecret id="password" name="password" type="password"
                                class="minerva-input-password"/>
 
                 <label class="labelText"> </label>
-                <h:commandButton type="submit" id="login" action="#{userMB.doLogin}" ajax="false"
+                <h:commandButton type="submit" id="login" ajax="false"
                                  value="LOGIN" styleClass="labelText" update="loginMessages"/>
             </h:panelGrid>
 
@@ -115,7 +120,7 @@
             <br/>
             <br/>
             <a href="javascript:;" id="go_to_map_button"
-               onClick="window.location.href='#{request.contextPath}/?id=#{mapMB.currentMapId}';" class="adminLink"><i
+			 class="adminLink"><i
                     class="fa fa-chevron-right"></i> BACK TO MAP</a>
             <br/>
 
@@ -128,5 +133,4 @@
 
     <ui:include src="/WEB-INF/components/admin/footer.xhtml"/>
 </h:body>
-</html>
-
+</html>
\ No newline at end of file
-- 
GitLab