Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
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.geronimo.security.realm.providers;
 
 import java.net.URI;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 
A LoginModule that reads a list of credentials and group from files on disk. The files should be formatted using standard Java properties syntax. Expects to be run by a GenericSecurityRealm (doesn't work on its own).

This login module checks security credentials so the lifecycle methods must return true to indicate success or throw LoginException to indicate failure.

Version:
$Rev: 907688 $ $Date: 2010-02-08 23:23:27 +0800 (Mon, 08 Feb 2010) $
 
 public class PropertiesFileLoginModule implements LoginModule {
     public final static String USERS_URI = "usersURI";
     public final static String GROUPS_URI = "groupsURI";
     public final static String DIGEST = "digest";
     public final static String ENCODING = "encoding";
     public final static List<StringsupportedOptions = Collections.unmodifiableList(Arrays.asList());
 
     private static final Logger log = LoggerFactory.getLogger(PropertiesFileLoginModule.class);
     
     final Properties users = new Properties();
     final Map<StringSet<String>> groups = new HashMap<StringSet<String>>();
     private String digest;
     private String encoding;
 
     private boolean loginSucceeded;
     private Subject subject;
     private CallbackHandler handler;
     private String username;
     private String password;
     private final Set<PrincipalallPrincipals = new HashSet<Principal>();
 
     public void initialize(Subject subjectCallbackHandler callbackHandlerMap sharedStateMap options) {
         this. = subject;
         this. = callbackHandler;
         for(Object optionoptions.keySet()) {
             if(!.contains(option) && !..contains(option)
                     && !..contains(option)) {
                 .warn("Ignoring option: "+option+". Not supported.");
             }
         }
         try {
             ServerInfo serverInfo = (ServerInfooptions.get(.);
            final String users = (Stringoptions.get();
            final String groups = (Stringoptions.get();
             = (Stringoptions.get();
             = (Stringoptions.get();
            if ( != null && !.equals("")) {
                // Check if the digest algorithm is available
                try {
                    MessageDigest.getInstance();
                } catch (NoSuchAlgorithmException e) {
                    .error("Initialization failed. Digest algorithm " +  + " is not available."e);
                    throw new IllegalArgumentException(
                            "Unable to configure properties file login module: " + e.getMessage(), e);
                }
                if ( != null && !"hex".equalsIgnoreCase() && !"base64".equalsIgnoreCase()) {
                    .error("Initialization failed. Digest Encoding " +  + " is not supported.");
                    throw new IllegalArgumentException(
                            "Unable to configure properties file login module. Digest Encoding " +  + " not supported.");
                }
            }
            if (users == null || groups == null) {
                throw new IllegalArgumentException("Both " +  + " and " +  + " must be provided!");
            }
            URI usersURI = new URI(users);
            URI groupsURI = new URI(groups);
            loadProperties(serverInfousersURIgroupsURI);
        } catch (Exception e) {
            .error("Initialization failed"e);
            throw new IllegalArgumentException("Unable to configure properties file login module: " + e.getMessage(),
                    e);
        }
    }
    public void loadProperties(ServerInfo serverInfoURI userURIURI groupURIthrows GeronimoSecurityException {
        try {
            URI userFile = serverInfo.resolveServer(userURI);
            URI groupFile = serverInfo.resolveServer(groupURI);
            InputStream stream = userFile.toURL().openStream();
            .clear();
            .load(stream);
            stream.close();
            Properties temp = new Properties();
            stream = groupFile.toURL().openStream();
            temp.load(stream);
            stream.close();
            Enumeration e = temp.keys();
            while (e.hasMoreElements()) {
                String groupName = (Stringe.nextElement();
                String[] userList = ((Stringtemp.get(groupName)).split(",");
                Set<Stringuserset = .get(groupName);
                if (userset == null) {
                    userset = new HashSet<String>();
                    .put(groupNameuserset);
                }
                for (String user : userList) {
                    userset.add(user);
                }
            }
        } catch (Exception e) {
            .error("Properties File Login Module - data load failed"e);
            throw new GeronimoSecurityException(e);
        }
    }


    
This LoginModule is not to be ignored. So, this method should never return false.

Returns:
true if authentication succeeds, or throw a LoginException such as FailedLoginException if authentication fails
    public boolean login() throws LoginException {
         = false;
        Callback[] callbacks = new Callback[2];
        callbacks[0] = new NameCallback("User name");
        callbacks[1] = new PasswordCallback("Password"false);
        try {
            .handle(callbacks);
        } catch (IOException ioe) {
            throw (LoginExceptionnew LoginException().initCause(ioe);
        } catch (UnsupportedCallbackException uce) {
            throw (LoginExceptionnew LoginException().initCause(uce);
        }
        assert callbacks.length == 2;
         = ((NameCallbackcallbacks[0]).getName();
        if ( == null || .equals("")) {
            // Clear out the private state
             = null;
             = null;
            throw new FailedLoginException();
        }
        String realPassword = .getProperty();
        if (realPassword == null || realPassword.equals("")) {
            // Clear out the private state
             = null;
             = null;
            throw new FailedLoginException();
        } else {
            // Decrypt the password if needed, so we can compare it with the supplied one
            realPassword = (String) EncryptionManager.decrypt(realPassword);
        }
        char[] entered = ((PasswordCallbackcallbacks[1]).getPassword();
         = entered == null ? null : new String(entered);
        if (!checkPassword(realPassword)) {
            // Clear out the private state
             = null;
             = null;
            throw new FailedLoginException();
        }
         = true;
        return true;
    }
    /*
     * @exception LoginException if login succeeded but commit failed.
     *
     * @return true if login succeeded and commit succeeded, or false if login failed but commit succeeded.
     */
    public boolean commit() throws LoginException {
        if() {
            if( != null) {
                .add(new GeronimoUserPrincipal());
            }
            for (Map.Entry<StringSet<String>> entry : .entrySet()) {
                String groupName = entry.getKey();
                Set<Stringusers = entry.getValue();
                for (String user : users) {
                    if (.equals(user)) {
                        .add(new GeronimoGroupPrincipal(groupName));
                        break;
                    }
                }
            }
            .getPrincipals().addAll();
        }
        // Clear out the private state
         = null;
         = null;
        return ;
    }
    public boolean abort() throws LoginException {
        if() {
            // Clear out the private state
             = null;
             = null;
            .clear();
        }
        return ;
    }
    public boolean logout() throws LoginException {
        // Clear out the private state
         = false;
         = null;
         = null;
        if(!.isReadOnly()) {
            // Remove principals added by this LoginModule
            .getPrincipals().removeAll();
        }
        .clear();
        return true;
    }

    
This method checks if the provided password is correct. The original password may have been digested.

Parameters:
real Original password in digested form if applicable
provided User provided password in clear text
Returns:
true If the password is correct
    private boolean checkPassword(String realString provided) {
        if (real == null && provided == null) {
            return true;
        }
        if (real == null || provided == null) {
            return false;
        }
        //both non-null
        if ( == null || .equals("")) {
            // No digest algorithm is used
            return real.equals(provided);
        }
        try {
            // Digest the user provided password
            MessageDigest md = MessageDigest.getInstance();
            byte[] data = md.digest(provided.getBytes());
            if ( == null || "hex".equalsIgnoreCase()) {
                // Convert bytes to hex digits
                byte[] hexData = new byte[data.length * 2];
                HexTranslator ht = new HexTranslator();
                ht.encode(data, 0, data.lengthhexData, 0);
                // Compare the digested provided password with the actual one
                return real.equalsIgnoreCase(new String(hexData));
            } else if ("base64".equalsIgnoreCase()) {
                return real.equals(new String(Base64.encode(data)));
            }
        } catch (NoSuchAlgorithmException e) {
            // Should not occur.  Availability of algorithm has been checked at initialization
            .error("Should not occur.  Availability of algorithm has been checked at initialization."e);
        }
        return false;
    }
New to GrepCode? Check out our FAQ X