All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.efaps.jaas.xml.XMLUserLoginModule Maven / Gradle / Ivy

Go to download

eFaps is a framework used to map objects with or without attached files to a relational database and optional file systems (only for attaches files). Configurable access control can be provided down to object and attribute level depending on implementation and use case. Depending on requirements, events (like triggers) allow to implement business logic and to separate business logic from user interface. The framework includes integrations (e.g. webdav, full text search) and a web application as 'simple' configurable user interface. Some best practises, example web application modules (e.g. team work module) support administrators and implementers using this framework.

There is a newer version: 3.2.0
Show newest version
/*
 * Copyright 2003 - 2012 The eFaps Team
 *
 * 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.
 *
 * Revision:        $Rev: 7483 $
 * Last Changed:    $Date: 2012-05-11 11:57:38 -0500 (Fri, 11 May 2012) $
 * Last Changed By: $Author: [email protected] $
 */

package org.efaps.jaas.xml;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;

import org.apache.commons.digester.Digester;
import org.efaps.jaas.ActionCallback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;

/***
 *
 * @author The eFaps Team
 * @version $Id: XMLUserLoginModule.java 7483 2012-05-11 16:57:38Z [email protected] $
 */
public class XMLUserLoginModule
    implements LoginModule
{
    /**
     * Logging instance used to give logging information of this class.
     */
    private static final Logger LOG = LoggerFactory.getLogger(XMLUserLoginModule.class);

    /**
     * Stores the mode in which mode the login module is called.
     */
    private ActionCallback.Mode mode = ActionCallback.Mode.UNDEFINED;

    /**
     * The subject is stored from the initialize method to store all single
     * entities for the person logging in.
     */
    private Subject subject = null;

    /**
     *
     */
    private CallbackHandler callbackHandler = null;

    /**
     * The logged in person principal is stored in this variable. The variable
     * is set if the user logged in and reset to null if the user is logged
     * out.
     */
    private XMLPersonPrincipal person = null;

    /**
     *
     */
    private final Map allPersons = new HashMap();

    /**
     * Initialize this LoginModule.
     *
     * 

This method is called by the LoginContext * after this LoginModule has been instantiated. * The purpose of this method is to initialize this * LoginModule with the relevant information. * If this LoginModule does not understand * any of the data stored in sharedState or * options parameters, they can be ignored. * *

* * @param _subject the Subject to be authenticated.

* @param _callbackHandler a CallbackHandler for communicating * with the end user (prompting for usernames and * passwords, for example).

* @param _sharedState state shared with other configured LoginModules.

* @param _options options specified in the login * Configuration for this particular * LoginModule. */ @Override public final void initialize(final Subject _subject, final CallbackHandler _callbackHandler, final Map < String, ? > _sharedState, final Map < String, ? > _options) { XMLUserLoginModule.LOG.debug("Init"); this.subject = _subject; this.callbackHandler = _callbackHandler; readPersons((String) _options.get("xmlFileName")); } /** * Method to authenticate a Subject (phase 1). * *

The implementation of this method authenticates * a Subject. For example, it may prompt for * Subject information such * as a username and password and then attempt to verify the password. * This method saves the result of the authentication attempt * as private state within the LoginModule. * *

* * @exception LoginException if the authentication fails * * @return true if the authentication succeeded, or false if this * LoginModule should be ignored. */ public final boolean login() throws LoginException { boolean ret = false; final Callback[] callbacks = new Callback[3]; callbacks[0] = new ActionCallback(); callbacks[1] = new NameCallback("Username: "); callbacks[2] = new PasswordCallback("Password: ", false); // Interact with the user to retrieve the username and password String userName = null; String password = null; try { this.callbackHandler.handle(callbacks); this.mode = ((ActionCallback) callbacks[0]).getMode(); userName = ((NameCallback) callbacks[1]).getName(); if (((PasswordCallback) callbacks[2]).getPassword() != null) { password = new String(((PasswordCallback) callbacks[2]).getPassword()); } } catch (final IOException e) { throw new LoginException(e.toString()); } catch (final UnsupportedCallbackException e) { throw new LoginException(e.toString()); } if (this.mode == ActionCallback.Mode.ALL_PERSONS) { ret = true; } else if (this.mode == ActionCallback.Mode.PERSON_INFORMATION) { this.person = this.allPersons.get(userName); if (this.person != null) { if (XMLUserLoginModule.LOG.isDebugEnabled()) { XMLUserLoginModule.LOG.debug("found '" + this.person + "'"); } ret = true; } } else { this.person = this.allPersons.get(userName); if (this.person != null) { if ((password == null) || ((password != null) && !password.equals(this.person.getPassword()))) { XMLUserLoginModule.LOG.error("person '" + this.person + "' tried to log in with wrong password"); this.person = null; throw new FailedLoginException("Username or password is incorrect"); } if (XMLUserLoginModule.LOG.isDebugEnabled()) { XMLUserLoginModule.LOG.debug("log in of '" + this.person + "'"); } this.mode = ActionCallback.Mode.LOGIN; ret = true; } } return ret; } /** * Method to commit the authentication process (phase 2). * *

This method is called if the LoginContext's * overall authentication succeeded * (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules * succeeded). * *

If this LoginModule's own authentication attempt * succeeded (checked by retrieving the private state saved by the * login method), then this method associates relevant * Principals and Credentials with the Subject located in the * LoginModule. If this LoginModule's own * authentication attempted failed, then this method removes/destroys * any state that was originally saved. * *

* * @exception LoginException if the commit fails * * @return true if this method succeeded, or false if this * LoginModule should be ignored. */ public final boolean commit() throws LoginException { boolean ret = false; if (this.mode == ActionCallback.Mode.ALL_PERSONS) { for (final XMLPersonPrincipal personTmp : this.allPersons.values()) { if (!this.subject.getPrincipals().contains(personTmp)) { if (XMLUserLoginModule.LOG.isDebugEnabled()) { XMLUserLoginModule.LOG.debug("commit person '" + personTmp + "'"); } this.subject.getPrincipals().add(personTmp); } } ret = true; } else if (this.person != null) { if (XMLUserLoginModule.LOG.isDebugEnabled()) { XMLUserLoginModule.LOG.debug("commit of '" + this.person + "'"); } if (!this.subject.getPrincipals().contains(this.person)) { this.subject.getPrincipals().add(this.person); for (final XMLRolePrincipal principal : this.person.getRoles()) { this.subject.getPrincipals().add(principal); } for (final XMLGroupPrincipal principal : this.person.getGroups()) { this.subject.getPrincipals().add(principal); } } ret = true; } return ret; } /** * Method to abort the authentication process (phase 2). * *

This method is called if the LoginContext's * overall authentication failed. * (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules * did not succeed). * *

If this LoginModule's own authentication attempt * succeeded (checked by retrieving the private state saved by the * login method), then this method cleans up any state * that was originally saved. * *

* * @exception LoginException if the abort fails * * @return true if this method succeeded, or false if this * LoginModule should be ignored. */ public final boolean abort() throws LoginException { boolean ret = false; if (this.person != null) { if (XMLUserLoginModule.LOG.isDebugEnabled()) { XMLUserLoginModule.LOG.debug("abort of " + this.person); } this.subject.getPrincipals().remove(this.person); for (final XMLRolePrincipal principal : this.person.getRoles()) { this.subject.getPrincipals().remove(principal); } for (final XMLGroupPrincipal principal : this.person.getGroups()) { this.subject.getPrincipals().remove(principal); } this.person = null; ret = true; } return ret; } /** * The method logs out a Subject. All principals (the person and the related * roles and groups) are removed from the subject in {@link #subject}. * * @return true if this login module is used to authentificate the * current user, otherwise false */ public final boolean logout() { boolean ret = false; if (this.person != null) { if (XMLUserLoginModule.LOG.isDebugEnabled()) { XMLUserLoginModule.LOG.debug("logout of " + this.person); } this.subject.getPrincipals().remove(this.person); for (final XMLRolePrincipal principal : this.person.getRoles()) { this.subject.getPrincipals().remove(principal); } for (final XMLGroupPrincipal principal : this.person.getGroups()) { this.subject.getPrincipals().remove(principal); } this.person = null; ret = true; } return ret; } /** * The name of the XML is store in this instance variable. The XML file * holds all allowed persons and their related roles and groups. * * @param _fileName name of the XML file with the user data */ @SuppressWarnings("unchecked") private void readPersons(final String _fileName) { try { final File file = new File(_fileName); final Digester digester = new Digester(); digester.setValidating(false); digester.addObjectCreate("persons", ArrayList.class); digester.addObjectCreate("persons/person", XMLPersonPrincipal.class); digester.addSetNext("persons/person", "add"); digester.addCallMethod("persons/person/name", "setName", 1); digester.addCallParam("persons/person/name", 0); digester.addCallMethod("persons/person/password", "setPassword", 1); digester.addCallParam("persons/person/password", 0); digester.addCallMethod("persons/person/firstName", "setFirstName", 1); digester.addCallParam("persons/person/firstName", 0); digester.addCallMethod("persons/person/lastName", "setLastName", 1); digester.addCallParam("persons/person/lastName", 0); digester.addCallMethod("persons/person/email", "setEmail", 1); digester.addCallParam("persons/person/email", 0); digester.addCallMethod("persons/person/organisation", "setOrganisation", 1); digester.addCallParam("persons/person/organisation", 0); digester.addCallMethod("persons/person/url", "setUrl", 1); digester.addCallParam("persons/person/url", 0); digester.addCallMethod("persons/person/phone", "setPhone", 1); digester.addCallParam("persons/person/phone", 0); digester.addCallMethod("persons/person/mobile", "setMobile", 1); digester.addCallParam("persons/person/mobile", 0); digester.addCallMethod("persons/person/fax", "setFax", 1); digester.addCallParam("persons/person/fax", 0); digester.addCallMethod("persons/person/role", "addRole", 1); digester.addCallParam("persons/person/role", 0); digester.addCallMethod("persons/person/group", "addGroup", 1); digester.addCallParam("persons/person/group", 0); final List personList = (List) digester.parse(file); for (final XMLPersonPrincipal personTmp : personList) { this.allPersons.put(personTmp.getName(), personTmp); } } catch (final IOException e) { XMLUserLoginModule.LOG.error("could not open file '" + _fileName + "'", e); } catch (final SAXException e) { XMLUserLoginModule.LOG.error("could not read file '" + _fileName + "'", e); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy