1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package fr.paris.lutece.portal.web.user;
35
36 import java.io.IOException;
37 import java.util.Collection;
38 import java.util.Enumeration;
39 import java.util.HashSet;
40 import java.util.Set;
41 import java.util.StringTokenizer;
42
43 import javax.servlet.Filter;
44 import javax.servlet.FilterChain;
45 import javax.servlet.FilterConfig;
46 import javax.servlet.ServletException;
47 import javax.servlet.ServletRequest;
48 import javax.servlet.ServletResponse;
49 import javax.servlet.http.HttpServletRequest;
50 import javax.servlet.http.HttpServletResponse;
51
52 import org.apache.commons.lang3.StringUtils;
53
54 import fr.paris.lutece.portal.business.securityheader.SecurityHeader;
55 import fr.paris.lutece.portal.business.securityheader.SecurityHeaderPageCategory;
56 import fr.paris.lutece.portal.business.securityheader.SecurityHeaderType;
57 import fr.paris.lutece.portal.service.admin.AccessDeniedException;
58 import fr.paris.lutece.portal.service.admin.AdminAuthenticationService;
59 import fr.paris.lutece.portal.service.admin.AdminUserService;
60 import fr.paris.lutece.portal.service.admin.PasswordResetException;
61 import fr.paris.lutece.portal.service.message.AdminMessage;
62 import fr.paris.lutece.portal.service.message.AdminMessageService;
63 import fr.paris.lutece.portal.service.security.SecurityTokenService;
64 import fr.paris.lutece.portal.service.security.UserNotSignedException;
65 import fr.paris.lutece.portal.service.securityheader.SecurityHeaderService;
66 import fr.paris.lutece.portal.service.spring.SpringContextService;
67 import fr.paris.lutece.portal.service.util.AppLogService;
68 import fr.paris.lutece.portal.service.util.AppPathService;
69 import fr.paris.lutece.portal.service.util.AppPropertiesService;
70 import fr.paris.lutece.portal.web.constants.Messages;
71 import fr.paris.lutece.portal.web.constants.Parameters;
72 import fr.paris.lutece.util.url.UrlItem;
73
74 import org.apache.logging.log4j.LogManager;
75 import org.apache.logging.log4j.Logger;
76
77
78
79
80 public class AuthenticationFilter implements Filter
81 {
82 private static final String PROPERTY_URL_PREFIX = "path.jsp.admin.public.";
83 private static final String PROPERTY_URL_SUFFIX_LIST = "list";
84 private static final String CONSTANT_LIST_SEPARATOR = ",";
85 private static final String PROPERTY_RESET_EXCEPTION_MESSAGE = "User must reset his password.";
86 private static final String PROPERTY_JSP_URL_ADMIN_LOGOUT = "lutece.admin.logout.url";
87 private static final String JSP_URL_ADMIN_LOGIN = "jsp/admin/AdminLogin.jsp";
88 private static final String BEAN_SECURITY_HEADER_SERVICE = "securityHeaderService";
89 private static final String LOGGER_LUTECE_SECURITY_HEADER = "lutece.securityHeader";
90 private Logger _logger = LogManager.getLogger( LOGGER_LUTECE_SECURITY_HEADER );
91
92
93
94
95 @Override
96 public void init( FilterConfig config ) throws ServletException
97 {
98
99 }
100
101
102
103
104 @Override
105 public void destroy( )
106 {
107
108 }
109
110
111
112
113 @Override
114 public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain ) throws IOException, ServletException
115 {
116 HttpServletRequest req = (HttpServletRequest) request;
117 HttpServletResponse resp = (HttpServletResponse) response;
118
119 AppLogService.debug( "Accessing url : {}", ( ) -> getResquestedUrl( req ) );
120
121 if ( isPrivateUrl( req ) )
122 {
123 addAdminAuthenticatedPagesHeaders(req, resp);
124 try
125 {
126 filterAccess( req );
127 }
128 catch( UserNotSignedException e )
129 {
130 AdminAuthenticationService.getInstance( ).setLoginNextUrl( req );
131
132 String strRedirectUrl = null;
133
134 if ( AdminAuthenticationService.getInstance( ).isExternalAuthentication( ) )
135 {
136 AppLogService.debug( "New session behind external authentication : {}", ( ) -> getResquestedUrl( req ) );
137
138 strRedirectUrl = AdminMessageService.getMessageUrl( req, Messages.MESSAGE_USER_NEW_SESSION, getRedirectUrlExternalAuthentication( req ),
139 AdminMessage.TYPE_INFO );
140 }
141 else
142 {
143 AppLogService.debug( "Access NOT granted to url : {}", ( ) -> getResquestedUrl( req ) );
144
145 strRedirectUrl = AdminMessageService.getMessageUrl( req, Messages.MESSAGE_USER_NOT_AUTHENTICATED, getRedirectUrl( req ),
146 AdminMessage.TYPE_WARNING );
147 }
148
149 resp.sendRedirect( getAbsoluteUrl( req, strRedirectUrl ) );
150
151 return;
152 }
153 catch( AccessDeniedException e )
154 {
155 AppLogService.debug( "Access NOT granted to url : {}", getResquestedUrl( req ) );
156
157 String strRedirectUrl = AdminMessageService.getMessageUrl( req, Messages.MESSAGE_AUTH_FAILURE, getRedirectUrl( req ), AdminMessage.TYPE_ERROR );
158 resp.sendRedirect( getAbsoluteUrl( req, strRedirectUrl ) );
159
160 return;
161 }
162 catch( PasswordResetException e )
163 {
164 if ( !getResquestedUrl( req ).equals( getChangePasswordUrl( req ) ) && !getResquestedUrl( req ).equals( getLoginUrl( req ) ) )
165 {
166 String strRedirectUrl = AdminMessageService.getMessageUrl( req, Messages.MESSAGE_USER_MUST_CHANGE_PASSWORD, getChangePasswordUrl( req ),
167 AdminMessage.TYPE_ERROR );
168 resp.sendRedirect( getAbsoluteUrl( req, strRedirectUrl ) );
169
170 return;
171 }
172 }
173 }
174 else if(isAdminLogoutUrl(req))
175 {
176 addBoLogoutPageSecurityHeaders(req, resp);
177 }
178
179 chain.doFilter( request, response );
180 }
181
182
183
184
185
186
187
188
189
190 private void addAdminAuthenticatedPagesHeaders( HttpServletRequest request, HttpServletResponse response )
191 {
192 SecurityHeaderService securityHeaderService = SpringContextService.getBean( BEAN_SECURITY_HEADER_SERVICE );
193 Collection<SecurityHeader> securityHeadersToAddList = securityHeaderService.findActive( SecurityHeaderType.PAGE.getCode( ), SecurityHeaderPageCategory.AUTHENTICATED_ADMIN_BACK_OFFICE.getCode( ) );
194 if( securityHeadersToAddList != null )
195 {
196 for( SecurityHeader securityHeader : securityHeadersToAddList )
197 {
198 response.setHeader( securityHeader.getName( ), securityHeader.getValue( ) );
199 _logger.debug( "Security header added to admin authenticated BO page {} - name : {}, value : {} ", request.getServletPath( ), securityHeader.getName( ), securityHeader.getValue( ) );
200 }
201 }
202 }
203
204
205
206
207
208
209
210
211
212 private void addBoLogoutPageSecurityHeaders( HttpServletRequest request, HttpServletResponse response )
213 {
214 SecurityHeaderService securityHeaderService = SpringContextService.getBean( BEAN_SECURITY_HEADER_SERVICE );
215 Collection<SecurityHeader> securityHeadersList = securityHeaderService.findActive( SecurityHeaderType.PAGE.getCode( ), SecurityHeaderPageCategory.LOGOUT_BO.getCode( ) );
216 if( securityHeadersList != null )
217 {
218 for( SecurityHeader securityHeader : securityHeadersList )
219 {
220 response.setHeader( securityHeader.getName( ), securityHeader.getValue( ) );
221 _logger.debug( "Security header added to logout page {} - name : {}, value : {} ", request.getServletPath( ), securityHeader.getName( ), securityHeader.getValue( ) );
222 }
223 }
224 }
225
226
227
228
229
230
231
232
233 private boolean isAdminLogoutUrl( HttpServletRequest request )
234 {
235 return getResquestedUrl( request ).equals( getAbsoluteUrl( request, AppPropertiesService.getProperty( PROPERTY_JSP_URL_ADMIN_LOGOUT ) ) );
236 }
237
238
239
240
241
242
243
244
245 private String getRedirectUrl( HttpServletRequest request )
246 {
247 String strLoginUrl = getLoginUrl( request );
248
249 if ( strLoginUrl == null )
250 {
251 return null;
252 }
253
254 UrlItem/url/UrlItem.html#UrlItem">UrlItem url = new UrlItem( strLoginUrl );
255
256 return url.getUrl( );
257 }
258
259
260
261
262
263
264
265
266
267 private String getLoginUrl( HttpServletRequest request )
268 {
269 String strLoginUrl = AdminAuthenticationService.getInstance( ).getLoginPageUrl( );
270
271 return getAbsoluteUrl( request, strLoginUrl );
272 }
273
274
275
276
277
278
279
280
281 private String getLogoutUrl( HttpServletRequest request )
282 {
283 return getAbsoluteUrl( request, AppPropertiesService.getProperty( PROPERTY_JSP_URL_ADMIN_LOGOUT ) );
284 }
285
286
287
288
289
290
291
292
293
294 private String getChangePasswordUrl( HttpServletRequest request )
295 {
296 String strChangePasswordUrl = AdminAuthenticationService.getInstance( ).getChangePasswordPageUrl( );
297
298 return getAbsoluteUrl( request, strChangePasswordUrl );
299 }
300
301
302
303
304
305
306
307
308
309
310 private boolean isPrivateUrl( HttpServletRequest request )
311 {
312 String strUrl = getResquestedUrl( request );
313 Set<String> allowedUrlSet = createAllowedUrlSet( request );
314 return !allowedUrlSet.contains( strUrl ) && !isInPublicUrlList( request, strUrl );
315 }
316
317 private Set<String> createAllowedUrlSet( HttpServletRequest request )
318 {
319 Set<String> set = new HashSet<>( );
320 set.add( getAbsoluteUrl( request, JSP_URL_ADMIN_LOGIN ) );
321 set.add( getLoginUrl( request ) );
322 set.add( getLogoutUrl( request ) );
323 return set;
324 }
325
326
327
328
329
330
331
332
333
334
335
336
337 private static void filterAccess( HttpServletRequest request ) throws UserNotSignedException, AccessDeniedException
338 {
339 if ( AdminAuthenticationService.getInstance( ).isExternalAuthentication( ) )
340 {
341
342
343 AdminAuthenticationService.getInstance( ).getRemoteUser( request );
344 }
345 else
346 {
347 if ( AdminAuthenticationService.getInstance( ).getRegisteredUser( request ) == null )
348 {
349
350 throw new UserNotSignedException( );
351 }
352
353 if ( AdminUserService.getAdminUser( request ).isPasswordReset( ) )
354 {
355 throw new PasswordResetException( PROPERTY_RESET_EXCEPTION_MESSAGE );
356 }
357 }
358 }
359
360
361
362
363
364
365
366
367
368
369
370 private boolean isInPublicUrlList( HttpServletRequest request, String strRequestedUrl )
371 {
372
373 String strList = AppPropertiesService.getProperty( PROPERTY_URL_PREFIX + PROPERTY_URL_SUFFIX_LIST );
374
375
376 StringTokenizer strTokens = new StringTokenizer( strList, CONSTANT_LIST_SEPARATOR );
377
378 while ( strTokens.hasMoreTokens( ) )
379 {
380 String strName = strTokens.nextToken( );
381 String strUrl = AppPropertiesService.getProperty( PROPERTY_URL_PREFIX + strName );
382 strUrl = getAbsoluteUrl( request, strUrl );
383
384 if ( strRequestedUrl.equals( strUrl ) )
385 {
386 return true;
387 }
388 }
389
390 return false;
391 }
392
393
394
395
396
397
398
399
400
401
402
403
404 private String getAbsoluteUrl( HttpServletRequest request, String strUrl )
405 {
406 if ( ( strUrl != null ) && !strUrl.startsWith( "http://" ) && !strUrl.startsWith( "https://" ) )
407 {
408 return AppPathService.getBaseUrl( request ) + strUrl;
409 }
410
411 return strUrl;
412 }
413
414
415
416
417
418
419
420
421
422 private String getResquestedUrl( HttpServletRequest request )
423 {
424 return AppPathService.getBaseUrl( request ) + request.getServletPath( ).substring( 1 );
425 }
426
427
428
429
430
431
432
433
434
435 private String getRedirectUrlExternalAuthentication( HttpServletRequest request )
436 {
437 String strNextUrl = AdminAuthenticationService.getInstance( ).getLoginNextUrl( request );
438
439 if ( StringUtils.isEmpty( strNextUrl ) )
440 {
441 strNextUrl = AppPathService.getAdminMenuUrl( );
442 }
443
444 return strNextUrl;
445 }
446 }