package com.fr.plugin.xxx.zojj.sso;/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (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.mozilla.org/MPL/ * * Software distributed under the License is distributed on an * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express * or implied. See the License for the specific language governing * rights and limitations under the License. * * * The Original Code is OIOSAML Java Service Provider. * * The Initial Developer of the Original Code is Trifork A/S. Portions * created by Trifork A/S are Copyright (C) 2008 Danish National IT * and Telecom Agency (http://www.itst.dk). All Rights Reserved. * * Contributor(s): * Joakim Recht * Rolf Njor Jensen * Aage Nielsen * */ import com.fr.data.NetworkHelper; import com.fr.decision.authority.data.User; import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider; import com.fr.decision.mobile.terminal.TerminalHandler; import com.fr.decision.webservice.utils.DecisionServiceConstants; import com.fr.decision.webservice.utils.WebServiceUtils; import com.fr.decision.webservice.v10.config.ConfigService; import com.fr.decision.webservice.v10.login.LoginService; import com.fr.decision.webservice.v10.login.TokenResource; import com.fr.decision.webservice.v10.user.UserService; import com.fr.intelli.record.Focus; import com.fr.intelli.record.Original; import com.fr.json.JSONObject; import com.fr.locale.InterProviderFactory; import com.fr.plugin.context.PluginContexts; import com.fr.plugin.xxx.zojj.sso.conf.SsoConfig; import com.fr.plugin.xxx.zojj.sso.util.HttpClient; import com.fr.plugin.xxx.zojj.sso.util.LogUtils; import com.fr.plugin.transform.FunctionRecorder; import com.fr.record.analyzer.EnableMetrics; import com.fr.stable.StringUtils; import com.fr.stable.fun.Authorize; import com.fr.stable.web.Device; import com.fr.web.utils.WebUtils; import javax.servlet.FilterChain; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.net.URLEncoder; import java.util.HashMap; import java.util.Map; /** * @author xxx * @date 2020/11/11 */ @FunctionRecorder @Authorize(callSignKey = Constants.PLUGIN_ID) @EnableMetrics public class LoginFilter extends AbstractGlobalRequestFilterProvider { @Override public String filterName() { return "zojj"; } @Override @Focus(id = Constants.PLUGIN_ID, text = "域单点登录", source = Original.PLUGIN) public String[] urlPatterns() { if (PluginContexts.currentContext().isAvailable()) { String servletPathName = "decision"; try { servletPathName = ConfigService.getInstance().getBasicParam().getServletPathName(); } catch (Exception e) { LogUtils.error(e.getMessage(), e); } return new String[]{ "/" + servletPathName, "/" + servletPathName + "/view/report", "/" + servletPathName + "/view/form", }; } else { return new String[]{"/neverbeused"}; } } @Override public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) { String ticket = req.getParameter("jwt_ticket"); SsoConfig config = SsoConfig.getInstance(); try { if (isAccept(req) || isLogin(req)) { next(req, res, filterChain); return; } if (StringUtils.isNotBlank(ticket)) { if (!config.isAccept()) { setError(res, String.format("单点登录配置未完成")); return; } String user = StringUtils.EMPTY; Map queryParas = new HashMap<>(); queryParas.put("jwt_ticket", ticket); String json = HttpClient.get(config.getValidUrl(), queryParas, new HashMap<>()); LogUtils.debug4plugin("vlalid token url is {} token is {} res is {}", config.getValidUrl(), ticket, json); JSONObject object = new JSONObject(json); boolean valid = object.getBoolean("isvalid"); user = object.getString("user"); user = user.substring(user.lastIndexOf("\\") + 1); if (!valid || StringUtils.isBlank(user)) { setError(res, "单点验证不通过"); return; } if (!checkUser(user)) { setError(res, "user: 【" + user + "】 not exist !"); return; } loginFromToken(req, res, user); } } catch (Exception e) { LogUtils.error(e.getMessage(), e); } String redirect = getUrl(req); LogUtils.debug4plugin("current request {} not login send redirect login", redirect); String sso = config.getSsoUrl(); try { res.sendRedirect(sso + "?redirecturl=" + URLEncoder.encode(redirect, "UTF-8")); } catch (IOException e) { LogUtils.error(e.getMessage(), e); } } private String getUrl(HttpServletRequest req) { String requestURL = req.getRequestURL().toString(); String queryString = req.getQueryString(); if (StringUtils.isNotBlank(queryString)) { requestURL += "?" + queryString; } return requestURL; } private boolean isLogin(HttpServletRequest request) throws Exception { String oldToken = TokenResource.COOKIE.getToken(request); return oldToken != null && checkTokenValid(request, (String) oldToken); } private boolean checkTokenValid(HttpServletRequest req, String token) { try { Device device = NetworkHelper.getDevice(req); LoginService.getInstance().loginStatusValid(token, TerminalHandler.getTerminal(req, device)); return true; } catch (Exception ignore) { } return false; } private boolean isAccept(HttpServletRequest req) { if (req.getRequestURI().endsWith("/view/form") || req.getRequestURI().endsWith("/view/report")) { return StringUtils.isBlank(WebUtils.getHTTPRequestParameter(req, "viewlet")) && StringUtils.isNotBlank(req.getParameter("samlToken")); } return false; } private void next(HttpServletRequest request, HttpServletResponse response, FilterChain chain) { try { chain.doFilter(request, response); } catch (Exception e) { throw new RuntimeException(e); } } private boolean checkUser(String username) { User user = null; try { user = UserService.getInstance().getUserByUserName(username); LogUtils.debug4plugin("get user:" + user); if (user != null) { return true; } } catch (Exception e) { LogUtils.error(e.getMessage(), e); } return false; } private boolean loginFromToken(HttpServletRequest req, HttpServletResponse res, String username) throws Exception { try { if (StringUtils.isNotEmpty(username)) { LogUtils.debug4plugin("current username:" + username); String token = LoginService.getInstance().login(req, res, username); LogUtils.debug4plugin("get login token:" + token); req.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME, token); LogUtils.debug4plugin("username:" + username + "login success"); return true; } else { LogUtils.warn("username is null!"); return false; } } catch (Exception e) { LogUtils.error(e.getMessage(), e); } return false; } private void setError(HttpServletResponse res, String reason) { try { PrintWriter printWriter = WebUtils.createPrintWriter(res); Map map = new HashMap<>(); map.put("result", InterProviderFactory.getProvider().getLocText("Fine-Engine_Error_Page_Result")); map.put("reason", reason); map.put("solution", InterProviderFactory.getProvider().getLocText("Fine-Engine_Please_Contact_Platform_Admin")); String page = WebServiceUtils.parseWebPageResourceSafe("com/fr/web/controller/decision/entrance/resources/unavailable.html", map); printWriter.write(page); printWriter.flush(); printWriter.close(); } catch (Exception e) { LogUtils.error(e.getMessage(), e); } } }