001/** 002 * Copyright 2005-2016 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.kew.web; 017 018import org.apache.commons.lang.StringUtils; 019import org.apache.log4j.MDC; 020import org.kuali.rice.core.api.config.property.ConfigurationService; 021import org.kuali.rice.core.api.exception.RiceRuntimeException; 022import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader; 023import org.kuali.rice.coreservice.framework.parameter.ParameterService; 024import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator; 025import org.kuali.rice.kew.api.KewApiConstants; 026import org.kuali.rice.kim.api.KimConstants; 027import org.kuali.rice.kim.api.identity.AuthenticationService; 028import org.kuali.rice.kim.api.identity.IdentityService; 029import org.kuali.rice.kim.api.identity.principal.Principal; 030import org.kuali.rice.kim.api.permission.PermissionService; 031import org.kuali.rice.kim.api.services.KimApiServiceLocator; 032import org.kuali.rice.krad.UserSession; 033import org.kuali.rice.krad.exception.AuthenticationException; 034import org.kuali.rice.krad.service.KRADServiceLocator; 035import org.kuali.rice.krad.util.KRADConstants; 036import org.kuali.rice.krad.util.KRADUtils; 037 038import javax.servlet.Filter; 039import javax.servlet.FilterChain; 040import javax.servlet.FilterConfig; 041import javax.servlet.ServletException; 042import javax.servlet.ServletRequest; 043import javax.servlet.ServletResponse; 044import javax.servlet.http.Cookie; 045import javax.servlet.http.HttpServletRequest; 046import javax.servlet.http.HttpServletResponse; 047import javax.xml.namespace.QName; 048import java.io.IOException; 049import java.util.Collections; 050import java.util.UUID; 051 052 053/** 054 * A filter for processing user logins and creating a {@link UserSession}. 055 * 056 * @see UserSession 057 * @author Kuali Rice Team (rice.collab@kuali.org) 058 */ 059public class UserLoginFilter implements Filter { 060 061 private static final String MDC_USER = "user"; 062 063 private IdentityService identityService; 064 private PermissionService permissionService; 065 private ConfigurationService kualiConfigurationService; 066 private ParameterService parameterService; 067 068 private FilterConfig filterConfig; 069 070 @Override 071 public void init(FilterConfig config) throws ServletException { 072 this.filterConfig = config; 073 } 074 075 @Override 076 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 077 this.doFilter((HttpServletRequest) request, (HttpServletResponse) response, chain); 078 } 079 080 private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { 081 082 try { 083 establishUserSession(request); 084 establishSessionCookie(request, response); 085 establishBackdoorUser(request); 086 087 addToMDC(request); 088 089 chain.doFilter(request, response); 090 } finally { 091 removeFromMDC(); 092 } 093 094 } 095 096 @Override 097 public void destroy() { 098 filterConfig = null; 099 } 100 101 /** 102 * Checks if a user can be authenticated and if so establishes a UserSession for that user. 103 */ 104 private void establishUserSession(HttpServletRequest request) { 105 if (!isUserSessionEstablished(request)) { 106 String principalName = ((AuthenticationService) GlobalResourceLoader.getResourceLoader().getService(new QName("kimAuthenticationService"))).getPrincipalName(request); 107 if (StringUtils.isBlank(principalName)) { 108 throw new AuthenticationException( "Blank User from AuthenticationService - This should never happen." ); 109 } 110 111 Principal principal = getIdentityService().getPrincipalByPrincipalName( principalName ); 112 if (principal == null) { 113 throw new AuthenticationException("Unknown User: " + principalName); 114 } 115 116 if (!isAuthorizedToLogin(principal.getPrincipalId())) { 117 throw new AuthenticationException("You cannot log in, because you are not an active Kuali user.\nPlease ask someone to activate your account if you need to use Kuali Systems.\nThe user id provided was: " + principalName + ".\n"); 118 } 119 120 final UserSession userSession = new UserSession(principalName); 121 if ( userSession.getPerson() == null ) { 122 throw new AuthenticationException("Invalid User: " + principalName); 123 } 124 125 request.getSession().setAttribute(KRADConstants.USER_SESSION_KEY, userSession); 126 } 127 } 128 129 /** checks if the passed in principalId is authorized to log in. */ 130 private boolean isAuthorizedToLogin(String principalId) { 131 return getPermissionService().isAuthorized( 132 principalId, 133 KimConstants.KIM_TYPE_DEFAULT_NAMESPACE, 134 KimConstants.PermissionNames.LOG_IN, 135 Collections.singletonMap("principalId", principalId)); 136 } 137 138 139 /** 140 * Creates a session id cookie if one does not exists. Write the cookie out to the response with that session id. 141 * Also, sets the cookie on the established user session. 142 */ 143 private void establishSessionCookie(HttpServletRequest request, HttpServletResponse response) { 144 String kualiSessionId = this.getKualiSessionId(request.getCookies()); 145 if (kualiSessionId == null) { 146 kualiSessionId = UUID.randomUUID().toString(); 147 response.addCookie(new Cookie(KRADConstants.KUALI_SESSION_ID, kualiSessionId)); 148 } 149 KRADUtils.getUserSessionFromRequest(request).setKualiSessionId(kualiSessionId); 150 } 151 152 /** gets the kuali session id from an array of cookies. If a session id does not exist returns null. */ 153 private String getKualiSessionId(final Cookie[] cookies) { 154 if (cookies != null) { 155 for (Cookie cookie : cookies) { 156 if (KRADConstants.KUALI_SESSION_ID.equals(cookie.getName())) { 157 return cookie.getValue(); 158 } 159 } 160 } 161 return null; 162 } 163 164 /** establishes the backdoor user on the established user id if backdoor capabilities are valid. */ 165 private void establishBackdoorUser(HttpServletRequest request) { 166 final String backdoor = request.getParameter(KRADConstants.BACKDOOR_PARAMETER); 167 if ( StringUtils.isNotBlank(backdoor) ) { 168 if ( !getKualiConfigurationService().getPropertyValueAsString(KRADConstants.PROD_ENVIRONMENT_CODE_KEY) 169 .equalsIgnoreCase( 170 getKualiConfigurationService().getPropertyValueAsString(KRADConstants.ENVIRONMENT_KEY)) ) { 171 if ( getParameterService().getParameterValueAsBoolean(KRADConstants.KUALI_RICE_WORKFLOW_NAMESPACE, KRADConstants.DetailTypes.BACKDOOR_DETAIL_TYPE, KewApiConstants.SHOW_BACK_DOOR_LOGIN_IND) ) { 172 try{ 173 KRADUtils.getUserSessionFromRequest(request).setBackdoorUser(backdoor); 174 }catch(RiceRuntimeException re){ 175 //Ignore so BackdoorAction can redirect to invalid_backdoor_portal 176 } 177 } 178 } 179 } 180 181 } 182 183 private void addToMDC(HttpServletRequest request) { 184 MDC.put(MDC_USER, KRADUtils.getUserSessionFromRequest(request).getPrincipalName()); 185 } 186 187 private void removeFromMDC() { 188 MDC.remove(MDC_USER); 189 } 190 191 /** 192 * Checks if the user who made the request has a UserSession established 193 * 194 * @param request the HTTPServletRequest object passed in 195 * @return true if the user session has been established, false otherwise 196 */ 197 private boolean isUserSessionEstablished(HttpServletRequest request) { 198 return (request.getSession().getAttribute(KRADConstants.USER_SESSION_KEY) != null); 199 } 200 201 private IdentityService getIdentityService() { 202 if (this.identityService == null) { 203 this.identityService = KimApiServiceLocator.getIdentityService(); 204 } 205 206 return this.identityService; 207 } 208 209 private PermissionService getPermissionService() { 210 if (this.permissionService == null) { 211 this.permissionService = KimApiServiceLocator.getPermissionService(); 212 } 213 214 return this.permissionService; 215 } 216 217 private ConfigurationService getKualiConfigurationService() { 218 if (this.kualiConfigurationService == null) { 219 this.kualiConfigurationService = KRADServiceLocator.getKualiConfigurationService(); 220 } 221 222 return this.kualiConfigurationService; 223 } 224 225 private ParameterService getParameterService() { 226 if (this.parameterService == null) { 227 this.parameterService = CoreFrameworkServiceLocator.getParameterService(); 228 } 229 230 return this.parameterService; 231 } 232}