%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.jetspeed.security.impl.DefaultLoginModule |
|
|
1 | /* |
|
2 | * Licensed to the Apache Software Foundation (ASF) under one or more |
|
3 | * contributor license agreements. See the NOTICE file distributed with |
|
4 | * this work for additional information regarding copyright ownership. |
|
5 | * The ASF licenses this file to You under the Apache License, Version 2.0 |
|
6 | * (the "License"); you may not use this file except in compliance with |
|
7 | * the License. You may obtain a copy of the License at |
|
8 | * |
|
9 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
10 | * |
|
11 | * Unless required by applicable law or agreed to in writing, software |
|
12 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
14 | * See the License for the specific language governing permissions and |
|
15 | * limitations under the License. |
|
16 | */ |
|
17 | package org.apache.jetspeed.security.impl; |
|
18 | ||
19 | import java.security.Principal; |
|
20 | import java.util.List; |
|
21 | import java.util.Map; |
|
22 | ||
23 | import javax.security.auth.Subject; |
|
24 | import javax.security.auth.callback.Callback; |
|
25 | import javax.security.auth.callback.CallbackHandler; |
|
26 | import javax.security.auth.callback.NameCallback; |
|
27 | import javax.security.auth.callback.PasswordCallback; |
|
28 | import javax.security.auth.login.FailedLoginException; |
|
29 | import javax.security.auth.login.LoginException; |
|
30 | import javax.security.auth.spi.LoginModule; |
|
31 | ||
32 | import org.apache.jetspeed.security.LoginModuleProxy; |
|
33 | import org.apache.jetspeed.security.RolePrincipal; |
|
34 | import org.apache.jetspeed.security.SecurityHelper; |
|
35 | import org.apache.jetspeed.security.User; |
|
36 | import org.apache.jetspeed.security.UserManager; |
|
37 | import org.apache.jetspeed.security.UserPrincipal; |
|
38 | ||
39 | /** |
|
40 | * <p>LoginModule implementation that authenticates a user |
|
41 | * against a relational database. OJB based implementation.</p> |
|
42 | * <p>When a user is successfully authenticated, the user principal |
|
43 | * are added to the current subject.</p> |
|
44 | * <p>The LoginModule also recognizes the debug option.</p> |
|
45 | * <p>Configuration files should provide:</p> |
|
46 | * <pre><code> |
|
47 | * Jetspeed { |
|
48 | * org.apache.jetspeed.security.impl.DefaultLoginModule required debug=true; |
|
49 | * }; |
|
50 | * </code></pre> |
|
51 | * @author <a href="mailto:dlestrat@apache.org">David Le Strat</a> |
|
52 | */ |
|
53 | public class DefaultLoginModule implements LoginModule |
|
54 | { |
|
55 | ||
56 | /** <p>LoginModule debug mode is turned off by default.</p> */ |
|
57 | protected boolean debug; |
|
58 | ||
59 | /** <p>The authentication status.</p> */ |
|
60 | protected boolean success; |
|
61 | ||
62 | /** <p>The commit status.</p> */ |
|
63 | protected boolean commitSuccess; |
|
64 | ||
65 | /** <p>The Subject to be authenticated.</p> */ |
|
66 | protected Subject subject; |
|
67 | ||
68 | /** <p>A CallbackHandler for communicating with the end user (prompting for usernames and passwords, for example).</p> */ |
|
69 | protected CallbackHandler callbackHandler; |
|
70 | ||
71 | /** <p>State shared with other configured LoginModules.</p> */ |
|
72 | protected Map sharedState; |
|
73 | ||
74 | /** <p>Options specified in the login Configuration for this particular LoginModule.</p> */ |
|
75 | protected Map options; |
|
76 | ||
77 | /** <p>InternalUserPrincipal manager service.</p> */ |
|
78 | protected UserManager ums; |
|
79 | ||
80 | /** The portal user role. */ |
|
81 | protected String portalUserRole; |
|
82 | ||
83 | /** <p>The user name.</p> */ |
|
84 | protected String username; |
|
85 | ||
86 | ||
87 | /** |
|
88 | * <p>The default login module constructor.</p> |
|
89 | */ |
|
90 | public DefaultLoginModule() |
|
91 | 0 | { |
92 | 0 | LoginModuleProxy loginModuleProxy = LoginModuleProxyImpl.loginModuleProxy; |
93 | 0 | if (loginModuleProxy != null) |
94 | { |
|
95 | 0 | this.ums = loginModuleProxy.getUserManager(); |
96 | 0 | this.portalUserRole = loginModuleProxy.getPortalUserRole(); |
97 | } |
|
98 | 0 | debug = false; |
99 | 0 | success = false; |
100 | 0 | commitSuccess = false; |
101 | 0 | username = null; |
102 | 0 | } |
103 | ||
104 | ||
105 | /** |
|
106 | * Create a new login module that uses the given user manager. |
|
107 | * @param userManager the user manager to use |
|
108 | * @param portalUserRole the portal user role to use |
|
109 | */ |
|
110 | protected DefaultLoginModule (UserManager userManager, String portalUserRole) |
|
111 | 0 | { |
112 | 0 | this.ums = userManager; |
113 | 0 | this.portalUserRole = portalUserRole; |
114 | 0 | debug = false; |
115 | 0 | success = false; |
116 | 0 | commitSuccess = false; |
117 | 0 | username = null; |
118 | 0 | } |
119 | protected DefaultLoginModule (UserManager userManager) |
|
120 | { |
|
121 | 0 | this(userManager, LoginModuleProxy.DEFAULT_PORTAL_USER_ROLE_NAME); |
122 | 0 | } |
123 | ||
124 | /** |
|
125 | * @see javax.security.auth.spi.LoginModule#abort() |
|
126 | */ |
|
127 | public boolean abort() throws LoginException |
|
128 | { |
|
129 | // Clean out state |
|
130 | 0 | success = false; |
131 | 0 | commitSuccess = false; |
132 | 0 | username = null; |
133 | 0 | if (callbackHandler instanceof PassiveCallbackHandler) |
134 | { |
|
135 | 0 | ((PassiveCallbackHandler) callbackHandler).clearPassword(); |
136 | } |
|
137 | 0 | logout(); |
138 | 0 | return true; |
139 | } |
|
140 | ||
141 | protected void refreshProxy() |
|
142 | { |
|
143 | 0 | if (this.ums == null) |
144 | { |
|
145 | 0 | LoginModuleProxy loginModuleProxy = LoginModuleProxyImpl.loginModuleProxy; |
146 | 0 | if (loginModuleProxy != null) |
147 | { |
|
148 | 0 | this.ums = loginModuleProxy.getUserManager(); |
149 | } |
|
150 | } |
|
151 | 0 | } |
152 | ||
153 | /** |
|
154 | * @see javax.security.auth.spi.LoginModule#commit() |
|
155 | */ |
|
156 | public boolean commit() throws LoginException |
|
157 | { |
|
158 | 0 | if (success) |
159 | { |
|
160 | 0 | if (subject.isReadOnly()) |
161 | { |
|
162 | 0 | throw new LoginException("Subject is Readonly"); |
163 | } |
|
164 | try |
|
165 | { |
|
166 | // TODO We should get the user profile here and had it in cache so that we do not have to retrieve it again. |
|
167 | // TODO Ideally the User should be available from the session. Need discussion around this. |
|
168 | 0 | refreshProxy(); |
169 | 0 | commitPrincipals(subject, ums.getUser(username)); |
170 | ||
171 | 0 | username = null; |
172 | 0 | commitSuccess = true; |
173 | ||
174 | 0 | if (callbackHandler instanceof PassiveCallbackHandler) |
175 | { |
|
176 | 0 | ((PassiveCallbackHandler) callbackHandler).clearPassword(); |
177 | } |
|
178 | ||
179 | } |
|
180 | 0 | catch (Exception ex) |
181 | { |
|
182 | 0 | ex.printStackTrace(System.out); |
183 | 0 | throw new LoginException(ex.getMessage()); |
184 | 0 | } |
185 | } |
|
186 | ||
187 | 0 | return commitSuccess; |
188 | } |
|
189 | ||
190 | /** |
|
191 | * @see javax.security.auth.spi.LoginModule#login() |
|
192 | */ |
|
193 | public boolean login() throws LoginException |
|
194 | { |
|
195 | 0 | if (callbackHandler == null) |
196 | { |
|
197 | 0 | throw new LoginException("Error: no CallbackHandler available " + "to garner authentication information from the user"); |
198 | } |
|
199 | try |
|
200 | { |
|
201 | // Setup default callback handlers. |
|
202 | 0 | Callback[] callbacks = new Callback[] { class="keyword">new NameCallback("Username: "), new PasswordCallback("Password: ", false)}; |
203 | ||
204 | 0 | callbackHandler.handle(callbacks); |
205 | ||
206 | 0 | username = ((NameCallback) callbacks[0]).getName(); |
207 | 0 | String password = new String(((PasswordCallback) callbacks[1]).getPassword()); |
208 | ||
209 | 0 | ((PasswordCallback) callbacks[1]).clearPassword(); |
210 | ||
211 | 0 | refreshProxy(); |
212 | 0 | success = ums.authenticate(this.username, password); |
213 | ||
214 | 0 | callbacks[0] = null; |
215 | 0 | callbacks[1] = null; |
216 | 0 | if (!success) |
217 | { |
|
218 | 0 | throw new FailedLoginException("Authentication failed: Password does not match"); |
219 | } |
|
220 | ||
221 | 0 | return (true); |
222 | } |
|
223 | 0 | catch (LoginException ex) |
224 | { |
|
225 | 0 | throw ex; |
226 | } |
|
227 | 0 | catch (Exception ex) |
228 | { |
|
229 | 0 | success = false; |
230 | 0 | throw new LoginException(ex.getMessage()); |
231 | } |
|
232 | } |
|
233 | ||
234 | /** |
|
235 | * @see javax.security.auth.spi.LoginModule#logout() |
|
236 | */ |
|
237 | public boolean logout() throws LoginException |
|
238 | { |
|
239 | // TODO Can we set subject to null? |
|
240 | 0 | subject.getPrincipals().clear(); |
241 | 0 | subject.getPrivateCredentials().clear(); |
242 | 0 | subject.getPublicCredentials().clear(); |
243 | 0 | success = false; |
244 | 0 | commitSuccess = false; |
245 | ||
246 | 0 | return true; |
247 | } |
|
248 | ||
249 | /** |
|
250 | * @see javax.security.auth.spi.LoginModule#initialize(javax.security.auth.Subject, javax.security.auth.callback.CallbackHandler, java.util.Map, java.util.Map) |
|
251 | */ |
|
252 | public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) |
|
253 | { |
|
254 | 0 | this.subject = subject; |
255 | 0 | this.callbackHandler = callbackHandler; |
256 | 0 | this.sharedState = sharedState; |
257 | 0 | this.options = options; |
258 | ||
259 | // Initialize debug mode if configure option. |
|
260 | 0 | if (options.containsKey("debug")) |
261 | { |
|
262 | 0 | debug = "true".equalsIgnoreCase((String) options.get("debug")); |
263 | } |
|
264 | 0 | } |
265 | ||
266 | ||
267 | protected Principal getUserPrincipal(User user) |
|
268 | { |
|
269 | 0 | return SecurityHelper.getPrincipal(user.getSubject(),UserPrincipal.class); |
270 | } |
|
271 | ||
272 | protected List getUserRoles(User user) |
|
273 | { |
|
274 | 0 | return SecurityHelper.getPrincipals(user.getSubject(),RolePrincipal.class); |
275 | } |
|
276 | ||
277 | /** |
|
278 | * Default setup of the logged on Subject Principals for Tomcat |
|
279 | * @param subject |
|
280 | * @param user |
|
281 | */ |
|
282 | protected void commitPrincipals(Subject subject, User user) |
|
283 | { |
|
284 | // add user specific portal user name and roles |
|
285 | 0 | subject.getPrincipals().add(getUserPrincipal(user)); |
286 | 0 | subject.getPrincipals().addAll(getUserRoles(user)); |
287 | ||
288 | // add portal user role: used in web.xml authorization to |
|
289 | // detect authenticated portal users |
|
290 | 0 | subject.getPrincipals().add(new RolePrincipalImpl(portalUserRole)); |
291 | 0 | } |
292 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |