001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.security.jaas.ext;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.security.jaas.PortalPrincipal;
020    import com.liferay.portal.kernel.util.GetterUtil;
021    import com.liferay.portal.kernel.util.StringPool;
022    import com.liferay.portal.service.UserLocalServiceUtil;
023    
024    import java.io.IOException;
025    
026    import java.security.Principal;
027    
028    import java.util.Map;
029    
030    import javax.security.auth.Subject;
031    import javax.security.auth.callback.Callback;
032    import javax.security.auth.callback.CallbackHandler;
033    import javax.security.auth.callback.NameCallback;
034    import javax.security.auth.callback.PasswordCallback;
035    import javax.security.auth.callback.UnsupportedCallbackException;
036    import javax.security.auth.login.LoginException;
037    import javax.security.auth.spi.LoginModule;
038    
039    /**
040     * @author Brian Wing Shun Chan
041     */
042    public class BasicLoginModule implements LoginModule {
043    
044            public boolean abort() {
045                    return true;
046            }
047    
048            public boolean commit() {
049                    if (getPrincipal() != null) {
050                            getSubject().getPrincipals().add(getPrincipal());
051    
052                            return true;
053                    }
054                    else {
055                            return false;
056                    }
057            }
058    
059            public void initialize(
060                    Subject subject, CallbackHandler callbackHandler,
061                    Map<String, ?> sharedState, Map<String, ?> options) {
062    
063                    _subject = subject;
064                    _callbackHandler = callbackHandler;
065            }
066    
067            public boolean login() throws LoginException {
068                    String[] credentials = null;
069    
070                    try {
071                            credentials = authenticate();
072                    }
073                    catch (Exception e) {
074                            _log.error(e.getMessage());
075    
076                            throw new LoginException();
077                    }
078    
079                    if ((credentials != null) && (credentials.length == 2)) {
080                            setPrincipal(getPortalPrincipal(credentials[0]));
081                            setPassword(credentials[1]);
082    
083                            return true;
084                    }
085                    else {
086                            throw new LoginException();
087                    }
088            }
089    
090            public boolean logout() {
091                    getSubject().getPrincipals().clear();
092    
093                    return true;
094            }
095    
096            protected Subject getSubject() {
097                    return _subject;
098            }
099    
100            protected Principal getPrincipal() {
101                    return _principal;
102            }
103    
104            protected void setPrincipal(Principal principal) {
105                    _principal = principal;
106            }
107    
108            protected Principal getPortalPrincipal(String name) {
109                    return new PortalPrincipal(name);
110            }
111    
112            protected String getPassword() {
113                    return _password;
114            }
115    
116            protected void setPassword(String password) {
117                    _password = password;
118            }
119    
120            protected String[] authenticate()
121                    throws IOException, UnsupportedCallbackException {
122    
123                    NameCallback nameCallback = new NameCallback("name: ");
124                    PasswordCallback passwordCallback =
125                            new PasswordCallback("password: ", false);
126    
127                    _callbackHandler.handle(
128                            new Callback[] {
129                                    nameCallback, passwordCallback
130                            });
131    
132                    String name = nameCallback.getName();
133    
134                    String password = null;
135                    char[] passwordChar = passwordCallback.getPassword();
136    
137                    if (passwordChar != null) {
138                            password = new String(passwordChar);
139                    }
140    
141                    if (name == null) {
142                            return new String[] {StringPool.BLANK, StringPool.BLANK};
143                    }
144    
145                    try {
146                            long userId = GetterUtil.getLong(name);
147    
148                            if (UserLocalServiceUtil.authenticateForJAAS(userId, password)) {
149                                    return new String[] {name, password};
150                            }
151                    }
152                    catch (Exception e) {
153                            _log.error(e, e);
154                    }
155    
156                    return null;
157            }
158    
159            private static Log _log = LogFactoryUtil.getLog(BasicLoginModule.class);
160    
161            private Subject _subject;
162            private CallbackHandler _callbackHandler;
163            private Principal _principal;
164            private String _password;
165    
166    }