Package org.apache.geronimo.security.realm.providers

Source Code of org.apache.geronimo.security.realm.providers.GeronimoPropertiesFileMappedPasswordCredentialLoginModule

/*
* 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.io.InputStream;
import java.net.URI;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.security.auth.DestroyFailedException;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.geronimo.common.GeronimoSecurityException;
import org.apache.geronimo.security.jaas.JaasLoginModuleUse;
import org.apache.geronimo.security.jaas.NamedUsernamePasswordCredential;
import org.apache.geronimo.security.jaas.WrappingLoginModule;
import org.apache.geronimo.system.serverinfo.ServerInfo;

/**
* GeronimoPropertiesFileMappedPasswordCredentialLoginModule adds NamedUsernamePasswordCredentials to the Subject.
* The NamedUsernamePasswordCredential are specified in a properties file specified in the options. Each line of the
* properties file is of the form:
*
* username=credentials
*
* where credentials is a comma-separated list of credentials and a credential is of the form
* name:username=password
*
* Thus a typical line would be:
*
* whee=foo:bar=baz,foo2:bar2=baz2
*
* This login module does not check credentials so it should never be able to cause a login to succeed.
* Therefore the lifecycle methods must return false to indicate success or throw a LoginException to indicate failure.
*
* @version $Rev: 653740 $ $Date: 2008-05-06 03:44:18 -0700 (Tue, 06 May 2008) $
*/
public class GeronimoPropertiesFileMappedPasswordCredentialLoginModule implements LoginModule {

    private static final Logger log = LoggerFactory.getLogger(GeronimoPropertiesFileMappedPasswordCredentialLoginModule.class);
    public final static String CREDENTIALS_URI = "credentialsURI";
    public final static List<String> supportedOptions = Collections.unmodifiableList(Arrays.asList(CREDENTIALS_URI));
    private final static Pattern pattern = Pattern.compile("([^:,=]*):([^:,=]*)=([^:,=]*)");

    private final Set<NamedUsernamePasswordCredential> passwordCredentials = new HashSet<NamedUsernamePasswordCredential>();
    private final Properties credentials = new Properties();
    private String userName;

    private Subject subject;
    private CallbackHandler callbackHandler;

    public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
        this.subject = subject;
        this.callbackHandler = callbackHandler;
        for(Object option: options.keySet()) {
            if(!supportedOptions.contains(option) && !JaasLoginModuleUse.supportedOptions.contains(option)
                    && !WrappingLoginModule.supportedOptions.contains(option)) {
                log.warn("Ignoring option: "+option+". Not supported.");
            }
        }
        try {
            ServerInfo serverInfo = (ServerInfo) options.get(JaasLoginModuleUse.SERVERINFO_LM_OPTION);
            final String credentials = (String) options.get(CREDENTIALS_URI);
            if (credentials == null) {
                throw new IllegalArgumentException(CREDENTIALS_URI + " must be provided!");
            }
            URI usersURI = new URI(credentials);
            loadProperties(serverInfo, usersURI);
        } catch (Exception e) {
            log.error("Initialization failed", e);
            throw new IllegalArgumentException("Unable to configure properties file login module: " + e.getMessage(), e);
        }
    }

    private void loadProperties(ServerInfo serverInfo, URI credentialsURI) throws GeronimoSecurityException {
        try {
            URI userFile = serverInfo.resolveServer(credentialsURI);
            InputStream stream = userFile.toURL().openStream();
            credentials.load(stream);
            stream.close();
        } catch (Exception e) {
            log.error("Properties File Login Module - data load failed", e);
            throw new GeronimoSecurityException(e);
        }
    }

    public boolean login() throws LoginException {
        Callback[] callbacks = new Callback[1];
        callbacks[0] = new NameCallback("User name");
        try {
            callbackHandler.handle(callbacks);
        } catch (java.io.IOException e) {
            throw (LoginException) new LoginException("Unlikely IOException").initCause(e);
        } catch (UnsupportedCallbackException e) {
            throw (LoginException) new LoginException("Unlikely UnsupportedCallbackException").initCause(e);
        }
        userName = ((NameCallback) callbacks[0]).getName();
        return false;
    }

    void parseCredentials(String unparsedCredentials, Set<NamedUsernamePasswordCredential> passwordCredentials) {
        Matcher matcher = pattern.matcher(unparsedCredentials);
        while (matcher.find()) {
            String credentialName = matcher.group(1);
            String credentialUser = matcher.group(2);
            String credentialPassword = matcher.group(3);
            NamedUsernamePasswordCredential credential = new NamedUsernamePasswordCredential(credentialUser, credentialPassword.toCharArray(), credentialName);
            passwordCredentials.add(credential);
        }
    }

    public boolean commit() throws LoginException {
        String unparsedCredentials = credentials.getProperty(userName);
        if (unparsedCredentials != null) {
            parseCredentials(unparsedCredentials, passwordCredentials);
        }
        subject.getPrivateCredentials().addAll(passwordCredentials);
       
        userName = null;
        return false;
    }

    public boolean abort() throws LoginException {
        userName = null;
        for(NamedUsernamePasswordCredential credential : passwordCredentials) {
            try{
                credential.destroy();
            } catch (DestroyFailedException e) {
                // do nothing
            }
        }
        passwordCredentials.clear();
        return false;
    }

    public boolean logout() throws LoginException {
        if(!subject.isReadOnly()) {
            subject.getPrivateCredentials().removeAll(passwordCredentials);
        }
        userName = null;
        for(NamedUsernamePasswordCredential credential : passwordCredentials) {
            try{
                credential.destroy();
            } catch (DestroyFailedException e) {
                // do nothing
            }
        }
        passwordCredentials.clear();
        return false;
    }
}
TOP

Related Classes of org.apache.geronimo.security.realm.providers.GeronimoPropertiesFileMappedPasswordCredentialLoginModule

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.