001/*
002 * $Id: JAASLoginService.java 4147 2012-02-01 17:13:24Z kschaefe $
003 *
004 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005 * Santa Clara, California 95054, U.S.A. All rights reserved.
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 * 
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015 * Lesser General Public License for more details.
016 * 
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this library; if not, write to the Free Software
019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
020 */
021package org.jdesktop.swingx.auth;
022
023import java.util.logging.Level;
024import java.util.logging.Logger;
025
026import javax.security.auth.Subject;
027import javax.security.auth.callback.Callback;
028import javax.security.auth.callback.CallbackHandler;
029import javax.security.auth.callback.NameCallback;
030import javax.security.auth.callback.PasswordCallback;
031import javax.security.auth.login.AccountExpiredException;
032import javax.security.auth.login.CredentialExpiredException;
033import javax.security.auth.login.FailedLoginException;
034import javax.security.auth.login.LoginContext;
035import javax.security.auth.login.LoginException;
036
037import org.jdesktop.beans.JavaBean;
038
039/**
040 * <b>JAASLoginService</b> implements a <b>LoginService</b>
041 * that uses JAAS for authentication. <b>JAASLoginService</b> uses the 
042 * server name as name of the configuration for JAAS.
043 * 
044 * @author Bino George
045 */
046@JavaBean
047public class JAASLoginService extends LoginService {
048    private static final Logger LOG = Logger.getLogger(JAASLoginService.class
049            .getName());
050
051        protected LoginContext loginContext;
052
053    /**
054     * Constructor for <b>JAASLoginService</b>
055     * @param server server name that is also used for the JAAS config name
056     */
057    public JAASLoginService(String server) {
058        super(server);
059    }
060    
061        /**
062         * Default JavaBeans constructor
063         */
064        public JAASLoginService() {
065            super();
066        }
067        
068    
069    /**
070     * @inheritDoc
071     *      
072     */
073    @Override
074    public boolean authenticate(String name, char[] password, String server) throws Exception {
075                // If user has selected a different server, update the login service
076                if (server != null) {
077                        if (!server.equals(getServer())) {
078                                setServer(server);
079                        }
080                }
081                // Clear the login context before attempting authentication
082                loginContext = null;
083                // Create a login context for the appropriate server and attempt to
084                // authenticate the user.
085        try {
086            loginContext = new LoginContext(getServer(),
087                    new JAASCallbackHandler(name, password));
088            loginContext.login();
089            return true;
090        } catch (AccountExpiredException e) {
091            // TODO add explanation?
092            LOG.log(Level.WARNING, "", e);
093            return false;
094        } catch (CredentialExpiredException e) {
095                        // TODO add explanation?
096                        LOG.log(Level.WARNING, "", e);
097            return false;
098        } catch (FailedLoginException e) {
099                        // TODO add explanation?
100                        LOG.log(Level.WARNING, "", e);
101            return false;
102        } catch (LoginException e) {
103                        // TODO add explanation?
104                        LOG.log(Level.WARNING, "", e);
105            return false;
106        } catch (Throwable e) {
107                        // TODO add explanation?
108                        LOG.log(Level.WARNING, "", e);
109            return false;
110        }
111    }
112
113        /**
114         * Returns the <code>LoginContext</code> used during the authentication
115         * process.
116         */
117        public LoginContext getLoginContext()
118        {
119                return loginContext;
120        }
121
122        /**
123         * Returns the <code>Subject</code> representing the authenticated 
124         * individual, or <code>null</code> if the user has not yet been 
125         * successfully authenticated.
126         */
127        public Subject getSubject()
128        {
129                if (loginContext == null)
130                        return null;
131                return loginContext.getSubject();
132        }
133
134    class JAASCallbackHandler implements CallbackHandler {
135
136        private String name;
137
138        private char[] password;
139
140        public JAASCallbackHandler(String name, char[] passwd) {
141            this.name = name;
142            this.password = passwd;
143        }
144
145        public void handle(Callback[] callbacks) throws java.io.IOException {
146            for (int i = 0; i < callbacks.length; i++) {
147                if (callbacks[i] instanceof NameCallback) {
148                    NameCallback cb = (NameCallback) callbacks[i];
149                    cb.setName(name);
150                } else if (callbacks[i] instanceof PasswordCallback) {
151                    PasswordCallback cb = (PasswordCallback) callbacks[i];
152                    cb.setPassword(password);
153                }
154            }
155        }
156
157    }
158}