View Javadoc
1   /*
2    * Copyright (c) 2002-2014, Mairie de Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.portal.service.admin;
35  
36  import fr.paris.lutece.portal.business.user.AdminUser;
37  import fr.paris.lutece.portal.business.user.AdminUserHome;
38  import fr.paris.lutece.portal.business.user.authentication.AdminAuthentication;
39  import fr.paris.lutece.portal.business.user.authentication.LuteceDefaultAdminAuthentication;
40  import fr.paris.lutece.portal.service.init.LuteceInitException;
41  import fr.paris.lutece.portal.service.security.UserNotSignedException;
42  import fr.paris.lutece.portal.service.spring.SpringContextService;
43  import fr.paris.lutece.portal.service.util.AppLogService;
44  import fr.paris.lutece.util.url.UrlItem;
45  
46  import org.apache.commons.lang.StringUtils;
47  
48  import java.util.Collection;
49  import java.util.Enumeration;
50  
51  import javax.security.auth.login.LoginException;
52  
53  import javax.servlet.http.HttpServletRequest;
54  import javax.servlet.http.HttpSession;
55  
56  
57  /**
58   * This class provides a security service to register and check user authentication
59   */
60  public final class AdminAuthenticationService
61  {
62      /**
63       * Session attribute that stores the AdminUser object attached to the session
64       */
65      private static final String ATTRIBUTE_ADMIN_USER = "lutece_admin_user";
66      private static final String ATTRIBUTE_ADMIN_LOGIN_NEXT_URL = "luteceAdminLoginNextUrl";
67      private static final String BEAN_ADMIN_AUTHENTICATION_MODULE = "adminAuthenticationModule";
68      private static AdminAuthenticationService _singleton = new AdminAuthenticationService(  );
69      private static AdminAuthentication _authentication;
70      private static boolean _bUseDefaultModule;
71  
72      /**
73       * Private constructor
74       */
75      private AdminAuthenticationService(  )
76      {
77      }
78  
79      /**
80       * Initialize service
81       * @throws LuteceInitException If error while initialization
82       */
83      public static synchronized void init(  ) throws LuteceInitException
84      {
85          _authentication = (AdminAuthentication) SpringContextService.getBean( BEAN_ADMIN_AUTHENTICATION_MODULE );
86          AppLogService.info( "Authentication module loaded : " + _authentication.getAuthServiceName(  ) );
87  
88          if ( _authentication.getClass(  ).equals( LuteceDefaultAdminAuthentication.class ) )
89          {
90              _bUseDefaultModule = true;
91          }
92      }
93  
94      /**
95       * Get the unique instance of the Security Service
96       * @return The instance
97       */
98      public static AdminAuthenticationService getInstance(  )
99      {
100         return _singleton;
101     }
102 
103     /**
104      * Check whether the authentication service is configurer on the default module.
105      * @return true if the default module is in use, false if another module is used
106      */
107     public boolean isDefaultModuleUsed(  )
108     {
109         return _bUseDefaultModule;
110     }
111 
112     /**
113      * Gets the AdminUser attached to the current Http session
114      *
115      * @return A valid AdminUser object if found
116      * @param request The Http request
117      * @throws AccessDeniedException If the user cannot have access
118      * @throws UserNotSignedException If the user is not signed
119      */
120     public AdminUser getRemoteUser( HttpServletRequest request )
121         throws UserNotSignedException, AccessDeniedException
122     {
123         AdminUser user = getRegisteredUser( request );
124 
125         if ( _authentication.isExternalAuthentication(  ) )
126         {
127             if ( user == null )
128             {
129                 // User is not registered by Lutece, but it may be authenticated by another system
130                 user = _authentication.getHttpAuthenticatedUser( request );
131                 registerUser( request, user );
132                 AdminUserService.updateDateLastLogin( user.getUserId(  ) );
133 
134                 // Start a new session
135                 throw new UserNotSignedException(  );
136             }
137             else
138             {
139                 // user is already in session. for external auth, we check that the user hasn't changed in the external module .
140                 AdminUser newUser = _authentication.getHttpAuthenticatedUser( request );
141 
142                 if ( newUser == null )
143                 {
144                     throw new AccessDeniedException( "User not found while retrieving from external authentication" );
145                 }
146                 else if ( !newUser.getAccessCode(  ).equals( user.getAccessCode(  ) ) )
147                 {
148                     unregisterUser( request );
149                     registerUser( request, newUser );
150                     AdminUserService.updateDateLastLogin( user.getUserId(  ) );
151 
152                     // Start a new session
153                     throw new UserNotSignedException(  );
154                 }
155             }
156         }
157         else // if not external authentication, just check if user is null or not
158         {
159             if ( user == null )
160             {
161                 // user is not signed
162                 throw new UserNotSignedException(  );
163             }
164         }
165 
166         return user;
167     }
168 
169     /**
170      * Checks user's login with the Authentication service.
171      * @param request The Http request
172      * @param strAccessCode The user's login
173      * @param strPassword The user's password
174      * @throws LoginException The LoginException
175      */
176     public void loginUser( HttpServletRequest request, final String strAccessCode, final String strPassword )
177         throws LoginException
178     {
179         AdminUser user = _authentication.login( strAccessCode, strPassword, request );
180 
181         try
182         {
183             registerUser( request, user );
184         }
185         catch ( AccessDeniedException e )
186         {
187             throw new LoginException(  );
188         }
189         catch ( UserNotSignedException e )
190         {
191             throw new LoginException(  );
192         }
193 
194         AdminUserService.updateDateLastLogin( user.getUserId(  ) );
195     }
196 
197     /**
198      * Logout the user
199      * @param request The HTTP request
200      */
201     public void logoutUser( HttpServletRequest request )
202     {
203         AdminUser user;
204 
205         try
206         {
207             user = getRemoteUser( request );
208         }
209         catch ( UserNotSignedException e )
210         {
211             return;
212         }
213         catch ( AccessDeniedException e )
214         {
215             return;
216         }
217 
218         _authentication.logout( user );
219         unregisterUser( request );
220     }
221 
222     /**
223      * Bind user : complete module user with local settings (roles, etc)
224      *
225      * @param user The current user
226      * @throws AccessDeniedException If the user cannot have access
227      * @throws UserNotSignedException If the user is not signed
228      * @return The AdminUser
229      */
230     private AdminUser bindUser( AdminUser user ) throws AccessDeniedException, UserNotSignedException
231     {
232         if ( user == null )
233         {
234             throw new UserNotSignedException(  );
235         }
236 
237         // retrieve the user in local system from the access code
238         AdminUser bindUser = AdminUserHome.findUserByLogin( user.getAccessCode(  ) );
239 
240         // only allow a user that is marked active
241         if ( ( bindUser == null ) || ( !bindUser.isStatusActive(  ) ) )
242         {
243             throw new AccessDeniedException( "User " + bindUser + " is null or not active" );
244         }
245 
246         // set the rights for this user
247         bindUser.setRights( AdminUserHome.getRightsListForUser( bindUser.getUserId(  ) ) );
248 
249         // set the rights for this user
250         bindUser.setRoles( AdminUserHome.getRolesListForUser( bindUser.getUserId(  ) ) );
251 
252         return bindUser;
253     }
254 
255     /**
256      * Register the user in the Http session
257      *
258      * @param request The Http request
259      * @param user The current user
260      * @throws AccessDeniedException If the user cannot have access
261      * @throws UserNotSignedException If the user is not signed
262      */
263     public void registerUser( HttpServletRequest request, AdminUser user )
264         throws AccessDeniedException, UserNotSignedException
265     {
266         HttpSession session = request.getSession( true );
267         session.setAttribute( ATTRIBUTE_ADMIN_USER, bindUser( user ) );
268     }
269 
270     /**
271      * Unregister the user in the Http session
272      * @param request The Http request
273      */
274     public void unregisterUser( HttpServletRequest request )
275     {
276         HttpSession session = request.getSession( true );
277         session.removeAttribute( ATTRIBUTE_ADMIN_USER );
278     }
279 
280     /**
281      * Gets the Lutece user registered in the Http session
282      * @param request The HTTP request
283      * @return The User registered or null if the user has not been registered
284      */
285     public AdminUser getRegisteredUser( HttpServletRequest request )
286     {
287         HttpSession session = request.getSession(  );
288 
289         if ( session != null )
290         {
291             return (AdminUser) session.getAttribute( ATTRIBUTE_ADMIN_USER );
292         }
293 
294         return null;
295     }
296 
297     /**
298      * Returns the authentication type : External or Lutece portal based
299      * @return true if the user is already authenticated or false if it needs to login.
300      */
301     public boolean isExternalAuthentication(  )
302     {
303         return _authentication.isExternalAuthentication(  );
304     }
305 
306     /**
307      * Returns the Login page URL of the Authentication Service
308      * @return The URL
309      */
310     public String getLoginPageUrl(  )
311     {
312         return _authentication.getLoginPageUrl(  );
313     }
314 
315     /**
316      * Returns the modification password page URL of the Authentication Service
317      * @return The URL
318      */
319     public String getChangePasswordPageUrl(  )
320     {
321         return _authentication.getChangePasswordPageUrl(  );
322     }
323 
324     /**
325      * Returns the DoLogin URL of the Authentication Service
326      * @return The URL
327      */
328     public String getDoLoginUrl(  )
329     {
330         return _authentication.getDoLoginUrl(  );
331     }
332 
333     /**
334      * Returns the DoLogout URL of the Authentication Service
335      * @return The URL
336      */
337     public String getDoLogoutUrl(  )
338     {
339         return _authentication.getDoLogoutUrl(  );
340     }
341 
342     /**
343      * Returns the new account page URL of the Authentication Service
344      * @return The URL
345      */
346     public String getNewAccountPageUrl(  )
347     {
348         return _authentication.getNewAccountPageUrl(  );
349     }
350 
351     /**
352      * Returns the view account page URL of the Authentication Service
353      * @return The URL
354      */
355     public String getViewAccountPageUrl(  )
356     {
357         return _authentication.getViewAccountPageUrl(  );
358     }
359 
360     /**
361      * Returns the lost password URL of the Authentication Service
362      * @return The URL
363      */
364     public String getLostPasswordPageUrl(  )
365     {
366         return _authentication.getLostPasswordPageUrl(  );
367     }
368 
369     /**
370      * Returns the lost login URL of the Authentication Service
371      * @return The URL
372      */
373     public String getLostLoginPageUrl(  )
374     {
375         return _authentication.getLostLoginPageUrl(  );
376     }
377 
378     /**
379      * Returns the user list
380      *
381      * @return the collection of all users from the module
382      * @param strLastName The last name
383      * @param strFirstName The first name
384      * @param strEmail The email
385      */
386     public Collection<AdminUser> getUserListFromModule( String strLastName, String strFirstName, String strEmail )
387     {
388         return _authentication.getUserList( strLastName, strFirstName, strEmail );
389     }
390 
391     /**
392      *
393      * @param strAccessCode The login
394      * @return The AdminUser
395      */
396     public AdminUser getUserPublicDataFromModule( String strAccessCode )
397     {
398         return _authentication.getUserPublicData( strAccessCode );
399     }
400 
401     /**
402      * Set the admin login next url
403      * @param request the HTTP request
404      */
405     public void setLoginNextUrl( HttpServletRequest request )
406     {
407         String strNextUrl = request.getRequestURI(  );
408         UrlItem url = new UrlItem( strNextUrl );
409         Enumeration enumParams = request.getParameterNames(  );
410 
411         while ( enumParams.hasMoreElements(  ) )
412         {
413             String strParamName = (String) enumParams.nextElement(  );
414             url.addParameter( strParamName, request.getParameter( strParamName ) );
415         }
416 
417         HttpSession session = request.getSession( true );
418         session.setAttribute( ATTRIBUTE_ADMIN_LOGIN_NEXT_URL, url.getUrl(  ) );
419     }
420 
421     /**
422      * Returns the url (asked before login) to redirect after login
423      * @param request The Http request
424      * @return The url asked before login
425      */
426     public String getLoginNextUrl( HttpServletRequest request )
427     {
428         String strNextUrl = StringUtils.EMPTY;
429         HttpSession session = request.getSession( false );
430 
431         if ( session != null )
432         {
433             strNextUrl = (String) session.getAttribute( ATTRIBUTE_ADMIN_LOGIN_NEXT_URL );
434             session.removeAttribute( ATTRIBUTE_ADMIN_LOGIN_NEXT_URL );
435         }
436 
437         return strNextUrl;
438     }
439 }