KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > web > app > servlet > AuthenticationHelper


1 /*
2  * Copyright (C) 2005 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.web.app.servlet;
18
19 import java.io.IOException JavaDoc;
20
21 import javax.portlet.PortletSession;
22 import javax.servlet.ServletContext JavaDoc;
23 import javax.servlet.http.Cookie JavaDoc;
24 import javax.servlet.http.HttpServletRequest JavaDoc;
25 import javax.servlet.http.HttpServletResponse JavaDoc;
26 import javax.servlet.http.HttpSession JavaDoc;
27 import javax.transaction.UserTransaction JavaDoc;
28
29 import org.alfresco.error.AlfrescoRuntimeException;
30 import org.alfresco.i18n.I18NUtil;
31 import org.alfresco.model.ContentModel;
32 import org.alfresco.repo.security.authentication.AuthenticationException;
33 import org.alfresco.repo.security.permissions.AccessDeniedException;
34 import org.alfresco.service.ServiceRegistry;
35 import org.alfresco.service.cmr.repository.InvalidNodeRefException;
36 import org.alfresco.service.cmr.repository.NodeRef;
37 import org.alfresco.service.cmr.repository.NodeService;
38 import org.alfresco.service.cmr.security.AuthenticationService;
39 import org.alfresco.service.cmr.security.PermissionService;
40 import org.alfresco.service.cmr.security.PersonService;
41 import org.alfresco.web.app.Application;
42 import org.alfresco.web.app.portlet.AlfrescoFacesPortlet;
43 import org.alfresco.web.bean.LoginBean;
44 import org.alfresco.web.bean.repository.User;
45 import org.apache.commons.logging.Log;
46 import org.apache.commons.logging.LogFactory;
47 import org.springframework.web.context.WebApplicationContext;
48 import org.springframework.web.context.support.WebApplicationContextUtils;
49
50 /**
51  * Helper to authenticate the current user using available Ticket information.
52  * <p>
53  * User information is looked up in the Session. If found the ticket is retrieved and validated.
54  * If the ticket is invalid then a redirect is performed to the login page.
55  * <p>
56  * If no User info is found then a search will be made for a previous username stored in a Cookie
57  * value. If the username if found then a redirect to the Login page will occur. If no username
58  * is found then Guest access login will be attempted by the system. Guest access can be forced
59  * with the appropriate method call.
60  *
61  * @author Kevin Roast
62  */

