Java tutorial
/* * Copyright (c) 2005-2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except * in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.wso2.carbon.ui; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.osgi.framework.Bundle; import org.osgi.framework.ServiceReference; import org.wso2.carbon.CarbonConstants; import org.wso2.carbon.core.common.AuthenticationException; import org.wso2.carbon.registry.core.Registry; import org.wso2.carbon.ui.deployment.beans.CarbonUIDefinitions; import org.wso2.carbon.ui.deployment.beans.Context; import org.wso2.carbon.ui.internal.CarbonUIServiceComponent; import org.wso2.carbon.utils.multitenancy.MultitenantConstants; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; import java.util.HashMap; import java.util.regex.Matcher; public class CarbonSecuredHttpContext extends SecuredComponentEntryHttpContext { public static final String LOGGED_USER = CarbonConstants.LOGGED_USER; public static final String CARBON_AUTHNETICATOR = "CarbonAuthenticator"; private static final Log log = LogFactory.getLog(CarbonSecuredHttpContext.class); private Bundle bundle = null; private HashMap<String, String> httpUrlsToBeByPassed = new HashMap<String, String>(); private HashMap<String, String> urlsToBeByPassed = new HashMap<String, String>(); private String defaultHomePage; private Context defaultContext; /** * * @param bundle * @param s * @param uiResourceRegistry * @param registry */ public CarbonSecuredHttpContext(Bundle bundle, String s, UIResourceRegistry uiResourceRegistry, Registry registry) { super(bundle, s, uiResourceRegistry); this.registry = registry; this.bundle = bundle; } /** * {@inheritDoc} */ public boolean handleSecurity(HttpServletRequest request, HttpServletResponse response) throws IOException { String requestedURI = request.getRequestURI(); // Get the matching CarbonUIAuthenticator. If no match found for the given request, this // will return null. CarbonUIAuthenticator authenticator = CarbonUILoginUtil.getAuthenticator(request); // This check is required for Single Logout implementation. If the request is not for SSO // based authentication page or SSO Servlet, then if the session is invalid redirect the // requests to logout_action.jsp. CarbonSSOSessionManager ssoSessionManager = CarbonSSOSessionManager.getInstance(); requestedURI = ssoSessionManager.getRequestedUrl(request, authenticator); HttpSession session; String sessionId; boolean authenticated = false; try { // Get the user's current authenticated session - if any exists. session = request.getSession(); sessionId = session.getId(); Boolean authenticatedObj = (Boolean) session.getAttribute("authenticated"); if (authenticatedObj != null) { authenticated = authenticatedObj.booleanValue(); if (log.isDebugEnabled()) { log.debug("Is authenticated " + authenticated); } } } catch (Exception e) { log.debug("No session exits"); return false; } String context = request.getContextPath(); if ("/".equals(context)) { context = ""; } // We eliminate the /tenant/{tenant-domain} from authentications Matcher matcher = CarbonUILoginUtil.getTenantEnabledUriPattern().matcher(requestedURI); if (matcher.matches()) { log.debug("Tenant webapp request " + requestedURI); return CarbonUILoginUtil.escapeTenantWebAppRequests(authenticated, response, requestedURI, context); } // TODO: When filtered from a Servlet filter the request uri always contains 2 //, this is a // temporary fix if (requestedURI.indexOf("//") == 0) { requestedURI = requestedURI.substring(1); } if (httpUrlsToBeByPassed.isEmpty()) { // Populates http urls to be by passed. populatehttpUrlsToBeByPassed(); } if (requestedURI.equals(context) || requestedURI.equals(context + "/")) { return handleRequestOnContext(request, response); } // Storing intermediate value of requestedURI. // This is needed for OpenID authentication later. String tempUrl = requestedURI; // When war is deployed on top of an existing app server we cannot use root context // for deployment. Hence a new context is added.Now url changes from eg: // carbon/admin/index.jsp to wso2/carbon/admin/index.jsp In this case before doing anything, // we need to remove web app context (eg: wso2) . CarbonUILoginUtil.addNewContext(requestedURI); // Disabling http access to admin console user guide documents should be allowed to access // via http protocol int val = -1; if ((val = allowNonSecuredContent(requestedURI, request, response, authenticated, authenticator)) != CarbonUILoginUtil.CONTINUE) { if (val == CarbonUILoginUtil.RETURN_TRUE) { log.debug("Skipping security check for non secured content. " + requestedURI); return true; } else { log.debug("Security check failed for the resource " + requestedURI); return false; } } // We are allowing requests for .jar/.class resources. Otherwise applets won't get loaded // due to session checks. (applet loading happens over https://) if (requestedURI.endsWith(".jar") || requestedURI.endsWith(".class")) { log.debug("Skipping authentication for .jar files and .class file." + requestedURI); return true; } String resourceURI = requestedURI.replaceFirst("/carbon/", "../"); if (log.isDebugEnabled()) { log.debug("CarbonSecuredHttpContext -> handleSecurity() requestURI:" + requestedURI + " id:" + sessionId + " resourceURI:" + resourceURI); } if (urlsToBeByPassed.isEmpty()) { // retrieve urls that should be by-passed from security check populateUrlsToBeBypassed(); } // if the current uri is marked to be by-passed, let it pass through if (isCurrentUrlToBePassed(request, session, resourceURI)) { return true; } String indexPageURL = CarbonUIUtil.getIndexPageURL(session.getServletContext(), request.getSession()); // Reading the requestedURL from the cookie to obtain the request made while not // authanticated; and setting it as the indexPageURL indexPageURL = CarbonUILoginUtil.getIndexPageUrlFromCookie(requestedURI, indexPageURL, request); // If a custom index page is used send the login request with the indexpage specified indexPageURL = CarbonUILoginUtil.getCustomIndexPage(request, indexPageURL); // Reading home page set on product.xml // If the params in the servletcontext is null get them from the UTIL indexPageURL = updateIndexPageWithHomePage(indexPageURL); if ((val = CarbonUILoginUtil.handleLoginPageRequest(requestedURI, request, response, authenticated, context, indexPageURL)) != CarbonUILoginUtil.CONTINUE) { if (val == CarbonUILoginUtil.RETURN_TRUE) { return true; } else { return false; } } // If authenticator defines to skip URL, return true if (ssoSessionManager.skipAuthentication(request)) { if (log.isDebugEnabled()) { log.debug("Skipping security checks for authenticator defined URL " + requestedURI); } return true; } // If someone signed in from a tenant, try to access a different tenant domain, he should be // forced to sign out without any prompt Cloud requirement requestedURI = CarbonUILoginUtil.getForcedSignOutRequestedURI(requestedURI, request); String contextPath = (request.getContextPath().equals("") || request.getContextPath().equals("/")) ? "" : request.getContextPath(); String tenantDomain = (String) session.getAttribute(MultitenantConstants.TENANT_DOMAIN); if (tenantDomain != null && !tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) { contextPath += "/" + MultitenantConstants.TENANT_AWARE_URL_PREFIX + "/" + tenantDomain; } String httpLogin = request.getParameter("gsHttpRequest"); boolean skipLoginPage = false; // Login page is not required for all the Authenticators. if (authenticator != null && authenticator.skipLoginPage() && requestedURI.indexOf("login_action.jsp") < 0 && (requestedURI.endsWith("/carbon/") || (requestedURI.indexOf("/registry/atom") == -1 && requestedURI.endsWith("/carbon")))) { // Add this to session for future use. request.getSession().setAttribute("skipLoginPage", "true"); } if (request.getSession().getAttribute("skipLoginPage") != null) { if ("true".equals(((String) request.getSession().getAttribute("skipLoginPage")))) { skipLoginPage = true; } } if (requestedURI.indexOf("login_action.jsp") > -1 && authenticator != null) { return CarbonUILoginUtil.handleLogin(authenticator, request, response, session, authenticated, contextPath, indexPageURL, httpLogin); } else if (requestedURI.indexOf("logout_action.jsp") > 1) { return CarbonUILoginUtil.handleLogout(authenticator, request, response, session, authenticated, contextPath, indexPageURL, httpLogin); } if (requestedURI.endsWith("/carbon/")) { if (skipLoginPage) { response.sendRedirect(contextPath + indexPageURL + "?skipLoginPage=true"); } else { response.sendRedirect(contextPath + indexPageURL); } return false; } else if (requestedURI.indexOf("/registry/atom") == -1 && requestedURI.endsWith("/carbon")) { if (skipLoginPage) { response.sendRedirect(contextPath + indexPageURL + "?skipLoginPage=true"); } else { response.sendRedirect(contextPath + indexPageURL); } return false; } else if (CarbonUILoginUtil.letRequestedUrlIn(requestedURI, tempUrl)) { return true; } else if (requestedURI.endsWith(".jsp") && authenticated) { return true; } if (!authenticated) { if (requestedURI.endsWith("ajaxprocessor.jsp")) { // Prevent login page appearing return true; } else { return CarbonUILoginUtil.saveOriginalUrl(authenticator, request, response, session, skipLoginPage, contextPath, indexPageURL, requestedURI); } } if (request.getSession().isNew()) { if (skipLoginPage) { response.sendRedirect(contextPath + "/carbon/admin/login_action.jsp"); } else { response.sendRedirect(contextPath + "/carbon/admin/login.jsp"); } return false; } return true; } /** * * @param indexPageURL * @return */ private String updateIndexPageWithHomePage(String indexPageURL) { // If the params in the servletcontext is null get them from the UTIL if (defaultHomePage == null) { defaultHomePage = (String) CarbonUIUtil .getProductParam(CarbonConstants.PRODUCT_XML_WSO2CARBON + CarbonConstants.DEFAULT_HOME_PAGE); } if (defaultHomePage != null && defaultHomePage.trim().length() > 0 && indexPageURL.contains("/carbon/admin/index.jsp")) { indexPageURL = defaultHomePage; if (!indexPageURL.startsWith("/")) { indexPageURL = "/" + indexPageURL; } } return indexPageURL; } /** * * @param request * @param session * @param resourceURI * @return */ private boolean isCurrentUrlToBePassed(HttpServletRequest request, HttpSession session, String resourceURI) { if (!urlsToBeByPassed.isEmpty() && urlsToBeByPassed.containsKey(resourceURI)) { if (log.isDebugEnabled()) { log.debug("By passing authentication check for URI : " + resourceURI); } // Before bypassing, set the backendURL properly so that it doesn't fail String contextPath = request.getContextPath(); String backendServerURL = request.getParameter("backendURL"); if (backendServerURL == null) { backendServerURL = CarbonUIUtil.getServerURL(session.getServletContext(), request.getSession()); } if ("/".equals(contextPath)) { contextPath = ""; } backendServerURL = backendServerURL.replace("${carbon.context}", contextPath); session.setAttribute(CarbonConstants.SERVER_URL, backendServerURL); return true; } return false; } /** * */ @SuppressWarnings({ "unchecked", "rawtypes" }) private void populateUrlsToBeBypassed() { if (bundle != null && urlsToBeByPassed.isEmpty()) { ServiceReference reference = bundle.getBundleContext() .getServiceReference(CarbonUIDefinitions.class.getName()); CarbonUIDefinitions carbonUIDefinitions; if (reference != null) { carbonUIDefinitions = (CarbonUIDefinitions) bundle.getBundleContext().getService(reference); if (carbonUIDefinitions != null) { urlsToBeByPassed = carbonUIDefinitions.getUnauthenticatedUrls(); } } } } /** * * @param requestedURI * @param request * @param response * @param authenticated * @param authenticator * @return * @throws IOException */ @SuppressWarnings("deprecation") private int allowNonSecuredContent(String requestedURI, HttpServletRequest request, HttpServletResponse response, boolean authenticated, CarbonUIAuthenticator authenticator) throws IOException { if (!request.isSecure() && !(requestedURI.endsWith(".html"))) { // By passing items required for try-it & IDE plugins if (requestedURI.endsWith(".css") || requestedURI.endsWith(".gif") || requestedURI.endsWith(".GIF") || requestedURI.endsWith(".jpg") || requestedURI.endsWith(".JPG") || requestedURI.endsWith(".png") || requestedURI.endsWith(".PNG") || requestedURI.endsWith(".xsl") || requestedURI.endsWith(".xslt") || requestedURI.endsWith(".js") || requestedURI.endsWith(".ico") || requestedURI.endsWith("/filedownload") || requestedURI.endsWith("/fileupload") || requestedURI.contains("/fileupload/") || requestedURI.contains("admin/jsp/WSRequestXSSproxy_ajaxprocessor.jsp") || requestedURI.contains("registry/atom") || requestedURI.contains("registry/tags") || requestedURI.contains("gadgets/") || requestedURI.contains("registry/resource")) { return CarbonUILoginUtil.RETURN_TRUE; } String resourceURI = requestedURI.replaceFirst("/carbon/", "../"); // By passing the pages which are specified as bypass https if (httpUrlsToBeByPassed.containsKey(resourceURI)) { if (!authenticated) { try { Cookie[] cookies = request.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { if (cookie.getName().equals(CarbonConstants.REMEMBER_ME_COOKE_NAME) && authenticator != null) { try { authenticator.authenticateWithCookie(request); } catch (AuthenticationException ignored) { // We can ignore here and proceed with normal login. if (log.isDebugEnabled()) { log.debug(ignored); } } } } } } catch (Exception e) { log.error(e.getMessage(), e); throw new IOException(e.getMessage(), e); } } return CarbonUILoginUtil.RETURN_TRUE; } String enableHTTPAdminConsole = CarbonUIServiceComponent.getServerConfiguration() .getFirstProperty(CarbonConstants.ENABLE_HTTP_ADMIN_CONSOLE); if (enableHTTPAdminConsole == null || "false".equalsIgnoreCase(enableHTTPAdminConsole.trim())) { String adminConsoleURL = CarbonUIUtil.getAdminConsoleURL(request); if (adminConsoleURL != null) { if (log.isTraceEnabled()) { log.trace("Request came to admin console via http.Forwarding to : " + adminConsoleURL); } response.sendRedirect(adminConsoleURL); return CarbonUILoginUtil.RETURN_FALSE; } } } return CarbonUILoginUtil.CONTINUE; } /** * * @param request * @param response * @return * @throws IOException */ private boolean handleRequestOnContext(HttpServletRequest request, HttpServletResponse response) throws IOException { log.debug("Handling request on context"); if (defaultContext != null && !"".equals(defaultContext.getContextName()) && !"null".equals(defaultContext.getContextName())) { String adminConsoleURL = CarbonUIUtil.getAdminConsoleURL(request); int index = adminConsoleURL.lastIndexOf("carbon"); String defaultContextUrl = adminConsoleURL.substring(0, index) + defaultContext.getContextName() + "/"; response.sendRedirect(defaultContextUrl); } else { response.sendRedirect("carbon"); } return false; } /** * */ @SuppressWarnings("unchecked") private void populatehttpUrlsToBeByPassed() { if (bundle != null && httpUrlsToBeByPassed.isEmpty() && defaultContext == null) { @SuppressWarnings("rawtypes") ServiceReference reference = bundle.getBundleContext() .getServiceReference(CarbonUIDefinitions.class.getName()); CarbonUIDefinitions carbonUIDefinitions; if (reference != null) { carbonUIDefinitions = (CarbonUIDefinitions) bundle.getBundleContext().getService(reference); if (carbonUIDefinitions != null) { httpUrlsToBeByPassed = carbonUIDefinitions.getHttpUrls(); if (carbonUIDefinitions.getContexts().containsKey("default-context")) { defaultContext = carbonUIDefinitions.getContexts().get("default-context"); } } } } } }