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