Java tutorial
/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.security; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import org.apache.commons.io.FileUtils; import org.geoserver.security.impl.GeoServerUser; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.util.StringUtils; /** * Uses the property file <code>$GEOSERVER_DATA_DIR/security/authkey.properties</code> as the source * for unique user identifiers. The file format is: * <ul> * <li>userkey1=username1</li> * <li>userkey2=username2</li> * <li>...</li> * </ul> * * The file will be automatically reloaded when modified * * @author Andrea Aime - GeoSolutions */ public class PropertyAuthenticationKeyMapper extends AbstractAuthenticationKeyMapper { /** * Name of the file used to store the authentication keys */ public static final String AUTHKEYS_FILE = "authkeys.properties"; PropertyFileWatcher fileWatcher; Properties authKeyProps; public boolean supportsReadOnlyUserGroupService() { return true; } @Override synchronized public GeoServerUser getUser(String key) throws IOException { checkProperties(); if (authKeyProps == null) { synchronize(); } if (fileWatcher.isStale()) // reload if necessary authKeyProps = fileWatcher.getProperties(); String userName = authKeyProps.getProperty(key); if (StringUtils.hasLength(userName) == false) { LOGGER.warning("Cannot find user for auth key: " + key); return null; } GeoServerUser theUser = null; try { theUser = (GeoServerUser) getUserGroupService().loadUserByUsername(userName); } catch (UsernameNotFoundException ex) { LOGGER.warning( "Cannot find user: " + userName + " in user/group service: " + getUserGroupServiceName()); return null; } if (theUser.isEnabled() == false) { LOGGER.info("Found user " + theUser.getUsername() + " for key " + key + ", but this user is disabled"); return null; } return theUser; } @Override protected void checkProperties() throws IOException { super.checkProperties(); } @Override synchronized public int synchronize() throws IOException { checkProperties(); File propFile = new File(getSecurityManager().getUserGroupRoot(), getUserGroupServiceName()); propFile = new File(propFile, AUTHKEYS_FILE); File backupFile = new File(getSecurityManager().getUserGroupRoot(), getUserGroupServiceName()); backupFile = new File(backupFile, AUTHKEYS_FILE + ".backup"); // check if the previous synchronize failed if (backupFile.exists()) throw new IOException("The file: " + backupFile.getCanonicalPath() + " has to be removed first"); authKeyProps = new Properties(); Properties oldProps = new Properties(); // check if property file exists and reload if (propFile.exists()) { FileUtils.copyFile(propFile, backupFile); FileInputStream inputFile = new FileInputStream(backupFile); try { oldProps.load(inputFile); } finally { inputFile.close(); } } Map<Object, Object> reverseMap = new HashMap<Object, Object>(); for (Entry<Object, Object> entry : oldProps.entrySet()) { reverseMap.put(entry.getValue(), entry.getKey()); } GeoServerUserGroupService service = getUserGroupService(); int counter = 0; for (GeoServerUser user : service.getUsers()) { if (reverseMap.containsKey(user.getUsername())) { authKeyProps.put(reverseMap.get(user.getUsername()), user.getUsername()); } else { authKeyProps.put(createAuthKey(), user.getUsername()); counter++; } } FileOutputStream outputFile = new FileOutputStream(propFile, false); try { authKeyProps.store(outputFile, "Format is authkey=username"); } finally { outputFile.close(); } if (backupFile.exists()) backupFile.delete(); fileWatcher = new PropertyFileWatcher(propFile); return counter; } }