boolean handleLoggedInUser( FilterChain chain, HttpServletRequest httpRequest, HttpServletResponse httpResponse, ServiceAccess serviceAccess, AuthorizationRequestData rdo) throws ServletException, IOException { VOUserDetails userDetails = rdo.getUserDetails(); if (userDetails != null) { httpRequest.getSession().setAttribute(PORTAL_HAS_BEEN_REQUESTED, !rdo.isMarketplace()); // if the user wants to use another organization he must login // again (the service sessions are destroyed as well) // don't let a user with status PASSWORD_MUST_BE_CHANGED see any // site but the one to change the pwd if (!authSettings.isServiceProvider()) { if (userDetails.getStatus() == UserAccountStatus.PASSWORD_MUST_BE_CHANGED && !rdo.isRequestedToChangePwd()) { forwardToPwdPage(userDetails.getUserId(), httpRequest, httpResponse); return true; } } // TODO stavreva: check this again if (authSettings.isServiceProvider() || !rdo.isRequestedToChangePwd()) { long t = System.currentTimeMillis(); if (ADMStringUtils.isBlank(httpRequest.getServletPath()) || httpRequest.getServletPath().startsWith(MenuBean.LINK_DEFAULT)) { String defaultUrl = getDefaultUrl(serviceAccess, rdo, httpRequest); forward(defaultUrl, httpRequest, httpResponse); } if (loginPage.equalsIgnoreCase(httpRequest.getServletPath())) { sendRedirect(httpRequest, httpResponse, MenuBean.LINK_DEFAULT); } if (isPageForbiddenToAccess(httpRequest, rdo, serviceAccess)) { forward(insufficientAuthoritiesUrl, httpRequest, httpResponse); } chain.doFilter(httpRequest, httpResponse); if (logger.isDebugLoggingEnabled()) { logger.logDebug( "URL='" + rdo.getRelativePath() + "' processed in " + (System.currentTimeMillis() - t) + "ms"); } return true; } } return false; }
/** * Validate the LDAP properties by performing a search request. * * @param baseDN the baseDN * @return the read attribute * @throws ValidationException Thrown in case the LDAP access failed or no record was found */ public VOUserDetails validateLdapProperties(VOUserDetails user) throws ValidationException { LdapVOUserDetailsMapper mapper = new LdapVOUserDetailsMapper(user, this.attrMap); VOUserDetails tmpUser = new VOUserDetails(); tmpUser.setAdditionalName(user.getAdditionalName()); tmpUser.setEMail(user.getEMail()); tmpUser.setFirstName(user.getFirstName()); tmpUser.setLastName(user.getLastName()); tmpUser.setLocale(user.getLocale()); try { String dnName = ldapAccess.dnSearch( this.dirProperties, this.baseDN, this.attrMap.get(SettingType.LDAP_ATTR_UID) + "=" + user.getUserId()); if (dnName == null) { // sessionCtx.setRollbackOnly(); ValidationException vf = new ValidationException( ReasonEnum.LDAP_USER_NOT_FOUND, null, new Object[] {user.getUserId()}); logger.logError( Log4jLogger.SYSTEM_LOG, vf, LogMessageIdentifier.ERROR_LDAP_SEARCH_OF_USER_FAILED, user.getUserId()); throw vf; } List<VOUserDetails> result = ldapAccess.search( this.dirProperties, this.baseDN, this.attrMap.get(SettingType.LDAP_ATTR_UID) + "=" + user.getUserId(), mapper, true); int size = result.size(); if (size == 1) { user = result.get(0); if (user.getLocale() != null && !user.getLocale().isEmpty() && user.getLocale().length() > LOCAL_LENGTH) { user.setLocale(user.getLocale().substring(0, LOCAL_LENGTH)); } validateLdapPropertyValue( this.attrMap, SettingType.LDAP_ATTR_ADDITIONAL_NAME, tmpUser.getAdditionalName(), user.getAdditionalName()); validateLdapPropertyValue( this.attrMap, SettingType.LDAP_ATTR_EMAIL, tmpUser.getEMail(), user.getEMail()); validateLdapPropertyValue( this.attrMap, SettingType.LDAP_ATTR_FIRST_NAME, tmpUser.getFirstName(), user.getFirstName()); validateLdapPropertyValue( this.attrMap, SettingType.LDAP_ATTR_LAST_NAME, tmpUser.getLastName(), user.getLastName()); validateLdapPropertyValue( this.attrMap, SettingType.LDAP_ATTR_LOCALE, tmpUser.getLocale(), user.getLocale()); return result.get(0); } else if (size == 0) { // sessionCtx.setRollbackOnly(); ValidationException vf = new ValidationException( ReasonEnum.LDAP_USER_NOT_FOUND, null, new Object[] {user.getUserId()}); logger.logError( Log4jLogger.SYSTEM_LOG, vf, LogMessageIdentifier.ERROR_VALIDATION_PARAMETER_LDAP_FOUND_ERROR, "LDAP User"); throw vf; } else { // sessionCtx.setRollbackOnly(); ValidationException vf = new ValidationException( ReasonEnum.LDAP_USER_NOT_UNIQUE, null, new Object[] {user.getUserId()}); logger.logError( Log4jLogger.SYSTEM_LOG, vf, LogMessageIdentifier.ERROR_VALIDATION_PARAMETER_LDAP_FOUND_ERROR, "LDAP User"); throw vf; } } catch (NameNotFoundException nnfe) { // sessionCtx.setRollbackOnly(); ValidationException vf = new ValidationException( ReasonEnum.LDAP_BASE_DN_INVALID, null, new Object[] {this.baseDN}); logger.logError( Log4jLogger.SYSTEM_LOG, vf, LogMessageIdentifier.ERROR_LDAP_ACCESS_FAILED, nnfe.getMessage()); throw vf; } catch (NamingException e1) { // sessionCtx.setRollbackOnly(); Object[] params = new Object[] {dirProperties.get(Context.PROVIDER_URL), e1.getMessage()}; ValidationException vf = new ValidationException(ReasonEnum.LDAP_CONNECTION_REFUSED, null, params); logger.logError( Log4jLogger.SYSTEM_LOG, vf, LogMessageIdentifier.ERROR_LDAP_SYSTEM_CONNECTION_REFUSED, "LDAPuser"); throw vf; } }
/** * If the user wants to access a service URL we must check if he is logged into the service. * * @return the given HTTP request, a request wrapper which must be used to perform the service * login or null if the caller should continue with the filter chain * @throws IOException * @throws ServletException * @throws DatatypeConfigurationException * @throws SAML2AuthnRequestException * @throws Exception */ private HttpServletRequest processServiceUrl( HttpServletRequest request, HttpServletResponse response, FilterChain chain, String subKey, String contextPath, AuthorizationRequestData rdo) throws ServletException, IOException { HttpSession session = request.getSession(); ServiceAccess serviceAccess = ServiceAccess.getServiceAcccessFor(session); if ("/".equals(contextPath) && !BesServletRequestReader.onlyServiceLogin(session)) { // if the user accesses a subscription from the my subscription list // we check the subscription key map in the session (this causes // some overhead - EJB call - and should NOT be done for every // service request) // preserve mId String mId = (String) session.getAttribute(Constants.REQ_PARAM_MARKETPLACE_ID); SessionListener.cleanup(session); session = request.getSession(); session.setAttribute(Constants.REQ_PARAM_MARKETPLACE_ID, mId); } Map<String, VOSubscription> map = getSubMapFromSession(session); VOSubscription sub = map.get(subKey); VOUserDetails userDetails = (VOUserDetails) session.getAttribute(Constants.SESS_ATTR_USER); if (BesServletRequestReader.onlyServiceLogin(session)) { session.removeAttribute(Constants.SESS_ATTR_ONLY_SERVICE_LOGIN); // at least remove the user details from the session session.removeAttribute(Constants.SESS_ATTR_USER); if (userDetails != null) { session.setAttribute(Constants.REQ_PARAM_LOCALE, userDetails.getLocale()); } } if (userDetails != null && userDetails.getStatus() != UserAccountStatus.PASSWORD_MUST_BE_CHANGED) { // the user is already logged in if (sub == null) { // the user is not logged in the service, we must call the // SSO bridge sub = getSubscription(serviceAccess, subKey); if (sub == null) { UserNotAssignedException e = new UserNotAssignedException(subKey, userDetails.getUserId()); logger.logError( Log4jLogger.SYSTEM_LOG | Log4jLogger.AUDIT_LOG, e, LogMessageIdentifier.ERROR_ACTIVE_SUBSCRIPTION_FOR_CURRENT_USER_FAILED, subKey); setErrorAttributesAndForward( getDefaultUrl(serviceAccess, rdo, request), request, response, e); return null; } else if (sub.getStatus() != SubscriptionStatus.ACTIVE && sub.getStatus() != SubscriptionStatus.PENDING_UPD) { SubscriptionStateException e = new SubscriptionStateException( "Subscription '" + subKey + "' not active or pending update.", Reason.ONLY_ACTIVE); logger.logError( Log4jLogger.SYSTEM_LOG | Log4jLogger.AUDIT_LOG, e, LogMessageIdentifier.ERROR_SUBSCRIPTION_NOT_ACTIVE, subKey); setErrorAttributesAndForward( getDefaultUrl(serviceAccess, rdo, request), request, response, e); return null; } else if (!sub.getServiceBaseURL() .toLowerCase() .startsWith(request.getScheme().toLowerCase() + "://")) { setErrorAttributesAndForward(errorPage, request, response, new ServiceSchemeException()); return null; } String userToken = ADMStringUtils.getRandomString(40); // create a service session database record (which is used by // the service to resolve the user token) try { synchronized (map) { createServiceSession(serviceAccess, subKey, session.getId(), userToken); // the map must be filled after the service session was // created otherwise the session listener cleanup method // might clear the list map.put(subKey, sub); } } catch (ObjectNotFoundException e) { handleSubscriptionNotFound(chain, request, response, rdo); return null; } catch (ServiceParameterException e) { setErrorAttributesAndForward(Constants.SERVICE_USAGE_ERROR_URI, request, response, e); return null; } catch (SaaSApplicationException e) { setErrorAttributesAndForward(errorPage, request, response, e); return null; } if (sub.getServiceAccessType() == ServiceAccessType.LOGIN) { // perform a redirect to the SSO bridge with the user token String url = removeEndingSlash(sub.getServiceBaseURL()); if (sub.getServiceLoginPath() != null) { url += sub.getServiceLoginPath(); } if (url.contains("?")) { url += "&"; } else { url += "?"; } SsoParameters ssoParameters = new SsoParameters(); ssoParameters.setContextPath(contextPath); ssoParameters.setInstanceId(sub.getServiceInstanceId()); ssoParameters.setLanguage(userDetails.getLocale()); ssoParameters.setSubscriptionKey(subKey); ssoParameters.setBssId(request.getSession().getId()); ssoParameters.setUsertoken(userToken); url += ssoParameters.getQueryString(); JSFUtils.sendRedirect(response, url); return null; } } else { if (sub.getServiceAccessType() == ServiceAccessType.LOGIN) { // send a redirect to the service base URL, the service // session should be still active JSFUtils.sendRedirect(response, sub.getServiceBaseURL()); return null; } // nothing to do (the user is logged in the platform and the // service) the rewriting is done by the subsequent filters in // the filter chain which is activated by the caller } } else { // the user is not logged in if (sub == null) { // the user is neither logged in platform nor in the // service, // // The later processing will forward to the service login // page processing. After the login there will be a redirect to // the primarily requested URL which will perform the service // login session.setAttribute(Constants.SESS_ATTR_ONLY_SERVICE_LOGIN, Boolean.TRUE); } else { // the user is logged in the service if (sub.getServiceAccessType() == ServiceAccessType.LOGIN) { // send a redirect to the service base URL, the service // session should be still active JSFUtils.sendRedirect(response, sub.getServiceBaseURL()); } else { // don't perform any other checks continue with the // filter chain which will perform the rewriting chain.doFilter(request, response); } return null; } } return request; }