/* * Copyright (c) 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.identity.entitlement.filter; import org.apache.axiom.util.base64.Base64Utils; import org.apache.axis2.AxisFault; import org.apache.axis2.client.Options; import org.apache.axis2.client.ServiceClient; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.context.ConfigurationContextFactory; import org.apache.axis2.transport.http.HTTPConstants; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.authenticator.stub.AuthenticationAdminStub; import org.wso2.carbon.authenticator.stub.LoginAuthenticationExceptionException; import org.wso2.carbon.identity.entitlement.filter.exception.EntitlementCacheUpdateServletDataHolder; import org.wso2.carbon.identity.entitlement.filter.exception.EntitlementCacheUpdateServletException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletConfig; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.util.NoSuchElementException; import java.util.Scanner; public class EntitlementCacheUpdateServlet extends HttpServlet { private static final Log log = LogFactory.getLog(EntitlementCacheUpdateServlet.class); private static final String USERNAME_STRING = "username"; private static final String PSWD_STRING = "password"; private static final String NULL_STRING = "null"; private static final String ADMIN = "AuthenticationAdmin"; private static final String UPDATE_CACHE = "/updateCacheAuth.do"; private static final String SUBJECT_SCOPE = "subjectScope"; private static final String UPDATE_CACHE_HTML = "/updateCache.html"; @Override public void init(ServletConfig config) throws EntitlementCacheUpdateServletException { EntitlementCacheUpdateServletDataHolder.getInstance().setServletConfig(config); try { EntitlementCacheUpdateServletDataHolder.getInstance().setConfigCtx(ConfigurationContextFactory .createConfigurationContextFromFileSystem(null, null)); } catch (AxisFault e) { log.error("Error while initializing Configuration Context", e); throw new EntitlementCacheUpdateServletException("Error while initializing Configuration Context", e); } EntitlementCacheUpdateServletDataHolder.getInstance().setHttpsPort(config.getInitParameter(EntitlementConstants.HTTPS_PORT)); EntitlementCacheUpdateServletDataHolder.getInstance().setAuthentication(config.getInitParameter(EntitlementConstants.AUTHENTICATION)); EntitlementCacheUpdateServletDataHolder.getInstance().setRemoteServiceUrl(config.getServletContext().getInitParameter(EntitlementConstants.REMOTE_SERVICE_URL)); EntitlementCacheUpdateServletDataHolder.getInstance().setRemoteServiceUserName(config.getServletContext().getInitParameter(EntitlementConstants.USERNAME)); EntitlementCacheUpdateServletDataHolder.getInstance().setRemoteServicePassword(config.getServletContext().getInitParameter(EntitlementConstants.PASSWORD)); EntitlementCacheUpdateServletDataHolder.getInstance().setAuthenticationPage(config.getInitParameter(EntitlementConstants.AUTHENTICATION_PAGE)); EntitlementCacheUpdateServletDataHolder.getInstance().setAuthenticationPageURL(config.getInitParameter(EntitlementConstants.AUTHENTICATION_PAGE_URL)); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws EntitlementCacheUpdateServletException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws EntitlementCacheUpdateServletException { if (!req.isSecure()) { redirectToHTTPS(req, resp); } else if (req.getParameter(USERNAME_STRING) != null && req.getParameter(PSWD_STRING) != null && !NULL_STRING.equals(req.getParameter(USERNAME_STRING)) && !NULL_STRING.equals(req.getParameter(PSWD_STRING) )) { doAuthentication(req, resp); } else { if (req.getParameter(USERNAME_STRING) == null) { log.info("\'username\' parameter not available in request. Redirecting to " + EntitlementCacheUpdateServletDataHolder.getInstance().getAuthenticationPageURL()); } if (req.getParameter(PSWD_STRING) == null) { log.info("\'password\' parameter not available in request. Redirecting to " + EntitlementCacheUpdateServletDataHolder.getInstance().getAuthenticationPageURL()); } if (req.getParameter(USERNAME_STRING) != null && NULL_STRING.equals(req.getParameter(USERNAME_STRING))) { log.info("\'username\' is empty in request. Redirecting to " + EntitlementCacheUpdateServletDataHolder .getInstance().getAuthenticationPageURL()); } if (req.getParameter(PSWD_STRING) != null && NULL_STRING.equals(req.getParameter(PSWD_STRING))) { log.info("\'password\' is empty in request. Redirecting to " + EntitlementCacheUpdateServletDataHolder.getInstance().getAuthenticationPageURL()); } showAuthPage(req, resp); } } private boolean authenticate(String userName, String password, String remoteIp) throws EntitlementCacheUpdateServletException { boolean isAuthenticated = false; String authentication = EntitlementCacheUpdateServletDataHolder.getInstance().getAuthentication(); String remoteServiceUrl = EntitlementCacheUpdateServletDataHolder.getInstance().getRemoteServiceUrl(); ConfigurationContext configCtx = EntitlementCacheUpdateServletDataHolder.getInstance().getConfigCtx(); String authCookie = EntitlementCacheUpdateServletDataHolder.getInstance().getAuthCookie(); String remoteServiceUserName = EntitlementCacheUpdateServletDataHolder.getInstance().getRemoteServiceUserName(); String remoteServicePassword = EntitlementCacheUpdateServletDataHolder.getInstance().getRemoteServicePassword(); if (authentication.equals(EntitlementConstants.WSO2_IS)) { AuthenticationAdminStub authStub; String authenticationAdminServiceURL = remoteServiceUrl + ADMIN; try { authStub = new AuthenticationAdminStub(configCtx, authenticationAdminServiceURL); ServiceClient client = authStub._getServiceClient(); Options options = client.getOptions(); options.setManageSession(true); options.setProperty(org.apache.axis2.transport.http.HTTPConstants.COOKIE_STRING, authCookie); isAuthenticated = authStub.login(userName, password, remoteIp); EntitlementCacheUpdateServletDataHolder.getInstance().setAuthCookie((String) authStub._getServiceClient() .getServiceContext() .getProperty(HTTPConstants.COOKIE_STRING)); } catch (LoginAuthenticationExceptionException e) { log.info(userName + " not authenticated to perform entitlement query to perform cache update"); if (log.isDebugEnabled()) { log.debug("Login Authentication Exception Occurred ", e); } } catch (Exception e) { throw new EntitlementCacheUpdateServletException("Error while trying to authenticate" + " with AuthenticationAdmin", e); } } else if (authentication.equals(EntitlementConstants.WEB_APP)) { if (userName.equals(remoteServiceUserName) && password.equals(remoteServicePassword)) { isAuthenticated = true; } } else { throw new EntitlementCacheUpdateServletException(authentication + " is an invalid" + " configuration for authentication parameter in web.xml. Valid configurations are" + " \'" + EntitlementConstants.WEB_APP + "\' and \'" + EntitlementConstants.WSO2_IS + "\'"); } return isAuthenticated; } private String convertStreamToString(InputStream is) { try { return new Scanner(is).useDelimiter("\\A").next(); } catch (NoSuchElementException e) { if (log.isDebugEnabled()) { log.debug("No such element: ", e); } return ""; } } private void redirectToHTTPS(HttpServletRequest req, HttpServletResponse resp) throws EntitlementCacheUpdateServletException { String serverName = req.getServerName(); String contextPath = req.getContextPath(); String servletPath = req.getServletPath(); String redirectURL = "https://" + serverName + ":" + EntitlementCacheUpdateServletDataHolder.getInstance().getHttpsPort() + contextPath + servletPath; try { resp.sendRedirect(redirectURL); } catch (IOException e) { log.error("Error while redirecting request to come over HTTPS", e); throw new EntitlementCacheUpdateServletException("Error while redirecting request to come over HTTPS", e); } } private void doAuthentication(HttpServletRequest req, HttpServletResponse resp) throws EntitlementCacheUpdateServletException { String username = req.getParameter(USERNAME_STRING); String password = req.getParameter(PSWD_STRING); String remoteIp = req.getServerName(); if (authenticate(username, password, remoteIp)) { RequestDispatcher requestDispatcher = req.getRequestDispatcher(UPDATE_CACHE); String subjectScope = EntitlementCacheUpdateServletDataHolder.getInstance().getServletConfig().getServletContext() .getInitParameter(SUBJECT_SCOPE); String subjectAttributeName = EntitlementCacheUpdateServletDataHolder.getInstance().getServletConfig().getServletContext() .getInitParameter("subjectAttributeName"); if (subjectScope.equals(EntitlementConstants.REQUEST_PARAM)) { requestDispatcher = req.getRequestDispatcher(UPDATE_CACHE + "?" + subjectAttributeName + "=" + username); } else if (subjectScope.equals(EntitlementConstants.REQUEST_ATTIBUTE)) { req.setAttribute(subjectAttributeName, username); } else if (subjectScope.equals(EntitlementConstants.SESSION)) { req.getSession().setAttribute(subjectAttributeName, username); } else { resp.setHeader("Authorization", Base64Utils.encode((username + ":" + password).getBytes(Charset.forName("UTF-8")))); } try { requestDispatcher.forward(req, resp); } catch (Exception e) { log.error("Error occurred while dispatching request to /updateCacheAuth.do", e); throw new EntitlementCacheUpdateServletException("Error occurred while dispatching request to /updateCacheAuth.do", e); } } else { showAuthPage(req, resp); } } private void showAuthPage(HttpServletRequest req, HttpServletResponse resp) throws EntitlementCacheUpdateServletException { if ("default".equals(EntitlementCacheUpdateServletDataHolder.getInstance().getAuthenticationPage())) { InputStream is = getClass().getResourceAsStream(UPDATE_CACHE_HTML); String updateCache = convertStreamToString(is); try { resp.getWriter().print(updateCache); } catch (IOException e) { log.error("Error occurred while writing /updateCache.html page to OutputStream"); throw new EntitlementCacheUpdateServletException("Error occurred while writing" + " /updateCache.html page to OutputStream" + e); } } else if ("custom".equals(EntitlementCacheUpdateServletDataHolder.getInstance().getAuthenticationPage())) { try { req.getRequestDispatcher(EntitlementCacheUpdateServletDataHolder.getInstance().getAuthenticationPageURL()).forward(req, resp); } catch (Exception e) { log.error("Error occurred while dispatching request to " + EntitlementCacheUpdateServletDataHolder .getInstance().getAuthenticationPageURL(), e); throw new EntitlementCacheUpdateServletException("Error occurred while dispatching" + " request to " + EntitlementCacheUpdateServletDataHolder.getInstance().getAuthenticationPageURL(), e); } } else { throw new EntitlementCacheUpdateServletException(EntitlementCacheUpdateServletDataHolder.getInstance().getAuthenticationPage() + " is an " + "invalid" + " configuration for authenticationPage parameter in web.xml. Valid" + " configurations are 'default' and 'custom'"); } } }