63 public final class AuthenticationHelper
64 {
65    /** session variables */
66    public static final String JavaDoc AUTHENTICATION_USER = "_alfAuthTicket";
67    public static final String JavaDoc SESSION_USERNAME = "_alfLastUser";
68    public static final String JavaDoc SESSION_INVALIDATED = "_alfSessionInvalid";
69    
70    /** JSF bean IDs */
71    public static final String JavaDoc LOGIN_BEAN = "LoginBean";
72    
73    /** public service bean IDs **/
74    private static final String JavaDoc AUTHENTICATION_SERVICE = "AuthenticationService";
75    private static final String JavaDoc UNPROTECTED_AUTH_SERVICE = "authenticationServiceImpl";
76    private static final String JavaDoc PERSON_SERVICE = "personService";
77    
78    /** cookie names */
79    private static final String JavaDoc COOKIE_ALFUSER = "alfUser";
80    
81    private static Log logger = LogFactory.getLog(AuthenticationHelper.class);
82    
83    
84    /**
85     * Helper to authenticate the current user using session based Ticket information.
86     * <p>
87     * User information is looked up in the Session. If found the ticket is retrieved and validated.
88     * If no User info is found or the ticket is invalid then a redirect is performed to the login page.
89     *
90     * @param guest True to force a Guest login attempt
91     *
92     * @return AuthenticationStatus result.
93     */

94    public static AuthenticationStatus authenticate(
95          ServletContext JavaDoc context, HttpServletRequest JavaDoc httpRequest, HttpServletResponse JavaDoc httpResponse, boolean guest)
96          throws IOException JavaDoc
97    {
98       HttpSession JavaDoc session = httpRequest.getSession();
99       
100       // examine the appropriate session for our User object
101
User user;
102       LoginBean loginBean = null;
103       if (Application.inPortalServer() == false)
104       {
105          user = (User)session.getAttribute(AUTHENTICATION_USER);
106          loginBean = (LoginBean)session.getAttribute(LOGIN_BEAN);
107       }
108       else
109       {
110          user = (User)session.getAttribute(AlfrescoFacesPortlet.MANAGED_BEAN_PREFIX + AUTHENTICATION_USER);
111       }
112       
113       // setup the authentication context
114
WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(context);
115       AuthenticationService auth = (AuthenticationService)wc.getBean(AUTHENTICATION_SERVICE);
116       
117       if (user == null || guest)
118       {
119          // Check for the session invalidated flag - this is set by the Logout action in the LoginBean
120
// it signals a forced Logout and means we should not immediately attempt a relogin as Guest.
121
// The attribute is removed from the session by the login.jsp page after the Cookie containing
122
// the last stored username string is cleared.
123
if (session.getAttribute(AuthenticationHelper.SESSION_INVALIDATED) == null)
124          {
125             Cookie JavaDoc authCookie = getAuthCookie(httpRequest);
126             if (authCookie == null || guest)
127             {
128                // no previous authentication or forced Guest - attempt Guest access
129
UserTransaction JavaDoc tx = null;
130                try
131                {
132                   auth.authenticateAsGuest();
133                   
134                   // if we get here then Guest access was allowed and successful
135
ServiceRegistry services = BaseServlet.getServiceRegistry(context);
136                   tx = services.getTransactionService().getUserTransaction();
137                   tx.begin();
138                   
139                   NodeService nodeService = services.getNodeService();
140                   PersonService personService = (PersonService)wc.getBean(PERSON_SERVICE);
141                   NodeRef guestRef = personService.getPerson(PermissionService.GUEST_AUTHORITY);
142                   user = new User(PermissionService.GUEST_AUTHORITY, auth.getCurrentTicket(), guestRef);
143                   NodeRef guestHomeRef = (NodeRef)nodeService.getProperty(guestRef, ContentModel.PROP_HOMEFOLDER);
144                   
145                   // check that the home space node exists - else Guest cannot proceed
146
if (nodeService.exists(guestHomeRef) == false)
147                   {
148                      throw new InvalidNodeRefException(guestHomeRef);
149                   }
150                   user.setHomeSpaceId(guestHomeRef.getId());
151                   
152                   tx.commit();
153                   tx = null; // clear this so we know not to rollback
154

155                   // store the User object in the Session - the authentication servlet will then proceed
156
session.setAttribute(AuthenticationHelper.AUTHENTICATION_USER, user);
157                
158                   // Set the current locale
159
I18NUtil.setLocale(Application.getLanguage(httpRequest.getSession()));
160                   
161                   // remove the session invalidated flag
162
session.removeAttribute(AuthenticationHelper.SESSION_INVALIDATED);
163                   
164                   // it is the responsibilty of the caller to handle the Guest return status
165
return AuthenticationStatus.Guest;
166                }
167                catch (AuthenticationException guestError)
168                {
169                   // Expected if Guest access not allowed - continue to login page as usual
170
}
171                catch (AccessDeniedException accessError)
172                {
173                   // Guest is unable to access either properties on Person
174
AuthenticationService unprotAuthService = (AuthenticationService)wc.getBean(UNPROTECTED_AUTH_SERVICE);
175                   unprotAuthService.invalidateTicket(unprotAuthService.getCurrentTicket());
176                   unprotAuthService.clearCurrentSecurityContext();
177                   logger.warn("Unable to login as Guest: " + accessError.getMessage());
178                }
179                catch (Throwable JavaDoc e)
180                {
181                   // Some other kind of serious failure to report
182
AuthenticationService unprotAuthService = (AuthenticationService)wc.getBean(UNPROTECTED_AUTH_SERVICE);
183                   unprotAuthService.invalidateTicket(unprotAuthService.getCurrentTicket());
184                   unprotAuthService.clearCurrentSecurityContext();
185                   throw new AlfrescoRuntimeException("Failed to authenticate as Guest user.", e);
186                }
187                finally
188                {
189                   try { if (tx != null) {tx.rollback();} } catch (Exception JavaDoc tex) {}
190                }
191             }
192          }
193          
194          // session invalidated - return to login screen
195
return AuthenticationStatus.Failure;
196       }
197       else
198       {
199          try
200          {
201             auth.validate(user.getTicket());
202          }
203          catch (AuthenticationException authErr)
204          {
205             // expired ticket
206
return AuthenticationStatus.Failure;
207          }
208          
209          // set last authentication username cookie value
210
if (loginBean != null)
211          {
212             setUsernameCookie(httpRequest, httpResponse, loginBean.getUsernameInternal());
213          }
214          
215          // Set the current locale
216
I18NUtil.setLocale(Application.getLanguage(httpRequest.getSession()));
217          
218          return AuthenticationStatus.Success;
219       }
220    }
221    
222    /**
223     * Helper to authenticate the current user using the supplied Ticket value.
224     *
225     * @return true if authentication successful, false otherwise.
226     */

227    public static AuthenticationStatus authenticate(
228          ServletContext JavaDoc context, HttpServletRequest JavaDoc httpRequest, HttpServletResponse JavaDoc httpResponse, String JavaDoc ticket)
229          throws IOException JavaDoc
230    {
231       // setup the authentication context
232
WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(context);
233       AuthenticationService auth = (AuthenticationService)wc.getBean(AUTHENTICATION_SERVICE);
234       try
235       {
236          auth.validate(ticket);
237       }
238       catch (AuthenticationException authErr)
239       {
240          return AuthenticationStatus.Failure;
241       }
242       
243       // Set the current locale
244
I18NUtil.setLocale(Application.getLanguage(httpRequest.getSession()));
245       
246       return AuthenticationStatus.Success;
247    }
248    
249    /**
250     * For no previous authentication or forced Guest - attempt Guest access
251     *
252     * @param ctx WebApplicationContext
253     * @param auth AuthenticationService
254     */

255    public static AuthenticationStatus portalGuestAuthenticate(WebApplicationContext ctx, PortletSession session, AuthenticationService auth)
256    {
257       UserTransaction JavaDoc tx = null;
258       try
259       {
260          auth.authenticateAsGuest();
261          
262          // if we get here then Guest access was allowed and successful
263
ServiceRegistry services = (ServiceRegistry)ctx.getBean(ServiceRegistry.SERVICE_REGISTRY);
264          tx = services.getTransactionService().getUserTransaction();
265          tx.begin();
266          
267          NodeService nodeService = services.getNodeService();
268          PersonService personService = (PersonService)ctx.getBean(PERSON_SERVICE);
269          NodeRef guestRef = personService.getPerson(PermissionService.GUEST_AUTHORITY);
270          User user = new User(PermissionService.GUEST_AUTHORITY, auth.getCurrentTicket(), guestRef);
271          NodeRef guestHomeRef = (NodeRef)nodeService.getProperty(guestRef, ContentModel.PROP_HOMEFOLDER);
272          
273          // check that the home space node exists - else Guest cannot proceed
274
if (nodeService.exists(guestHomeRef) == false)
275          {
276             throw new InvalidNodeRefException(guestHomeRef);
277          }
278          user.setHomeSpaceId(guestHomeRef.getId());
279          
280          tx.commit();
281          tx = null; // clear this so we know not to rollback
282

283          // store the User object in the Session - the authentication servlet will then proceed
284
session.setAttribute(AuthenticationHelper.AUTHENTICATION_USER, user);
285       
286          // Set the current locale
287
I18NUtil.setLocale(Application.getLanguage(session));
288          
289          // remove the session invalidated flag
290
session.removeAttribute(AuthenticationHelper.SESSION_INVALIDATED);
291          
292          // it is the responsibilty of the caller to handle the Guest return status
293
return AuthenticationStatus.Guest;
294       }
295       catch (AuthenticationException guestError)
296       {
297          // Expected if Guest access not allowed - continue to login page as usual
298
}
299       catch (AccessDeniedException accessError)
300       {
301          // Guest is unable to access either properties on Person
302
AuthenticationService unprotAuthService = (AuthenticationService)ctx.getBean(UNPROTECTED_AUTH_SERVICE);
303          unprotAuthService.invalidateTicket(unprotAuthService.getCurrentTicket());
304          unprotAuthService.clearCurrentSecurityContext();
305          logger.warn("Unable to login as Guest: " + accessError.getMessage());
306       }
307       catch (Throwable JavaDoc e)
308       {
309          // Some other kind of serious failure to report
310
AuthenticationService unprotAuthService = (AuthenticationService)ctx.getBean(UNPROTECTED_AUTH_SERVICE);
311          unprotAuthService.invalidateTicket(unprotAuthService.getCurrentTicket());
312          unprotAuthService.clearCurrentSecurityContext();
313          throw new AlfrescoRuntimeException("Failed to authenticate as Guest user.", e);
314       }
315       finally
316       {
317          try { if (tx != null) {tx.rollback();} } catch (Exception JavaDoc tex) {}
318       }
319       
320       return AuthenticationStatus.Failure;
321    }
322    
323    /**
324     * Setup the Alfresco auth cookie value.
325     *
326     * @param httpRequest
327     * @param httpResponse
328     * @param username
329     */

330    public static void setUsernameCookie(HttpServletRequest JavaDoc httpRequest, HttpServletResponse JavaDoc httpResponse, String JavaDoc username)
331    {
332       Cookie JavaDoc authCookie = getAuthCookie(httpRequest);
333       if (authCookie == null)
334       {
335          authCookie = new Cookie JavaDoc(COOKIE_ALFUSER, username);
336       }
337       else
338       {
339          authCookie.setValue(username);
340       }
341       authCookie.setPath(httpRequest.getContextPath());
342       // TODO: make this configurable - currently 7 days (value in seconds)
343
authCookie.setMaxAge(60*60*24*7);
344       httpResponse.addCookie(authCookie);
345    }
346    
347    /**
348     * Helper to return the Alfresco auth cookie. The cookie saves the last used username value.
349     *
350     * @param httpRequest
351     *
352     * @return Cookie if found or null if not present
353     */

354    public static Cookie JavaDoc getAuthCookie(HttpServletRequest JavaDoc httpRequest)
355    {
356       Cookie JavaDoc authCookie = null;
357       Cookie JavaDoc[] cookies = httpRequest.getCookies();
358       if (cookies != null)
359       {
360          for (int i=0; i<cookies.length; i++)
361          {
362             if (COOKIE_ALFUSER.equals(cookies[i].getName()))
363             {
364                // found cookie
365
authCookie = cookies[i];
366                break;
367             }
368          }
369       }
370       return authCookie;
371    }
372 }
373
Popular Tags