JSD-8967 app单点(基于时间戳和密钥加密签名)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

144 lines
4.5 KiB

package com.fr.plugin.jfsso.filter;
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
import com.fr.json.JSONObject;
import com.fr.license.utils.JsonUtil;
import com.fr.plugin.context.PluginContexts;
import com.fr.plugin.jfsso.config.PluginSimpleConfig;
import com.fr.plugin.jfsso.utils.*;
import com.fr.record.analyzer.EnableMetrics;
import com.fr.stable.fun.Authorize;
import com.fr.third.org.apache.http.impl.cookie.BasicClientCookie;
import javax.servlet.FilterChain;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Calendar;
import java.util.Random;
@EnableMetrics
@Authorize(callSignKey = "com.fr.plugin.jfsso")
public class SSOFilter extends AbstractGlobalRequestFilterProvider {
@Override
public String filterName() {
return "jfssoFilter";
}
@Override
public String[] urlPatterns() {
return new String[]{"/decision/*"};
}
@Override
public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain ){
if(PluginContexts.currentContext().isAvailable()) {
PluginSimpleConfig psc = PluginSimpleConfig.getInstance();
String tokenStr = psc.getTokenStr();
//token
String tokenid = req.getParameter(tokenStr);
//时间戳
String ts = req.getParameter("ts");
//签名
String sign = req.getParameter("sign");
if (Utils.isNotNullStr(tokenid)) {
String decrpt = EncryptUtils.aesDecrypt(tokenid,psc.getAppkey());
String[] decrypt = decrpt.split("_");
String jmts = decrypt[1];
if(!ts.equals(jmts)){
ResponseUtils.failedResponse(res,"时间戳校验失败");
return ;
}
String shastr = decrypt[0]+"_"+ts;
String signstr =EncryptUtils.sha(shastr);
if(!sign.equals(signstr)){
ResponseUtils.failedResponse(res,"验签失败");
return ;
}
String username = getToken(tokenid, psc);
FRUtils.FRLogInfo("username:" + username);
//登录
FRUtils.login(req, res, username, "");
}
}
release(req,res,chain);
}
/**
* 获取token
* @param tokenid
* @return
*/
private String getToken(String tokenid,PluginSimpleConfig psc) {
String tokenUrl = psc.getTokenUrl();
String random = getStringRandom(6);
String ts = String.valueOf(Calendar.getInstance().getTimeInMillis());
String token = EncryptUtils.aesEncrypt(random+"_"+tokenid+"_"+ts,psc.getFrkey());
String sign = EncryptUtils.sha(random+"_"+ts);
tokenUrl += "?ts="+ts + "&saas_login_token="+token+"&sign="+sign;
BasicClientCookie[] cookies = new BasicClientCookie[1];
BasicClientCookie bc = new BasicClientCookie("saas_login_token",tokenid);
bc.setPath("/");
cookies[0] = bc;
String result = HttpUtils.HttpPostJson(tokenUrl,null,null,cookies);
if(Utils.isNullStr(result)){
return "";
}
JSONObject json = new JSONObject(result);
if(json == null){
return "";
}
String code = json.getString("code");
if(!code.equals("0")){
return "";
}
return json.getJSONObject("result").getString("account");
}
//放行拦截器
private void release(HttpServletRequest req, HttpServletResponse res, FilterChain chain) {
try{
chain.doFilter(req,res);
}catch (Exception e){
FRUtils.FRLogInfo("拦截失败");
}
}
public static String getStringRandom(int length) {
String val = "";
Random random = new Random();
//参数length,表示生成几位随机数
for(int i = 0; i < length; i++) {
String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
//输出字母还是数字
if("char".equalsIgnoreCase(charOrNum)){
//输出是大写字母还是小写字母
int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;
val += (char)(random.nextInt(26) + temp);
}else if("num".equalsIgnoreCase(charOrNum)) {
val += String.valueOf(random.nextInt(10));
}
}
return val;
}
}