/* * © Copyright IBM Corp. 2013 * * Licensed 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 com.ibm.sbt.service.core.handlers; import java.io.IOException; import java.io.PrintWriter; import java.net.URLDecoder; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.ibm.commons.Platform; import com.ibm.commons.runtime.Context; import com.ibm.commons.util.PathUtil; import com.ibm.commons.util.StringUtil; import com.ibm.sbt.security.authentication.AuthenticationException; import com.ibm.sbt.services.endpoints.BasicEndpoint; import com.ibm.sbt.services.endpoints.Endpoint; import com.ibm.sbt.services.endpoints.EndpointFactory; import com.ibm.sbt.services.endpoints.FormEndpoint; public class AuthCredsHandler extends AbstractServiceHandler { private static final long serialVersionUID = 1L; public static final String URL_PATH = "basicAuth"; public static final String MODE_MAINWINDOW = "mainWindow"; public static final String MODE_POPUP = "popup"; public static final String AUTH_ACCEPTED = "accepted"; public static final String AUTH_DECLINED = "declined"; public static final String USER_NAME = "username"; public static final String PASSWORD = "password"; public static final String LOGIN_UI = "loginUi"; public static final String REDIRECT_URL = "redirectURL"; public static final String ENDPOINT_ALIAS = "endpointAlias"; public static final String REDIRECT_URL_TO_LOGIN = "redirectURLToLogin"; public static final String ENDPOINT_NAME = "endPointName"; public static final String JS_APP = "JSApp"; public static final String JAVA_APP = "JavaApp"; @Override public void service(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { String pathInfo = request.getPathInfo(); Endpoint endpoint = EndpointFactory.getEndpoint(getEndpointName(pathInfo)); //remove hardcoded name ..get second token from path info BasicEndpoint basicendpoint = null; if(endpoint instanceof BasicEndpoint ) { basicendpoint = (BasicEndpoint)endpoint; String user = request.getParameter(USER_NAME); String pswd = request.getParameter(PASSWORD); //test if auth info is okay ...we need to check if user/password are valid. try { if(basicendpoint.login(user, pswd, false)) { basicendpoint.setUser(user); basicendpoint.setPassword(pswd); basicendpoint.writeToStore(); if(getCallerType(pathInfo).equals(JS_APP)){ generateCloseScript(request, response, AUTH_ACCEPTED); }else if(getCallerType(pathInfo).equals(JAVA_APP)){ redirectToJavaApp(request, response, AUTH_ACCEPTED ); } }else{ response.setStatus(401); if(getCallerType(pathInfo).equals(JS_APP)){ generateCloseScript(request, response, AUTH_DECLINED); }else if(getCallerType(pathInfo).equals(JAVA_APP)){ redirectToJavaApp(request, response, AUTH_DECLINED); } } } catch (AuthenticationException e) { Platform.getInstance().log("PasswordException in BasicAuthCredsHandler"+e); } }else if(endpoint instanceof FormEndpoint){ String user = request.getParameter(USER_NAME); String pswd = request.getParameter(PASSWORD); FormEndpoint scendpoint = (FormEndpoint)endpoint; try { if(scendpoint.login(user, pswd)) { scendpoint.setUser(user); scendpoint.setPassword(pswd); if(getCallerType(pathInfo).equals(JS_APP)){ generateCloseScript(request, response, AUTH_ACCEPTED); }else if(getCallerType(pathInfo).equals(JAVA_APP)){ redirectToJavaApp(request, response, AUTH_ACCEPTED ); } }else{ response.setStatus(401); if(getCallerType(pathInfo).equals(JS_APP)){ generateCloseScript(request, response, AUTH_DECLINED); }else if(getCallerType(pathInfo).equals(JAVA_APP)){ redirectToJavaApp(request, response, AUTH_DECLINED); } } } catch (AuthenticationException e) { Platform.getInstance().log("PasswordException in BasicAuthCredsHandler"+e); } } } public String getCallerType(String pathInfo){//returns string JSApp or JavaApp String callerType = ""; if(pathInfo != null){ String[] tokens = pathInfo.split("/"); if(tokens.length > 3){ callerType = tokens[3]; } } return callerType; } public String getEndpointName(String pathInfo){ String endPointName = ""; if(pathInfo != null){ String[] tokens = pathInfo.split("/"); if(tokens.length > 2){ endPointName = tokens[2]; } } return endPointName; } protected void redirectToJavaApp(HttpServletRequest req, HttpServletResponse resp, String authentication) throws ServletException, IOException { Context context = Context.get(); String url = (String)req.getParameter(REDIRECT_URL); if(authentication.equals(AUTH_DECLINED)){ if(url != null){ if(url.indexOf("showWrongCredsMessage=true") == -1){// don't add again if wrongCreds parameter is already added for declined Authentication if(url.indexOf('?')!= -1) url = PathUtil.concat(url,"showWrongCredsMessage=true", '&'); else url = PathUtil.concat(url,"showWrongCredsMessage=true", '?'); } } } context.sendRedirect(url); } protected void generateCloseScript(HttpServletRequest req, HttpServletResponse resp, String authentication) throws ServletException, IOException { String pathInfo = req.getPathInfo(); String mode = req.getParameter(LOGIN_UI); if(mode != null){ //mode is null for dojo dialog LOGIN_UI. No action required in that case. String redirectToLogin = req.getParameter(REDIRECT_URL_TO_LOGIN); PrintWriter pw = resp.getWriter(); try { pw.println("<html>"); pw.println("<head>"); pw.println("</head>"); pw.println("<body>"); pw.println("<script>"); if(StringUtil.isEmpty(mode) || mode.equalsIgnoreCase(MODE_MAINWINDOW)) {//MainWindow mode String redirectURL = URLDecoder.decode(req.getParameter(REDIRECT_URL),"utf-8"); if(authentication.equals(AUTH_DECLINED)){ pw.println("window.location.href = '"+redirectToLogin+"&redirectURL="+redirectURL+"&loginUi="+mode+"&showWrongCredsMessage=true'"); }else if(authentication.equals(AUTH_ACCEPTED)){ pw.println(" window.location.href = '"+redirectURL+"';"); } } else if(mode.equalsIgnoreCase(MODE_POPUP)) {//Popup Mode pw.println(" if (window.opener && !window.opener.closed) {"); pw.println("window.opener.require(['sbt/config'], function(config){"); if(authentication.equals(AUTH_DECLINED)){ pw.println("window.location.href = '"+redirectToLogin+"&redirectURL=empty&loginUi="+mode+"&showWrongCredsMessage=true'"); }else if(authentication.equals(AUTH_ACCEPTED)){ String endpointAlias = URLDecoder.decode(req.getParameter(ENDPOINT_ALIAS),"utf-8"); pw.println("config.findEndpoint('"+ endpointAlias + "').isAuthenticated = true;"); pw.println("if(config.callback){"); pw.println("config.callback();"); pw.println("delete config.callback;"); pw.println("}"); pw.println("delete window.opener.globalLoginFormStrings;"); pw.println("delete window.opener.globalEndpointAlias;"); pw.println("window.close();"); } pw.println("});"); pw.println("}"); } else { throw new ServletException(StringUtil.format("Invalid mode {0}", mode)); } pw.println("</script>"); pw.println("</body>"); pw.println("</html>"); } finally { pw.flush(); } } } }