View Javadoc
1   /**
2    * Copyright 2011-2013 The Kuali Foundation Licensed under the
3    * Educational Community License, Version 2.0 (the "License"); you may
4    * not use this file except in compliance with the License. You may
5    * obtain a copy of the License at
6    *
7    * http://www.osedu.org/licenses/ECL-2.0
8    *
9    * Unless required by applicable law or agreed to in writing,
10   * software distributed under the License is distributed on an "AS IS"
11   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12   * or implied. See the License for the specific language governing
13   * permissions and limitations under the License.
14   */
15  
16  package org.kuali.mobility.security.authn.interceptors;
17  
18  import org.apache.log4j.Logger;
19  import org.kuali.mobility.security.authn.util.AuthenticationConstants;
20  import org.kuali.mobility.security.user.api.User;
21  import org.kuali.mobility.security.user.api.UserDao;
22  import org.kuali.mobility.security.user.entity.UserImpl;
23  import org.springframework.beans.factory.annotation.Autowired;
24  import org.springframework.beans.factory.annotation.Qualifier;
25  import org.springframework.web.servlet.HandlerInterceptor;
26  import org.springframework.web.servlet.ModelAndView;
27  
28  import javax.servlet.http.HttpServletRequest;
29  import javax.servlet.http.HttpServletResponse;
30  
31  /**
32   * The RemoteUserInterceptor looks for a remote_user and creates a user 
33   * object in the session for it.  It is the base hook to start an authenticated 
34   * session. All authN and authZ should either be added to it or come after 
35   * it in the filter/interceptor chain.
36   */
37  public class RemoteUserInterceptor implements HandlerInterceptor {
38  	private static final Logger LOG = Logger.getLogger( RemoteUserInterceptor.class );
39  
40  	@Autowired
41  	@Qualifier("kmeUserDao")
42  	private UserDao userDao;
43  
44  	@Override
45  	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
46  		LOG.trace("RemoteUserInterceptor preHandle");
47          User user = (User)request.getSession(true).getAttribute( AuthenticationConstants.KME_USER_KEY );
48  		if( user == null )
49  		{
50              LOG.debug("No user found in session, creating a new one.");
51  			user = new UserImpl();
52  			request.getSession().setAttribute( AuthenticationConstants.KME_USER_KEY, user );
53  		}
54  		if( request.getRemoteUser() != null && !request.getRemoteUser().isEmpty() )
55  		{
56              LOG.debug("REMOTE_USER exists. Preparing to reconcile user :"+request.getRemoteUser());
57  
58  			if( user.isPublicUser() )
59  			{
60                  LOG.debug("User was public, loading user "+request.getRemoteUser()+" from database.");
61  				User existingUser = getUserDao().loadUserByLoginName(request.getRemoteUser());
62  				if( existingUser == null ) {
63                      LOG.debug("User "+request.getRemoteUser()+" not found in database.");
64  					user.setLoginName(request.getRemoteUser());
65  					getUserDao().saveUser(user);
66  				} else {
67                      LOG.debug("User found and being pushed into session.");
68  					request.getSession().setAttribute( AuthenticationConstants.KME_USER_KEY, existingUser );
69  				}
70  			}
71  			else if( !request.getRemoteUser().equalsIgnoreCase( user.getLoginName() ) )
72  			{
73  				LOG.info( "Identify mismatch. Expected ["+user.getLoginName()+"] recieved ["+request.getRemoteUser()+"]" );
74  				user.invalidateUser();
75  				request.getSession().invalidate();
76  				request.getSession(true);
77  				response.sendError(401, "Identity Mismatch.  Attempting to override existing user with a new one." );
78  			}
79  
80  		}
81  
82          /*	Comment out the following block as all requests (include static contents i.e. image, cs and js files) go through
83              this interceptor, while only requests for protected/secured contents have REMOTE_USER.
84              Should improve or refactor in the future.
85          */
86          /*
87          else
88  		{
89              LOG.info("REMOTE_USER NOT exists");
90  			if( user.getLoginName() != null )
91  			{
92  				if( !user.getLoginName().startsWith( AuthenticationConstants.PUBLIC_USER ) )
93  				{
94  					LOG.info( "Identity mismatch. Session user populated when no REMOTE_USER provided. User removed from session." );
95  					user.setLoginName(AuthenticationConstants.PUBLIC_USER + request.getSession().getId());
96  				}
97  				else if( !user.getLoginName().equalsIgnoreCase( AuthenticationConstants.PUBLIC_USER + request.getSession().getId() ) )
98  				{
99  					LOG.info( "Identity mismatch. Public user key does not match expected id. User updated in session.");
100 					user.invalidateUser();
101                     user = new UserImpl();
102 					user.setLoginName(AuthenticationConstants.PUBLIC_USER + request.getSession().getId());
103                     request.getSession().setAttribute( AuthenticationConstants.KME_USER_KEY, user );
104                 }
105 			}
106 		}
107 		*/
108 		return true;
109 	}
110 
111 	@Override
112 	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}
113 
114 	@Override
115 	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
116 
117 	public UserDao getUserDao() {
118 		return userDao;
119 	}
120 
121 	public void setUserDao(UserDao userDao) {
122 		this.userDao = userDao;
123 	}
124 }