View Javadoc
1   /*
2    * Copyright (c) 2002-2023, City of 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.plugins.ctv.cas.web;
35  
36  import fr.paris.lutece.plugins.mylutece.modules.cas.authentication.CASAuthentication;
37  import fr.paris.lutece.plugins.mylutece.modules.cas.web.ParameterGatewayResolver;
38  import fr.paris.lutece.portal.business.user.AdminUser;
39  import fr.paris.lutece.portal.service.admin.AccessDeniedException;
40  import fr.paris.lutece.portal.service.admin.AdminAuthenticationService;
41  import fr.paris.lutece.portal.service.message.SiteMessage;
42  import fr.paris.lutece.portal.service.message.SiteMessageException;
43  import fr.paris.lutece.portal.service.message.SiteMessageService;
44  import fr.paris.lutece.portal.service.security.LoginRedirectException;
45  import fr.paris.lutece.portal.service.security.LuteceUser;
46  import fr.paris.lutece.portal.service.security.SecurityService;
47  import fr.paris.lutece.portal.service.security.UserNotSignedException;
48  import fr.paris.lutece.portal.service.spring.SpringContextService;
49  import fr.paris.lutece.portal.service.util.AppLogService;
50  import fr.paris.lutece.portal.service.util.AppPathService;
51  import org.jasig.cas.client.authentication.DefaultGatewayResolverImpl;
52  
53  import javax.security.auth.login.LoginException;
54  import javax.servlet.*;
55  import javax.servlet.http.HttpServletRequest;
56  import javax.servlet.http.HttpServletResponse;
57  import java.io.IOException;
58  import java.util.Enumeration;
59  
60  /**
61   * CustomLuteceCASFilter Surcharge LuteceCASFilter pour gerer le user Admin et eviter une deconnexion lors d'un appel BO effectue sur une URL FO
62   */
63  public class CustomLuteceCASFilter implements Filter
64  {
65  
66      /**
67       * Filter parameter that, if present, indicates that a message should be displayed if cookies are not supported
68       */
69      private static final String PARAM_NOCOOKIEMESSAGEKEY = "noCookieMessageKey";
70      /**
71       * Message key when cookies are not supported
72       */
73      private String noCookieMessageKey = null;
74      /**
75       * Filter parameter that, if present, indicates whether the user should be redirected to remove the gateway parameter from the query string.
76       */
77      private static final String PARAM_REDIRECTAFTERGATEWWAY = "redirectAfterGateway";
78      /**
79       * Specify whether the filter should redirect the user agent after a successful validation to remove the gateway parameter from the query string.
80       */
81      private boolean redirectAfterGateway = false;
82  
83      /**
84       *
85       * {@inheritDoc}
86       */
87      @Override
88      public void destroy( )
89      {
90          // nothing
91      }
92  
93      /**
94       *
95       * {@inheritDoc}
96       */
97      @Override
98      public void doFilter( ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain ) throws IOException, ServletException
99      {
100         HttpServletRequest request = (HttpServletRequest) servletRequest;
101         HttpServletResponse response = (HttpServletResponse) servletResponse;
102 
103         Boolean attrSupportsCookies = (Boolean) request.getAttribute( ParameterGatewayResolver.ATTR_SUPPORTS_COOKIES );
104         if ( attrSupportsCookies != null && !attrSupportsCookies.booleanValue( ) && noCookieMessageKey != null )
105         {
106             // cookies are blocked
107             try
108             {
109                 SiteMessageService.setMessage( request, noCookieMessageKey, SiteMessage.TYPE_ERROR );
110             }
111             catch( SiteMessageException e )
112             {
113                 request.getSession( true ).setAttribute( DefaultGatewayResolverImpl.CONST_CAS_GATEWAY, "yes" );
114                 response.sendRedirect( response.encodeRedirectURL( AppPathService.getSiteMessageUrl( request ) ) );
115                 return;
116             }
117         }
118         if ( redirectAfterGateway && request.getParameter( ParameterGatewayResolver.PARAM_GATEWAY ) != null )
119         {
120             String url = constructServiceURL( request );
121             request.getSession( true ).setAttribute( DefaultGatewayResolverImpl.CONST_CAS_GATEWAY, "yes" );
122             response.sendRedirect( response.encodeRedirectURL( url ) );
123             return;
124         }
125 
126         LuteceUser user = SecurityService.getInstance( ).getRegisteredUser( request );
127         // surcharge : recuperation du user BO
128         AdminUser userBO = null;
129         try
130         {
131             userBO = AdminAuthenticationService.getInstance( ).getRemoteUser( request );
132         }
133         catch( UserNotSignedException | AccessDeniedException e )
134         {
135             AppLogService.error( e );
136         }
137         // surcharge : traitement effectue uniquement si user FO et BO sont null
138         if ( user == null && userBO == null )
139         {
140             CASAuthentication casAuthentication = (CASAuthentication) SpringContextService.getBean( "mylutece-cas.authentication" );
141 
142             try
143             {
144                 user = casAuthentication.login( "", "", request );
145             }
146             catch( LoginException e )
147             {
148                 AppLogService.error( e.getMessage( ), e );
149             }
150             catch( LoginRedirectException e )
151             {
152                 AppLogService.error( e.getMessage( ), e );
153             }
154 
155             if ( AppLogService.isDebugEnabled( ) )
156             {
157                 AppLogService.debug( "User " + user + " logged" );
158             }
159 
160             SecurityService.getInstance( ).registerUser( request, user );
161         }
162 
163         chain.doFilter( servletRequest, response );
164     }
165 
166     /**
167      * Constructs the service URL, removing the gateway parameter
168      * 
169      * @param request
170      *            the request
171      * @return the service url
172      */
173     private String constructServiceURL( HttpServletRequest request )
174     {
175         StringBuffer url = request.getRequestURL( );
176         @SuppressWarnings( "unchecked" )
177         Enumeration<String> paramNames = request.getParameterNames( );
178         boolean firstParamater = true;
179         while ( paramNames.hasMoreElements( ) )
180         {
181             String param = paramNames.nextElement( );
182             if ( !param.equals( ParameterGatewayResolver.PARAM_GATEWAY ) )
183             {
184                 if ( firstParamater )
185                 {
186                     url.append( '?' );
187                     firstParamater = false;
188                 }
189                 else
190                 {
191                     url.append( '&' );
192                 }
193                 url.append( param ).append( '=' ).append( request.getParameter( param ) );
194             }
195         }
196         return url.toString( );
197     }
198 
199     /**
200      *
201      * {@inheritDoc}
202      */
203     @Override
204     public void init( FilterConfig config ) throws ServletException
205     {
206         noCookieMessageKey = config.getInitParameter( PARAM_NOCOOKIEMESSAGEKEY );
207         String paramRedirect = config.getInitParameter( PARAM_REDIRECTAFTERGATEWWAY );
208         redirectAfterGateway = paramRedirect != null && Boolean.parseBoolean( paramRedirect );
209     }
210 }