7 changed files with 319 additions and 1 deletions
@ -1,3 +1,6 @@ |
|||||||
# open-JSD-9066 |
# open-JSD-9066 |
||||||
|
|
||||||
JSD-9066 FR单点接口密码自定义解密 |
JSD-9066 FR单点接口密码自定义解密\ |
||||||
|
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ |
||||||
|
仅作为开发者学习参考使用!禁止用于任何商业用途!\ |
||||||
|
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。 |
@ -0,0 +1,25 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
||||||
|
<plugin> |
||||||
|
<id>com.fr.plugin.xxxx.cqjg.jump</id> |
||||||
|
<main-package>com.fr.plugin.xxxx.cqjg.jump</main-package> |
||||||
|
<name><![CDATA[跳转Chrome]]></name> |
||||||
|
<active>yes</active> |
||||||
|
<version>1.4</version> |
||||||
|
<env-version>10.0</env-version> |
||||||
|
<jartime>2018-07-31</jartime> |
||||||
|
<vendor>xxxx</vendor> |
||||||
|
<description><![CDATA[跳转Chrome]]></description> |
||||||
|
<change-notes><![CDATA[ |
||||||
|
[2021-10-29]【1.0】初始化插件。<br/> |
||||||
|
[2021-11-04]【1.1】逻辑修改为解析token中用户的方式。<br/> |
||||||
|
[2021-11-08]【1.2】增加获取token链接,直接比对数据库密码。<br/> |
||||||
|
[2021-11-08]【1.3】增加sha256加密后比对数据库密码。<br/> |
||||||
|
[2021-11-08]【1.4】增加写入cookie。<br/> |
||||||
|
]]></change-notes> |
||||||
|
<extra-decision> |
||||||
|
<HttpHandlerProvider class="com.fr.plugin.xxxx.cqjg.jump.TokenRequestHandlerBridge"/> |
||||||
|
<URLAliasProvider class="com.fr.plugin.xxxx.cqjg.jump.TokenRequestURLAliasBridge" /> |
||||||
|
<GlobalRequestFilterProvider class="com.fr.plugin.xxxx.cqjg.jump.GlobalFilter"/> |
||||||
|
</extra-decision> |
||||||
|
<function-recorder class="com.fr.plugin.xxxx.cqjg.jump.GlobalFilter"/> |
||||||
|
</plugin> |
@ -0,0 +1,9 @@ |
|||||||
|
package com.fr.plugin.xxxx.cqjg.jump; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author fr.open |
||||||
|
* @date 2020/5/14 |
||||||
|
*/ |
||||||
|
public class Constants { |
||||||
|
public static final String PLUGIN_ID = "com.fr.plugin.xxxx.cqjg.jump"; |
||||||
|
} |
@ -0,0 +1,109 @@ |
|||||||
|
package com.fr.plugin.xxxx.cqjg.jump; |
||||||
|
|
||||||
|
import com.fr.cert.token.Claims; |
||||||
|
import com.fr.cert.token.Jwts; |
||||||
|
import com.fr.decision.authority.data.User; |
||||||
|
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider; |
||||||
|
import com.fr.decision.webservice.exception.user.UserNotExistException; |
||||||
|
import com.fr.decision.webservice.utils.DecisionServiceConstants; |
||||||
|
import com.fr.decision.webservice.v10.config.ConfigService; |
||||||
|
import com.fr.decision.webservice.v10.login.LoginService; |
||||||
|
import com.fr.decision.webservice.v10.user.UserService; |
||||||
|
import com.fr.intelli.record.Focus; |
||||||
|
import com.fr.intelli.record.Original; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.plugin.context.PluginContexts; |
||||||
|
import com.fr.plugin.transform.FunctionRecorder; |
||||||
|
import com.fr.record.analyzer.EnableMetrics; |
||||||
|
import com.fr.security.KeySecretSeedConfig; |
||||||
|
import com.fr.security.SecurityToolbox; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.stable.fun.Authorize; |
||||||
|
|
||||||
|
import javax.servlet.FilterChain; |
||||||
|
import javax.servlet.ServletException; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import javax.servlet.http.HttpServletResponse; |
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
/** |
||||||
|
* @Author fr.open |
||||||
|
* @Date 2021/10/29 |
||||||
|
* @Description |
||||||
|
**/ |
||||||
|
@FunctionRecorder |
||||||
|
@Authorize(callSignKey = Constants.PLUGIN_ID) |
||||||
|
@EnableMetrics |
||||||
|
public class GlobalFilter extends AbstractGlobalRequestFilterProvider { |
||||||
|
|
||||||
|
private static final String flag = "00000"; |
||||||
|
|
||||||
|
@Override |
||||||
|
public String filterName() { |
||||||
|
return "global"; |
||||||
|
} |
||||||
|
|
||||||
|
@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) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
return new String[]{ |
||||||
|
"/" + servletPathName, |
||||||
|
"/" + servletPathName + "/view/report", |
||||||
|
|
||||||
|
}; |
||||||
|
} else { |
||||||
|
return new String[0]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) { |
||||||
|
String query = req.getQueryString(); |
||||||
|
if (StringUtils.isNotBlank(query) && query.contains(flag)) { |
||||||
|
int start = query.indexOf(flag) + 5; |
||||||
|
int end = query.indexOf("&", start); |
||||||
|
String token = query.substring(start, end == -1 ? query.length() : end); |
||||||
|
FineLoggerFactory.getLogger().info("get token is {}", token); |
||||||
|
try { |
||||||
|
byte[] bytes = SecurityToolbox.base642Byte(KeySecretSeedConfig.getInstance().getTrustSeed()); |
||||||
|
Claims claims = Jwts.parser().setSigningKey(bytes).parseClaimsJws(token).getBody(); |
||||||
|
loginFromToken(req,res,claims.getSubject()); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
try { |
||||||
|
filterChain.doFilter(req, res); |
||||||
|
} catch (IOException e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage()); |
||||||
|
} catch (ServletException e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private boolean loginFromToken(HttpServletRequest req, HttpServletResponse res, String username) throws Exception { |
||||||
|
try { |
||||||
|
if (StringUtils.isNotEmpty(username)) { |
||||||
|
User user = UserService.getInstance().getUserByUserName(username); |
||||||
|
if (user == null) { |
||||||
|
throw new UserNotExistException(); |
||||||
|
} |
||||||
|
String token = LoginService.getInstance().login(req, res, username); |
||||||
|
req.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME, token); |
||||||
|
return true; |
||||||
|
} else { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,18 @@ |
|||||||
|
package com.fr.plugin.xxxx.cqjg.jump; |
||||||
|
|
||||||
|
import com.fr.decision.fun.HttpHandler; |
||||||
|
import com.fr.decision.fun.impl.AbstractHttpHandlerProvider; |
||||||
|
import com.fr.plugin.holger.cqjg.jump.handle.TokenHandler; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author fr.open |
||||||
|
* @since 2021/07/28 |
||||||
|
*/ |
||||||
|
public class TokenRequestHandlerBridge extends AbstractHttpHandlerProvider { |
||||||
|
@Override |
||||||
|
public HttpHandler[] registerHandlers() { |
||||||
|
return new HttpHandler[]{ |
||||||
|
new TokenHandler() |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,18 @@ |
|||||||
|
package com.fr.plugin.xxxx.cqjg.jump; |
||||||
|
|
||||||
|
import com.fr.decision.fun.impl.AbstractURLAliasProvider; |
||||||
|
import com.fr.decision.webservice.url.alias.URLAlias; |
||||||
|
import com.fr.decision.webservice.url.alias.URLAliasFactory; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author fr.open |
||||||
|
* @since 2021/07/28 |
||||||
|
*/ |
||||||
|
public class TokenRequestURLAliasBridge extends AbstractURLAliasProvider { |
||||||
|
@Override |
||||||
|
public URLAlias[] registerAlias() { |
||||||
|
return new URLAlias[]{ |
||||||
|
URLAliasFactory.createPluginAlias("/token", "/token", true), |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,136 @@ |
|||||||
|
package com.fr.plugin.xxxx.cqjg.jump.handle; |
||||||
|
|
||||||
|
import com.fr.base.ServerConfig; |
||||||
|
import com.fr.base.TemplateUtils; |
||||||
|
import com.fr.data.NetworkHelper; |
||||||
|
import com.fr.decision.authority.AuthorityContext; |
||||||
|
import com.fr.decision.authority.data.User; |
||||||
|
import com.fr.decision.config.FSConfig; |
||||||
|
import com.fr.decision.fun.impl.BaseHttpHandler; |
||||||
|
import com.fr.decision.mobile.terminal.TerminalHandler; |
||||||
|
import com.fr.decision.webservice.CrossDomainResponse; |
||||||
|
import com.fr.decision.webservice.bean.authentication.LoginClientBean; |
||||||
|
import com.fr.decision.webservice.exception.user.UserNotExistException; |
||||||
|
import com.fr.decision.webservice.utils.DecisionStatusService; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.security.JwtUtils; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.stable.query.QueryFactory; |
||||||
|
import com.fr.stable.query.restriction.RestrictionFactory; |
||||||
|
import com.fr.stable.web.Device; |
||||||
|
import com.fr.store.Converter; |
||||||
|
import com.fr.third.com.lowagie.text.pdf.BadPasswordException; |
||||||
|
import com.fr.third.org.apache.commons.codec.digest.DigestUtils; |
||||||
|
import com.fr.third.springframework.web.bind.annotation.RequestMethod; |
||||||
|
import com.fr.web.utils.WebUtils; |
||||||
|
|
||||||
|
import javax.servlet.http.Cookie; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import javax.servlet.http.HttpServletResponse; |
||||||
|
import java.util.HashMap; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* @author fr.open |
||||||
|
* @Date 2021/08/17 |
||||||
|
*/ |
||||||
|
public class TokenHandler extends BaseHttpHandler { |
||||||
|
|
||||||
|
@Override |
||||||
|
public RequestMethod getMethod() { |
||||||
|
return RequestMethod.GET; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getPath() { |
||||||
|
return "/token"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isPublic() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void handle(HttpServletRequest req, HttpServletResponse res) { |
||||||
|
CrossDomainResponse domainResponse = null; |
||||||
|
try { |
||||||
|
String origin = NetworkHelper.getOriginalURL(req); |
||||||
|
String uri = req.getRequestURI(); |
||||||
|
String render = TemplateUtils.render(origin.replace(uri, "${fineServletURL}")); |
||||||
|
String username = WebUtils.getHTTPRequestParameter(req, "fine_username"); |
||||||
|
String password = WebUtils.getHTTPRequestParameter(req, "fine_password"); |
||||||
|
String validity = WebUtils.getHTTPRequestParameter(req, "validity"); |
||||||
|
User user = AuthorityContext.getInstance().getUserController().findOne(QueryFactory.create().addRestriction(RestrictionFactory.eq("userName", username))); |
||||||
|
if (user == null) { |
||||||
|
throw new UserNotExistException(); |
||||||
|
} |
||||||
|
if (!StringUtils.equals(DigestUtils.sha256Hex(password), user.getPassword())) { |
||||||
|
throw new BadPasswordException(); |
||||||
|
} |
||||||
|
long timeout = getTokenTimeOutByValidity(Integer.parseInt(validity)); |
||||||
|
String token = generateToken(user.getUserName(), user.getDisplayName(), user.getTenantId(),timeout ); |
||||||
|
Device device = NetworkHelper.getDevice(req); |
||||||
|
TerminalHandler handler = TerminalHandler.getTerminal(req, device); |
||||||
|
LoginClientBean clientBean = new LoginClientBean(req, device, handler); |
||||||
|
clientBean.setUsername(user.getUserName()); |
||||||
|
clientBean.setToken(token); |
||||||
|
clientBean.setValidity(Integer.parseInt(validity)); |
||||||
|
clientBean.setUserId(user.getId()); |
||||||
|
this.addLoginStatus(token, clientBean, timeout); |
||||||
|
this.writeToken2Cookie(res, token, Integer.parseInt(validity)); |
||||||
|
|
||||||
|
domainResponse = CrossDomainResponse.create().callbackFuncName("callback").parameter("accessToken",token).parameter("url", render).parameter("status", "success"); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
domainResponse = CrossDomainResponse.error(e, "callback"); |
||||||
|
} |
||||||
|
try { |
||||||
|
WebUtils.printAsString(res, domainResponse.createCrossDomainResponse()); |
||||||
|
; |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
private void writeToken2Cookie(HttpServletResponse res, String token, int validity) { |
||||||
|
try { |
||||||
|
if (StringUtils.isNotEmpty(token)) { |
||||||
|
Cookie tokenCookie = new Cookie("fine_auth_token", token); |
||||||
|
long timeout = validity == -2 ? 1209600000L : (long)validity; |
||||||
|
tokenCookie.setMaxAge((int)timeout); |
||||||
|
tokenCookie.setPath(ServerConfig.getInstance().getCookiePath()); |
||||||
|
res.addCookie(tokenCookie); |
||||||
|
Cookie rememberLogin = new Cookie("fine_remember_login", String.valueOf(validity == -2 ? -2 : -1)); |
||||||
|
rememberLogin.setMaxAge((int)timeout); |
||||||
|
rememberLogin.setPath(ServerConfig.getInstance().getCookiePath()); |
||||||
|
res.addCookie(rememberLogin); |
||||||
|
} else { |
||||||
|
FineLoggerFactory.getLogger().error("empty token cannot save."); |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private void addLoginStatus(String token, LoginClientBean bean, long timeout) throws Exception { |
||||||
|
DecisionStatusService.loginStatusService().put(token, bean, new Converter<LoginClientBean>() { |
||||||
|
@Override |
||||||
|
public String[] createAlias(LoginClientBean bean) { |
||||||
|
return new String[]{bean.getUsername()}; |
||||||
|
} |
||||||
|
}, timeout); |
||||||
|
} |
||||||
|
|
||||||
|
private long getTokenTimeOutByValidity(int validity) { |
||||||
|
return validity == -2 ? 1209600000L : FSConfig.getInstance().getLoginConfig().getLoginTimeout(); |
||||||
|
} |
||||||
|
|
||||||
|
private String generateToken(String username, String displayName, String tenanId, long validity) { |
||||||
|
HashMap map = new HashMap(); |
||||||
|
map.put("description", displayName); |
||||||
|
map.put("tenantId", tenanId); |
||||||
|
return JwtUtils.createDefaultJWT(username, map, validity); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue