Java tutorial
/* * Copyright 1999-2009 University of Chicago * * Licensed 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.nimbustools.messaging.query.security; import org.springframework.core.io.Resource; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataRetrievalFailureException; import org.mortbay.util.QuotedStringTokenizer; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Map; import java.util.HashMap; import java.util.NoSuchElementException; /** * Placeholder UserDetailsService which loads users from a file. * * The file format is one user per line: DN accessID secret * Any token may be quoted and they are separated by whitespace. * Lines starting with # are ignored */ public class FileUserDetailsService implements QueryUserDetailsService { private static final Log logger = LogFactory.getLog(FileUserDetailsService.class.getName()); private static final String DELIMS = " \t\n\r\f"; final private Object lock = new Object(); private File file; private long lastModified; final private Map<String, QueryUser> mapByID; final private Map<String, QueryUser> mapByDN; public FileUserDetailsService(Resource fileResource) throws IOException { if (fileResource == null) { throw new IllegalArgumentException("fileResource may not be null"); } mapByID = new HashMap<String, QueryUser>(); mapByDN = new HashMap<String, QueryUser>(); load(fileResource.getFile()); } public QueryUser loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { if (username == null) { throw new IllegalArgumentException("username may not be null"); } synchronized (this.lock) { this.refreshIfNeeded(); final QueryUser user = mapByID.get(username); if (user != null) { return user; } throw new UsernameNotFoundException("access identifier '" + username + "' unknown"); } } public QueryUser loadUserByDn(String dn) throws UsernameNotFoundException, DataAccessException { if (dn == null) { throw new IllegalArgumentException("dn may not be null"); } synchronized (this.lock) { this.refreshIfNeeded(); final QueryUser user = mapByDN.get(dn); if (user != null) { return user; } throw new UsernameNotFoundException("DN '" + dn + "' unknown"); } } public boolean refreshIfNeeded() throws DataAccessException { synchronized (this.lock) { if (this.file.lastModified() > this.lastModified) { try { load(this.file); } catch (IOException e) { throw new DataRetrievalFailureException("Error refreshing user file", e); } return true; } return false; } } private void load(File file) throws IOException { if (file == null) { throw new IllegalArgumentException("file may not be null"); } InputStream in = null; try { in = new FileInputStream(file); this.file = file; this.lastModified = file.lastModified(); load(in); } finally { if (in != null) { try { in.close(); } catch (Exception e) { logger.warn("Failed to close (??)", e); } } } } private void load(InputStream stream) throws IOException { final BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); mapByID.clear(); mapByDN.clear(); String line; while ((line = reader.readLine()) != null) { // format is DN accessID secret // each token can be quoted and is seperated by whitespace line = line.trim(); if (line.length() == 0 || line.charAt(0) == '#') { continue; } final QuotedStringTokenizer tokenizer = new QuotedStringTokenizer(line, DELIMS); final QueryUser user; try { final String dn = tokenizer.nextToken(); final String accessID = tokenizer.nextToken(); final String secret = tokenizer.nextToken(); user = new QueryUser(accessID, secret, dn); } catch (NoSuchElementException e) { logger.warn("encountered illegal query user entry in file: '" + line + "'. Ignoring."); continue; } mapByID.put(user.getAccessID(), user); mapByDN.put(user.getDn(), user); } } }