pioneer
2 years ago
commit
ba3a72d86c
14 changed files with 691 additions and 0 deletions
@ -0,0 +1,6 @@ |
|||||||
|
# open-JSD-10171 |
||||||
|
|
||||||
|
JSD-10171 单点和模板权限校验\ |
||||||
|
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ |
||||||
|
仅作为开发者学习参考使用!禁止用于任何商业用途!\ |
||||||
|
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系【pioneer】处理。 |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,5 @@ |
|||||||
|
loginUrl=http://xx:7001/sso-server/login |
||||||
|
validateUrl=http://xx:7001/sso-server/serviceValidate |
||||||
|
serverName=xx |
||||||
|
remoteChain=true |
||||||
|
mobileChain=false |
Binary file not shown.
@ -0,0 +1,21 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
||||||
|
<plugin> |
||||||
|
<id>com.fr.plugin.fg</id> |
||||||
|
<name><![CDATA[ xx权限集成 ]]></name> |
||||||
|
<active>yes</active> |
||||||
|
<version>1.9.4</version> |
||||||
|
<env-version>10.0~11.0</env-version> |
||||||
|
<vendor>fr.open</vendor> |
||||||
|
<jartime>2018-07-03</jartime> |
||||||
|
<description><![CDATA[xx权限集成]]></description> |
||||||
|
<change-notes><![CDATA[ |
||||||
|
<p>[2022-06-10]1.9.4:修复定时调度启动入参不为空</p> |
||||||
|
<p>[2020-12-11]新增导出请求放行,可配置放行url</p> |
||||||
|
<p>兼容FR和BI模板预览地址权限过滤</p> |
||||||
|
]]></change-notes> |
||||||
|
<main-package>com.fr.plugin.fg.auth</main-package> |
||||||
|
<function-recorder class="com.fr.plugin.fg.auth.filter.CheckTempleteAuth"/> |
||||||
|
<extra-decision> |
||||||
|
<GlobalRequestFilterProvider class="com.fr.plugin.fg.auth.filter.CheckTempleteAuth"/> |
||||||
|
</extra-decision> |
||||||
|
</plugin> |
@ -0,0 +1,53 @@ |
|||||||
|
package com.fr.plugin.fg.auth; |
||||||
|
|
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.ytec.authAPI.interFace.AuthIF; |
||||||
|
import com.ytec.authAPI.interFace.bean.AuthObjDtl; |
||||||
|
|
||||||
|
import java.util.*; |
||||||
|
|
||||||
|
public class FGAuthApi { |
||||||
|
|
||||||
|
private static final String DMNS_TYPE_ALL = "d_pf_all"; |
||||||
|
|
||||||
|
public static Map<String, Map<String, Set<String>>> tempAuth = null; |
||||||
|
|
||||||
|
static { |
||||||
|
FineLoggerFactory.getLogger().info("FGAuth:报表工程启动,开始获取模板权限"); |
||||||
|
updateTempAuth(); |
||||||
|
} |
||||||
|
|
||||||
|
public static boolean updateTempAuth(){ |
||||||
|
Map<String, Map<String, Set<String>>> menuAuthMap = new HashMap<String, Map<String, Set<String>>>(); |
||||||
|
try { |
||||||
|
AuthIF authIF_ = AuthIF.getInstance(); |
||||||
|
List<AuthObjDtl> objList = authIF_.getAuthedDmnsVlByDmnsTyp(DMNS_TYPE_ALL);//AuthObjDtl为权限详细
|
||||||
|
if (objList.size() > 0) { |
||||||
|
for (AuthObjDtl authObj : objList) { |
||||||
|
Set<String> objIDList = menuAuthMap.get(authObj.getDmnsDtl().getDmnsVlCd()) == null ? null: |
||||||
|
menuAuthMap.get(authObj.getDmnsDtl().getDmnsVlCd()).get(authObj.getObjTyp());//authObj.getDmnsDtl()为维度值详细,包括报表ID和报表名称
|
||||||
|
if (objIDList == null) { |
||||||
|
Map<String, Set<String>> objAuthMap = new HashMap<String, Set<String>>(); |
||||||
|
objAuthMap.put(AuthObjDtl.OBJ_TYP_ROLE, new HashSet<String>()); // role
|
||||||
|
objAuthMap.put(AuthObjDtl.OBJ_TYP_USR, new HashSet<String>()); // usr
|
||||||
|
menuAuthMap.put(authObj.getDmnsDtl().getDmnsVlCd(), objAuthMap); |
||||||
|
objIDList = objAuthMap.get(authObj.getObjTyp());//authObj.getObjTyp()为授权对象类型,包括role和usr两种类型,平台可以针对用户或者角色进行权限设置
|
||||||
|
} |
||||||
|
objIDList.add(authObj.getObjId());//authObj.getObjId()既对应的授权对象ID,根据对象类型,是用户ID或者角色ID
|
||||||
|
} |
||||||
|
//objAuthMap_ = menuAuthMap;
|
||||||
|
} else { |
||||||
|
FineLoggerFactory.getLogger().error("FGAuth:从权限API取得菜单权限失败"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
//lastUpdateTime_ = typeInfo.getLatestUpdateTime();
|
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error("FGAuth:从权限API更新·权限设置失败", e); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
FineLoggerFactory.getLogger().info("FGAuth:读取到的模板权限为 " + menuAuthMap); |
||||||
|
tempAuth = menuAuthMap; |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,17 @@ |
|||||||
|
package com.fr.plugin.fg.auth; |
||||||
|
|
||||||
|
import com.fr.cluster.core.ClusterNode; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.scheduler.job.FineScheduleJob; |
||||||
|
import com.fr.third.v2.org.quartz.JobExecutionContext; |
||||||
|
|
||||||
|
public class TempAuthSyncJob extends FineScheduleJob { |
||||||
|
@Override |
||||||
|
public void run(JobExecutionContext jobExecutionContext, ClusterNode clusterNode){ |
||||||
|
if (FGAuthApi.updateTempAuth()) { |
||||||
|
FineLoggerFactory.getLogger().info("FGAuth:定时任务更新完成······"); |
||||||
|
} else { |
||||||
|
FineLoggerFactory.getLogger().info("FGAuth:定时任务更新失败······"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,44 @@ |
|||||||
|
package com.fr.plugin.fg.auth; |
||||||
|
|
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.scheduler.QuartzContext; |
||||||
|
import com.fr.scheduler.ScheduleJobManager; |
||||||
|
import com.fr.third.v2.org.quartz.JobKey; |
||||||
|
import com.fr.third.v2.org.quartz.SimpleScheduleBuilder; |
||||||
|
import com.fr.third.v2.org.quartz.TriggerBuilder; |
||||||
|
|
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
public class TempAuthSyncSchedule { |
||||||
|
|
||||||
|
private static Long syncTime = 10000L; |
||||||
|
private static String scheduleName = "FGTempAuthSync"; |
||||||
|
|
||||||
|
public static void startSchedule(String jobName, String jobGroup, Map<String, Object> parameters) throws Exception { |
||||||
|
JobKey jobKey = new JobKey(jobName, jobGroup); |
||||||
|
if (QuartzContext.getInstance().getScheduler().checkExists(jobKey)) { |
||||||
|
ScheduleJobManager.getInstance().removeJob(jobKey.getName(), jobKey.getGroup()); |
||||||
|
} |
||||||
|
|
||||||
|
TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger(); |
||||||
|
triggerBuilder.forJob(jobKey.getName(), jobKey.getGroup()) |
||||||
|
.withIdentity(jobKey.getName(), jobKey.getGroup()) |
||||||
|
.startNow(); |
||||||
|
|
||||||
|
SimpleScheduleBuilder schedule = SimpleScheduleBuilder.simpleSchedule(); |
||||||
|
schedule.withMisfireHandlingInstructionNextWithExistingCount(); |
||||||
|
schedule.withIntervalInMilliseconds(syncTime); |
||||||
|
schedule.repeatForever(); |
||||||
|
triggerBuilder.withSchedule(schedule); |
||||||
|
|
||||||
|
ScheduleJobManager.getInstance().addJob( |
||||||
|
jobKey.getName(), |
||||||
|
jobKey.getGroup(), |
||||||
|
scheduleName, |
||||||
|
TempAuthSyncJob.class, |
||||||
|
triggerBuilder.build(), |
||||||
|
parameters); |
||||||
|
|
||||||
|
FineLoggerFactory.getLogger().info("FGAuth:定时任务已启动完成,执行频率为 " + syncTime/1000 + "秒"); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,202 @@ |
|||||||
|
package com.fr.plugin.fg.auth.filter; |
||||||
|
|
||||||
|
import com.fr.data.NetworkHelper; |
||||||
|
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider; |
||||||
|
import com.fr.io.utils.ResourceIOUtils; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.web.utils.WebUtils; |
||||||
|
import edu.yale.its.tp.cas.client.ProxyTicketValidator; |
||||||
|
import edu.yale.its.tp.cas.client.Util; |
||||||
|
import edu.yale.its.tp.cas.client.filter.CASFilterRequestWrapper; |
||||||
|
import org.xml.sax.SAXException; |
||||||
|
|
||||||
|
import javax.servlet.FilterChain; |
||||||
|
import javax.servlet.FilterConfig; |
||||||
|
import javax.servlet.ServletException; |
||||||
|
import javax.servlet.ServletRequest; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import javax.servlet.http.HttpServletResponse; |
||||||
|
import javax.servlet.http.HttpSession; |
||||||
|
import javax.xml.parsers.ParserConfigurationException; |
||||||
|
import java.io.IOException; |
||||||
|
import java.net.URLEncoder; |
||||||
|
import java.util.Properties; |
||||||
|
import java.util.StringTokenizer; |
||||||
|
|
||||||
|
public class CasYaleFilter extends AbstractGlobalRequestFilterProvider { |
||||||
|
|
||||||
|
public static final String CAS_FILTER_USER = "edu.yale.its.tp.cas.client.filter.user"; |
||||||
|
public static String IGNORE_URL; |
||||||
|
private String casLogin; |
||||||
|
private String casValidate; |
||||||
|
private String casAuthorizedProxy; |
||||||
|
private String casServiceUrl; |
||||||
|
private String casRenew; |
||||||
|
private String casServerName; |
||||||
|
private boolean wrapRequest; |
||||||
|
|
||||||
|
private Properties properties = new Properties(); |
||||||
|
|
||||||
|
@Override |
||||||
|
public String filterName() { |
||||||
|
return "cas"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String[] urlPatterns() { |
||||||
|
return new String[]{ "/*"}; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void init(FilterConfig filterConfig) { |
||||||
|
try { |
||||||
|
properties.load(ResourceIOUtils.read("/resources/fgAuth.properties")); |
||||||
|
} catch (IOException e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getLocalizedMessage(), e); |
||||||
|
} |
||||||
|
this.casLogin = properties.getProperty("loginUrl"); |
||||||
|
this.casValidate = properties.getProperty("validateUrl"); |
||||||
|
|
||||||
|
this.casServerName = properties.getProperty("serverName"); |
||||||
|
|
||||||
|
this.IGNORE_URL = properties.getProperty("ignoreUrl"); // 逗号分隔
|
||||||
|
FineLoggerFactory.getLogger().debug("IGNORE_URL: {}", IGNORE_URL); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) { |
||||||
|
try { |
||||||
|
if (isIgnoreRequest(request)) { |
||||||
|
filterChain.doFilter(request, response); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (this.wrapRequest) { |
||||||
|
request = new CASFilterRequestWrapper((HttpServletRequest)request); |
||||||
|
} |
||||||
|
|
||||||
|
HttpSession var4 = ((HttpServletRequest)request).getSession(); |
||||||
|
if (var4 != null && var4.getAttribute("edu.yale.its.tp.cas.client.filter.user") != null) { |
||||||
|
filterChain.doFilter((ServletRequest)request, response); |
||||||
|
} else { |
||||||
|
String var5 = ((ServletRequest)request).getParameter("ticket"); |
||||||
|
if (var5 != null && !var5.equals("")) { |
||||||
|
String var6 = this.getAuthenticatedUser((HttpServletRequest)request); |
||||||
|
if (var6 == null) { |
||||||
|
throw new ServletException("Unexpected CAS authentication error"); |
||||||
|
} else { |
||||||
|
if (var4 != null) { |
||||||
|
var4.setAttribute("edu.yale.its.tp.cas.client.filter.user", var6); |
||||||
|
} |
||||||
|
|
||||||
|
filterChain.doFilter((ServletRequest)request, response); |
||||||
|
} |
||||||
|
} else if (this.casLogin == null) { |
||||||
|
throw new ServletException("When CASFilter protects pages that do not receive a 'ticket' parameter, it needs a edu.yale.its.tp.cas.client.filter.loginUrl filter parameter"); |
||||||
|
} else { |
||||||
|
((HttpServletResponse)response).sendRedirect(this.casLogin + "?service=" + this.getService((HttpServletRequest)request) + (this.casRenew != null && !this.casRenew.equals("") ? "&renew=" + this.casRenew : "")); |
||||||
|
} |
||||||
|
} |
||||||
|
} catch (ServletException e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getLocalizedMessage(), e); |
||||||
|
} catch (IOException e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getLocalizedMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private String getAuthenticatedUser(HttpServletRequest request) throws ServletException { |
||||||
|
ProxyTicketValidator var2 = null; |
||||||
|
|
||||||
|
String var4; |
||||||
|
try { |
||||||
|
var2 = new ProxyTicketValidator(); |
||||||
|
var2.setCasValidateUrl(this.casValidate); |
||||||
|
var2.setServiceTicket(request.getParameter("ticket")); |
||||||
|
var2.setService(this.getService(request)); |
||||||
|
var2.setRenew(Boolean.valueOf(this.casRenew)); |
||||||
|
var2.validate(); |
||||||
|
if (!var2.isAuthenticationSuccesful()) { |
||||||
|
throw new ServletException("CAS authentication error: " + var2.getErrorCode() + ": " + var2.getErrorMessage()); |
||||||
|
} else { |
||||||
|
if (var2.getProxyList().size() != 0) { |
||||||
|
if (this.casAuthorizedProxy == null) { |
||||||
|
throw new ServletException("this page does not accept proxied tickets"); |
||||||
|
} |
||||||
|
|
||||||
|
boolean var3 = false; |
||||||
|
var4 = (String)var2.getProxyList().get(0); |
||||||
|
StringTokenizer var5 = new StringTokenizer(this.casAuthorizedProxy); |
||||||
|
|
||||||
|
while(var5.hasMoreTokens()) { |
||||||
|
if (var4.equals(var5.nextToken())) { |
||||||
|
var3 = true; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (!var3) { |
||||||
|
throw new ServletException("unauthorized top-level proxy: '" + var2.getProxyList().get(0) + "'"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return var2.getUser(); |
||||||
|
} |
||||||
|
} catch (SAXException var6) { |
||||||
|
var4 = ""; |
||||||
|
if (var2 != null) { |
||||||
|
var4 = var2.getResponse(); |
||||||
|
} |
||||||
|
|
||||||
|
throw new ServletException(var6 + " " + var4); |
||||||
|
} catch (ParserConfigurationException var7) { |
||||||
|
throw new ServletException(var7); |
||||||
|
} catch (IOException var8) { |
||||||
|
throw new ServletException(var8); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private String getService(HttpServletRequest request) throws ServletException { |
||||||
|
if (this.casServerName == null && this.casServiceUrl == null) { |
||||||
|
throw new ServletException("need one of the following configuration parameters: edu.yale.its.tp.cas.client.filter.serviceUrl or edu.yale.its.tp.cas.client.filter.serverName"); |
||||||
|
} else { |
||||||
|
return this.casServiceUrl != null ? URLEncoder.encode(this.casServiceUrl) : Util.getService(request, this.casServerName); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void destroy() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public static boolean isIgnoreRequest(HttpServletRequest request) { |
||||||
|
if (request.getRequestURI().contains("remote") || |
||||||
|
isMobile(request) || |
||||||
|
StringUtils.isNotBlank(WebUtils.getHTTPRequestParameter(request, "format"))) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
String[] ignores = IGNORE_URL.split(","); |
||||||
|
FineLoggerFactory.getLogger().info("isIgnoreRequest uri: {}", request.getRequestURI()); |
||||||
|
for (String ignore:ignores) { |
||||||
|
if (request.getRequestURI().contains(ignore)) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
public static boolean isMobile(HttpServletRequest req) { |
||||||
|
String[] mobileArray = {"iPhone", "iPad", "android", "windows phone", "xiaomi"}; |
||||||
|
String userAgent = req.getHeader("user-agent"); |
||||||
|
if (userAgent != null && userAgent.toUpperCase().contains("MOBILE")) { |
||||||
|
for(String mobile : mobileArray) { |
||||||
|
if(userAgent.toUpperCase().contains(mobile.toUpperCase())) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return NetworkHelper.getDevice(req).isMobile(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,164 @@ |
|||||||
|
package com.fr.plugin.fg.auth.filter; |
||||||
|
|
||||||
|
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.WebServiceUtils; |
||||||
|
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.general.ComparatorUtils; |
||||||
|
import com.fr.locale.InterProviderFactory; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.plugin.fg.auth.TempAuthSyncSchedule; |
||||||
|
import com.fr.plugin.transform.ExecuteFunctionRecord; |
||||||
|
import com.fr.plugin.transform.FunctionRecorder; |
||||||
|
import com.fr.security.JwtUtils; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.stable.web.Device; |
||||||
|
import com.fr.web.utils.WebUtils; |
||||||
|
import com.ytec.authAPI.interFace.AuthIF; |
||||||
|
import com.ytec.authAPI.interFace.bean.AuthObjDtl; |
||||||
|
|
||||||
|
import javax.servlet.FilterChain; |
||||||
|
import javax.servlet.FilterConfig; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import javax.servlet.http.HttpServletResponse; |
||||||
|
import javax.servlet.http.HttpSession; |
||||||
|
import java.io.PrintWriter; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.Set; |
||||||
|
|
||||||
|
import static com.fr.plugin.fg.auth.FGAuthApi.tempAuth; |
||||||
|
|
||||||
|
@FunctionRecorder |
||||||
|
public class CheckTempleteAuth extends AbstractGlobalRequestFilterProvider{ |
||||||
|
|
||||||
|
private String name = "fineFgAuth"; |
||||||
|
private String cpt_path = "/decision/view/report"; |
||||||
|
private String frm_path = "/decision/view/form"; |
||||||
|
private String bi_path = "/decision/v5/design/report/"; |
||||||
|
|
||||||
|
@Override |
||||||
|
public String filterName() { |
||||||
|
return name; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String[] urlPatterns() { |
||||||
|
return new String[]{cpt_path, frm_path, bi_path}; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void init(FilterConfig filterConfig) { |
||||||
|
super.init(filterConfig); |
||||||
|
try { |
||||||
|
FineLoggerFactory.getLogger().info("FGAuth:Schedule开始启动"); |
||||||
|
TempAuthSyncSchedule.startSchedule(name, name, new HashMap<String, Object>()); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error("FGAuth:Schedule启动失败" + e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@ExecuteFunctionRecord |
||||||
|
@Override |
||||||
|
public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) { |
||||||
|
try { |
||||||
|
|
||||||
|
// 未登录请求 直接放行
|
||||||
|
if (!LoginService.getInstance().isLogged(req)) { |
||||||
|
filterChain.doFilter(req, res); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
String viewlet = WebUtils.getHTTPRequestParameter(req, "viewlet"); |
||||||
|
// 客户报表分两类, 以【我的报表】开头的报表走验证, 其他的都不走验证
|
||||||
|
if ((StringUtils.isNotBlank(viewlet) && viewlet.startsWith("我的报表")) || isBiViewUrl(req)) { |
||||||
|
//String userName = getUser(req);
|
||||||
|
String userName = LoginService.getInstance().getCurrentUserNameFromRequestCookie(req); |
||||||
|
User user = UserService.getInstance().getUserByUserName(userName); |
||||||
|
|
||||||
|
FineLoggerFactory.getLogger().info("FGAuth:用户 {}, 模板名称 {}", userName, viewlet); |
||||||
|
if (!checkUserAuth(userName, viewlet, user)) { |
||||||
|
FineLoggerFactory.getLogger().info("FGAuth:用户 {} 没有模板权限 {}", userName, viewlet); |
||||||
|
showError(res); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
filterChain.doFilter(req, res); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error("FGAuth: CheckTemplateAuth#doFilter执行异常" + e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isBiViewUrl(HttpServletRequest req){ |
||||||
|
if (req.getRequestURI().contains(bi_path)) { |
||||||
|
FineLoggerFactory.getLogger().info("FGAuth: BI的预览请求" + req.getRequestURI()); |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
private void showError(HttpServletResponse res){ |
||||||
|
try { |
||||||
|
PrintWriter printWriter = WebUtils.createPrintWriter(res); |
||||||
|
Map<String, Object> map = new HashMap<>(); |
||||||
|
map.put("result", InterProviderFactory.getProvider().getLocText("Fine-Engine_Error_Page_Result")); |
||||||
|
map.put("reason", InterProviderFactory.getProvider().getLocText("Fine-Engine_Report_No_Priviledege")); |
||||||
|
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) { |
||||||
|
FineLoggerFactory.getLogger().error("FGAuth: CheckTempleteAuth#showError执行异常" + e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 校验tempAuth中是否包含当前用户 |
||||||
|
* @param userName |
||||||
|
* @param viewlet |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
private boolean checkUserAuth(String userName, String viewlet, User user) throws Exception { |
||||||
|
// 超管
|
||||||
|
if (UserService.getInstance().isAdmin(user.getId())){ |
||||||
|
return true; |
||||||
|
} |
||||||
|
/** |
||||||
|
* 只取模板的编号 |
||||||
|
* 我的报表/dept_019/rpt_0005.frm 转换为 bi_rpt_0005 |
||||||
|
*/ |
||||||
|
viewlet = "bi_" + viewlet.substring(viewlet.lastIndexOf("/") + 1).replace(".cpt", "").replace(".frm", ""); |
||||||
|
if (!tempAuth.containsKey(viewlet)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
// 用户名校验
|
||||||
|
Set<String> userInfo = tempAuth.get(viewlet).get(AuthObjDtl.OBJ_TYP_USR); |
||||||
|
FineLoggerFactory.getLogger().info("FGAuth: {} 的userInfo为 {}", viewlet, userInfo); |
||||||
|
if (userInfo != null && userInfo.contains(userName)) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
// 角色校验
|
||||||
|
//List<String> roles = UserService.getInstance().getUserDetailInfoByUsername(userName).getCustomRoleNames();
|
||||||
|
Set<String> roles = AuthIF.getInstance().getUserRoles(userName); |
||||||
|
Set<String> roleInfo = tempAuth.get(viewlet).get(AuthObjDtl.OBJ_TYP_ROLE); |
||||||
|
FineLoggerFactory.getLogger().info("FGAuth: {} 的roleInfo为 {}", viewlet, roleInfo); |
||||||
|
FineLoggerFactory.getLogger().info("FGAuth: 当前用户 {} 的角色信息为 {}", userName, roles); |
||||||
|
if (roles != null && roleInfo != null){ |
||||||
|
for (String role : roles) { |
||||||
|
if (roleInfo.contains(role)) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,73 @@ |
|||||||
|
package com.fr.plugin.fg.auth.filter; |
||||||
|
|
||||||
|
import com.fr.data.NetworkHelper; |
||||||
|
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider; |
||||||
|
|
||||||
|
import javax.servlet.*; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import javax.servlet.http.HttpServletResponse; |
||||||
|
import java.io.IOException; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public class FGFilter extends AbstractGlobalRequestFilterProvider { |
||||||
|
|
||||||
|
@Override |
||||||
|
public String filterName() { |
||||||
|
return "FGFilter"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String[] urlPatterns() { |
||||||
|
return new String[]{ |
||||||
|
"/*" |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) { |
||||||
|
// 远程设计 and 移动端请求放行
|
||||||
|
try { |
||||||
|
if (request.getRequestURI().contains("remote")) { |
||||||
|
filterChain.doFilter(request, response); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (NetworkHelper.getDevice(request).isMobile() |
||||||
|
|| "h5".equals(request.getParameter("op")) |
||||||
|
|| request.getRequestURI().contains("/weixin/single/login") |
||||||
|
|| request.getRequestURI().contains("mobile")) { |
||||||
|
filterChain.doFilter(request, response); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} catch (Exception e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private static class VirtualFilterChain implements FilterChain { |
||||||
|
private List<Filter> filters; |
||||||
|
private FilterChain originChain; |
||||||
|
private int count; |
||||||
|
|
||||||
|
VirtualFilterChain(List<Filter> filters, FilterChain originChain) { |
||||||
|
this.filters = filters; |
||||||
|
this.originChain = originChain; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException, ServletException { |
||||||
|
if (count == filters.size()) { |
||||||
|
originChain.doFilter(servletRequest, servletResponse); |
||||||
|
} else { |
||||||
|
filters.get(count++).doFilter(servletRequest, servletResponse, this); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,106 @@ |
|||||||
|
package com.fr.plugin.fg.auth.filter; |
||||||
|
|
||||||
|
import com.fr.data.NetworkHelper; |
||||||
|
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.v10.login.LoginService; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.security.JwtUtils; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.stable.web.Device; |
||||||
|
import org.jasig.cas.client.validation.Assertion; |
||||||
|
|
||||||
|
import javax.servlet.FilterChain; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import javax.servlet.http.HttpServletResponse; |
||||||
|
import javax.servlet.http.HttpSession; |
||||||
|
|
||||||
|
public class LoginFilter extends AbstractGlobalRequestFilterProvider { |
||||||
|
@Override |
||||||
|
public String filterName() { |
||||||
|
return "fineCasLogin"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String[] urlPatterns() { |
||||||
|
return new String[]{ "/*"}; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) { |
||||||
|
try { |
||||||
|
if (CasYaleFilter.isIgnoreRequest(request)) { |
||||||
|
filterChain.doFilter(request, response); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
HttpSession session = request.getSession(true); |
||||||
|
FineLoggerFactory.getLogger().info("URL:" + request.getRequestURI()); |
||||||
|
String username; |
||||||
|
//获取cas传递过来的username
|
||||||
|
Object object = request.getSession().getAttribute("_const_cas_assertion_"); |
||||||
|
if (object != null) { |
||||||
|
Assertion assertion = (Assertion) object; |
||||||
|
username = assertion.getPrincipal().getName(); |
||||||
|
} else { |
||||||
|
username = (String) session.getAttribute("edu.yale.its.tp.cas.client.filter.user"); |
||||||
|
} |
||||||
|
|
||||||
|
try { |
||||||
|
//用户名为空,登录请求有问题,直接报错
|
||||||
|
if (StringUtils.isNotEmpty(username)) { |
||||||
|
FineLoggerFactory.getLogger().info("username:" + username); |
||||||
|
//获取请求携带的token
|
||||||
|
Object oldToken = session.getAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME); |
||||||
|
|
||||||
|
//token不存在,或者token过期了,走后台登录方法
|
||||||
|
if (oldToken == null || !checkTokenValid(request, (String) oldToken, username)) { |
||||||
|
login(request, response, session, username); |
||||||
|
filterChain.doFilter(request, response); |
||||||
|
} else { |
||||||
|
//放行
|
||||||
|
filterChain.doFilter(request, response); |
||||||
|
FineLoggerFactory.getLogger().info("no need"); |
||||||
|
} |
||||||
|
} else { |
||||||
|
throw new Exception("username is empty"); |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 后台登录方法 |
||||||
|
*/ |
||||||
|
private void login(HttpServletRequest req, HttpServletResponse res, HttpSession session, String username) throws Exception { |
||||||
|
String token = LoginService.getInstance().login(req, res, username); |
||||||
|
session.setAttribute("fine_auth_token", token); |
||||||
|
req.setAttribute("fine_auth_token", token); |
||||||
|
FineLoggerFactory.getLogger().info("fr FrFilter is over with username is ###" + username); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 校验token是否有效 |
||||||
|
*/ |
||||||
|
private boolean checkTokenValid(HttpServletRequest req, String token, String currentUserName) { |
||||||
|
try { |
||||||
|
//当前登录用户和token对应的用户名不同,需要重新生成token
|
||||||
|
if (!ComparatorUtils.equals(currentUserName, JwtUtils.parseJWT(token).getSubject())) { |
||||||
|
FineLoggerFactory.getLogger().info("username changed:" + currentUserName); |
||||||
|
return false; |
||||||
|
} |
||||||
|
Device device = NetworkHelper.getDevice(req); |
||||||
|
LoginService.getInstance().loginStatusValid(token, TerminalHandler.getTerminal(req, device)); |
||||||
|
return true; |
||||||
|
} catch (Exception ignore) { |
||||||
|
} |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue