package com.terra.proxy.controller;
|
|
import java.util.*;
|
|
import javax.servlet.http.HttpServletRequest;
|
|
import cn.hutool.core.collection.CollectionUtil;
|
import com.terra.proxy.util.JedisUtils;
|
import io.swagger.models.auth.In;
|
import org.apache.commons.lang3.StringUtils;
|
import org.apache.http.HttpStatus;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.core.env.Environment;
|
import org.springframework.web.bind.annotation.*;
|
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.serializer.SerializerFeature;
|
import com.terra.proxy.bean.CustomerToken;
|
import com.terra.proxy.bean.ResActionRecord;
|
import com.terra.proxy.bean.TokenRecord;
|
import com.terra.proxy.mapper.LogMapper;
|
import com.terra.proxy.service.Impl.LogServiceImpl;
|
import com.terra.proxy.service.Impl.ResActionRecordServiceImpl;
|
import com.terra.proxy.service.Impl.ServerRegisterServiceImpl;
|
import com.terra.proxy.util.HttpContextUtils;
|
import com.terra.proxy.util.JwtUtils;
|
import com.terra.proxy.util.Result;
|
|
import cn.hutool.json.JSONUtil;
|
import io.jsonwebtoken.Claims;
|
import redis.clients.jedis.Jedis;
|
|
/**
|
* token生成与验证
|
*
|
* @author TanBin
|
* @date 2018年1月31日 下午6:26:13
|
*/
|
@RestController
|
public class TokenController {
|
|
@Autowired
|
public Environment env;
|
|
@Autowired
|
LogServiceImpl logservice;
|
|
@Autowired
|
ResActionRecordServiceImpl actionRecordService;
|
|
@Autowired
|
private JwtUtils jwtUtils;
|
|
@Autowired
|
JedisUtils jedisUtils;
|
|
@Value("${sys.allowedips}")
|
private String allowedips;
|
@Value("${sys.jwt.expire}")
|
private Long expireSeconds;
|
|
@Autowired
|
ServerRegisterServiceImpl serverRegisterService;
|
|
@Autowired
|
LogMapper logMapper;
|
|
private static final Logger log = LoggerFactory.getLogger(TokenController.class);
|
|
|
@RequestMapping(value = "/token/getToken", method = { RequestMethod.POST, RequestMethod.GET })
|
public String getToken(String message,long expireSeconds)
|
{
|
// 生成token
|
String token = jwtUtils.generateToken( message.toString(), expireSeconds);
|
return token;
|
}
|
|
@RequestMapping(value="/token/delTokenRecord",method = {RequestMethod.GET,RequestMethod.POST})
|
@ResponseBody
|
public String delToken(String token,Integer expiration){
|
Jedis jedis=JedisUtils.getJedis();
|
String t="zytoken:"+token;
|
try{
|
Map<String, Object> params =new HashMap<>();
|
params.put("token", token);
|
params.put("expiration", -1);
|
jedis.del(t);
|
//除去自动续约token
|
jedis.srem("autoToken",token);
|
logservice.updateTokenRecord(params);
|
}catch (Exception e) {
|
e.printStackTrace();
|
}
|
return "success";
|
}
|
|
|
|
|
|
@RequestMapping(value="/token/selectTokenRecord",method = {RequestMethod.GET,RequestMethod.POST})
|
@ResponseBody
|
public String selectTokenRecord(Integer limit,Integer page,String token,Integer tokenstatus,String identyinfo,Integer resourceId){
|
Map<String, Object> params =new HashMap<>();
|
params.put("limit", limit);
|
params.put("page", (page-1)*limit);
|
params.put("token", token);
|
params.put("tokenstatus", tokenstatus);
|
params.put("identyinfo", identyinfo);
|
params.put("resourceId", resourceId);
|
List<Map> list=logservice.selectTokenRecord(params);
|
Jedis jedis = JedisUtils.getJedis();
|
//自动续约列表
|
Set<String> autoToken = jedis.smembers("autoToken");
|
list.stream().forEach(map -> {
|
String string = map.get("TOKEN").toString();
|
if(StringUtils.isNotEmpty(string)&&autoToken.contains(string)){
|
map.put("AUTOTOKEN","1");
|
}else {
|
map.put("AUTOTOKEN","0");
|
}
|
});
|
JedisUtils.close(jedis);
|
JSONObject json=new JSONObject();
|
json.put("total", logservice.getTotalTokenRecord(params));
|
json.put("data", list);
|
json.put("totalpage",Math.ceil((double) logservice.getTotalTokenRecord(params)/(double)limit));
|
return JSONObject.toJSONStringWithDateFormat(json, "yyyy-MM-dd HH:mm:ss", SerializerFeature.PrettyFormat);
|
}
|
|
@RequestMapping(value = "/token/tokenTimeExtend", method = { RequestMethod.POST, RequestMethod.GET })
|
public String tokenTimeExtend(String tokenlist,Integer expireSeconds)
|
{ Jedis jedis= JedisUtils.getJedis();
|
Map<String, Object> params =new HashMap<>();
|
if (StringUtils.isEmpty(tokenlist)) return Result.ok().toString();
|
if(null==expireSeconds) expireSeconds= this.expireSeconds.intValue();
|
try{
|
String[] tokens=tokenlist.split(";");
|
for(String t : tokens){
|
String token="zyToken:"+t;
|
String s = jedis.get(token);
|
if(StringUtils.isEmpty(s)){
|
//如果已经过期 重新加入redis 并且更新数据
|
jedis.setex(token,expireSeconds,"1");
|
}else {
|
//如果没过期 过期时间加长
|
Long ttl = jedis.ttl(token);
|
int time=Integer.parseInt(String.valueOf(ttl+expireSeconds));
|
expireSeconds=time;
|
jedis.setex(token,time,"1");
|
}
|
|
params.put("token", t);
|
params.put("expiration", expireSeconds);
|
params.put("applytime", new Date());
|
logservice.updateTokenRecord(params);
|
}
|
}catch (Exception e){
|
e.printStackTrace();
|
|
}finally {
|
jedis.close();
|
}
|
|
return "ok";
|
}
|
|
@RequestMapping(value = "/token/decToken", method = { RequestMethod.POST, RequestMethod.GET })
|
public String decToken(String token)
|
{
|
Claims claims = jwtUtils.getClaimByToken(token);
|
if (claims == null || jwtUtils.isTokenExpired(claims.getExpiration())) {
|
return "token已失效";
|
}
|
return claims.getSubject();
|
}
|
|
|
/**
|
* 生成用户访问资源服务token
|
* 调用示例:token/generate?loginName=landtoollxb&resourceId=&resourceUrl=&expireSeconds=&clientIp=
|
*
|
* @param userid
|
* @param resourceId
|
* @param expireSeconds
|
* @param clientIp
|
* @param subzyids
|
* @param isPubzy
|
* @return
|
*/
|
private Result generateByloginName(Integer userid, String resourceId, Long expireSeconds,
|
String clientIp,String subzyids,Boolean isPubzy) {
|
if ( userid==0) {
|
return Result.error("缺少userid参数");
|
}
|
if (StringUtils.isBlank(resourceId)) {
|
return Result.error("缺少resourceId参数");
|
}
|
|
if (StringUtils.isBlank(clientIp)) {
|
return Result.error("缺少clientIp参数");
|
}
|
CustomerToken cutToken=new CustomerToken();
|
cutToken.setResourceId(resourceId);
|
cutToken.setClientIp(clientIp);
|
cutToken.setUserid(userid.toString());
|
cutToken.setSubzyids(subzyids);
|
cutToken.setIsPubzy(isPubzy);
|
|
// 生成token
|
String token = jwtUtils.generateToken( cutToken.toString(), expireSeconds);
|
SaveTokenRecord( expireSeconds, "用户"+userid+"生成", token, cutToken, clientIp);
|
Map<String, Object> map = new HashMap<>();
|
map.put("token", token);
|
map.put("expire", jwtUtils.getClaimByToken(token).getExpiration());
|
Result r = Result.ok().put(map);
|
return r;
|
}
|
|
|
/**
|
* 系统内部使用
|
* 生成token
|
* 调用示例:token/generate?loginName=landtoollxb&resourceId=&resourceUrl=&expireSeconds=&clientIp=
|
*
|
* @param userid
|
* @param resourceId
|
* @param expireSeconds
|
* @param clientIp
|
* @param subzyids
|
* @param isPubzy
|
* @return
|
*/
|
@RequestMapping(value = "/token/generate", method = { RequestMethod.POST, RequestMethod.GET })
|
public Result generate(Integer userid, String resourceId, Long expireSeconds,String clientIp,String subzyids,Boolean isPubzy) {
|
Map<String, Object> msg = new HashMap<>();
|
//判读IP是否合法------
|
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
|
String ip = request.getLocalAddr();
|
|
//判读IP是否合法------
|
if(!checkIp(ip))
|
{
|
return Result.error("非法IP调用【"+ip+"】");
|
}
|
|
Result r = generateByloginName(userid, resourceId, expireSeconds, clientIp, subzyids,isPubzy);
|
|
return r;
|
}
|
|
|
|
|
|
/**
|
* 系统内部使用
|
* 生成token
|
* 调用示例:token/appgenerate?resourceId=&resourceUrl=&expireSeconds=&appId=&appUrl=
|
*
|
* @param resourceId
|
* @param resourceId
|
* @param expireSeconds
|
* @param appId
|
* @param appUrl
|
* @return
|
*/
|
|
@RequestMapping(value = "/token/appgenerate", method = { RequestMethod.POST, RequestMethod.GET })
|
public Result appGenerate(Integer userId,String resourceId, Long expireSeconds, Long appId, String appUrl,String subzyids) {
|
|
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
|
String clientIp = request.getLocalAddr();
|
|
//判读IP是否合法------
|
if(!checkIp(clientIp))
|
{
|
return Result.error("非法IP调用【"+clientIp+"】");
|
}
|
if (StringUtils.isBlank(resourceId)) {
|
return Result.error("缺少resourceId参数");
|
}
|
if (null == appId) {
|
return Result.error("缺少appId参数");
|
}
|
if (StringUtils.isBlank(appUrl)) {
|
return Result.error("缺少appUrl参数");
|
}
|
|
CustomerToken cutToken=new CustomerToken();
|
cutToken.setResourceId(resourceId);
|
cutToken.setAppId(appId.toString());
|
cutToken.setAppUrl(appUrl);
|
cutToken.setUserid( userId.toString());
|
cutToken.setSubzyids(subzyids);
|
|
// 生成token
|
String token = jwtUtils.generateToken(cutToken.toString(), expireSeconds);
|
SaveTokenRecord( expireSeconds, "应用系统"+appId+"生成", token, cutToken, clientIp);
|
Map<String, Object> map = new HashMap<>();
|
map.put("token", token);
|
map.put("expire", jwtUtils.getClaimByToken(token).getExpiration());
|
Result r = Result.ok().put(map);
|
|
return r;
|
}
|
|
|
/**
|
* "?resourceId=" + resourceId
|
+ "&requestUrl=" + requestUrl + "&clientIp=" + clientIp
|
+ "&refererUrl=" + referer + "&token=" + token;
|
* 验证token 调用示例:token/validate?token=&requestUrl=&clientip=
|
* 或:token/validate?token=&requestUrl=&refererUrl=
|
* 目前日志记录有问题:loginName在Token里面,记录不到。
|
* @param token
|
* @param requestUrl
|
* @param clientIp
|
* @param refererUrl
|
* @return
|
*/
|
|
@RequestMapping(value = "/token/validate", method = { RequestMethod.POST, RequestMethod.GET })
|
public Result validate(String token, String requestUrl, String clientIp, String refererUrl,String resourceId) {
|
// 校验token
|
if (StringUtils.isBlank(token)) {
|
return Result.error(HttpStatus.SC_UNAUTHORIZED, "未传入token");
|
}
|
Claims claims = jwtUtils.getClaimByToken(token);
|
if (claims == null || jwtUtils.isTokenExpired(claims.getExpiration())) {
|
return Result.error(HttpStatus.SC_UNAUTHORIZED, "token已失效");
|
}
|
|
String msg = claims.getSubject();
|
CustomerToken cutToken=CustomerToken.fromString(msg);
|
|
String appId =cutToken.getAppId();
|
// 无appId属通过浏览器直接访问的情况:校验 clientIp 与 Token里面的IP地址是否匹配,
|
if (StringUtils.isBlank(appId)) {
|
//资源池系统采用APPToken 方式校验,解决专题地图里面图层其他用户访问IP校验不通过问题
|
//如果本地ArcMap调用资源池里面的图层后发布服务,仍然会存在其他用户访问IP校验不通过问题----lxb(延后解决)
|
|
log.info("传入IP:"+clientIp +"加密时申请IP:"+(String) cutToken.getClientIp() );
|
if (StringUtils.isBlank(clientIp) || !clientIp.equalsIgnoreCase((String) cutToken.getClientIp())) {
|
return Result.error(HttpStatus.SC_UNAUTHORIZED, "未授权的客户端");
|
}
|
|
// 有appId属通过app访问的情况:校验 refererUrl 与 Token里面的appUrl地址是否匹配
|
} else {
|
log.info("传入refererUrl:"+refererUrl +"加密时申请appUrl:"+(String) cutToken.getAppUrl() );
|
|
if (StringUtils.isBlank(refererUrl) || !refererUrl.startsWith((String) cutToken.getAppUrl())) {
|
return Result.error(HttpStatus.SC_UNAUTHORIZED, "未授权的应用系统");
|
}
|
}
|
|
//记录日志
|
saveLogAction(cutToken,resourceId);
|
//如果是专题底图,并且包含有不公开的图层资源,则返回资源ID列表.
|
Result r = Result.ok(cutToken.getSubzyids() );
|
return r;
|
}
|
|
private void saveLogAction(CustomerToken map,String resourceId){
|
ResActionRecord record = new ResActionRecord();
|
//解密 Token 里包含userid的取那值,没有取0
|
Long userid =Long.parseLong( map.getUserid()) ;//")!=null?Long.parseLong(map.get("userId").toString()):0L;
|
record.setUserid(userid);
|
Integer appid =Integer.parseInt( map.getAppId());//map.get("appId")!=null?Integer.parseInt(map.get("appId").toString()):0;
|
record.setAppid(appid);
|
record.setResourceid(resourceId.length()!=0? Integer.parseInt(resourceId):0);
|
actionRecordService.save(record);
|
}
|
|
private Boolean checkIp(String ip)
|
{
|
Boolean rsult=false ;
|
String whiteIPlist = env.getProperty("whiteIPlist");
|
if(StringUtils.contains(whiteIPlist, ip))
|
{
|
rsult=true;
|
}
|
return rsult;
|
}
|
|
|
|
/**
|
* 外部调用
|
* 临时token获取
|
* @param resourceid 资源id
|
* @param req
|
* @param expiration 失效时间
|
* @param identyinfo 备注信息 表明 token使用人
|
* @param appUrl 申请token系统地址
|
* @param isPubzy 公开级别
|
* @param appId 应用id
|
* @param applyuserid token申请人用户id
|
* @return
|
*/
|
@RequestMapping(value = "/genToken", method = RequestMethod.GET)
|
public @ResponseBody String genToken(String resourceid,HttpServletRequest req,Long expiration,String identyinfo,String appUrl,Boolean isPubzy,String appId,String applyuserid ) {
|
String clientIp = req.getLocalAddr();
|
JSONObject json=new JSONObject();
|
Jedis jedis = jedisUtils.getJedis();
|
try {
|
CustomerToken cutToken=new CustomerToken();
|
cutToken.setResourceId(resourceid);
|
cutToken.setUserid(applyuserid);
|
cutToken.setAppUrl(appUrl);
|
cutToken.setIsPubzy(isPubzy);
|
cutToken.setAppId(appId);
|
cutToken.setClientIp(req.getRemoteHost());
|
cutToken.setRemark(identyinfo);
|
String token = expiration!=null?jwtUtils.generateToken(cutToken.toString(), expiration):jwtUtils.generateToken(cutToken.toString(), expireSeconds);
|
SaveTokenRecord( expiration, identyinfo, token, cutToken, clientIp);
|
jedis.setex("zytoken:"+token,expiration!=null?expiration.intValue():expireSeconds.intValue(), "1");
|
json.put("code", 200);
|
json.put("data", token);
|
json.put("message", "获取成功");
|
return json.toJSONString();
|
} catch (Exception e) {
|
e.printStackTrace();
|
|
} finally {
|
jedis.close();
|
}
|
return "error";
|
}
|
/**
|
* 取消自动续约的Token
|
* @param token token值
|
*/
|
@RequestMapping("/token/delAutoToken")
|
public void delAutoToken(@RequestParam String token){
|
if(StringUtils.isNotEmpty(token)){
|
Jedis jedis = JedisUtils.getJedis();
|
jedis.srem("autoToken",token);
|
JedisUtils.close(jedis);
|
}
|
}
|
|
/**
|
* 记录生成的Token
|
* @param expiration 持续时间
|
* @param identyinfo 备注信息,为jwt中间的数据部分
|
* @param token token值
|
* @param cutToken token对象类
|
* @param
|
*/
|
public void SaveTokenRecord(Long expiration,String identyinfo,String token,CustomerToken cutToken,String clientIp){
|
TokenRecord record=new TokenRecord();
|
record.setApplytime(new Date());
|
record.setExpiration(expiration!=null?expiration.intValue():expireSeconds.intValue());
|
record.setResourceid(Integer.valueOf(cutToken.getResourceId()));
|
record.setIdentyinfo(identyinfo);
|
record.setTokeninfo(cutToken.toString());
|
record.setToken(token);
|
record.setTokenapplyer(clientIp);
|
logMapper.saveTokenRecord(record);
|
}
|
|
|
/**
|
* 外部调用
|
* 临时token获取
|
* @param resourceid 资源id
|
* @param req
|
* @param expiration 失效时间
|
* @param identyinfo 备注信息 表明 token使用人
|
* @param appUrl 申请token系统地址
|
* @param isPubzy 公开级别
|
* @param appId 应用id
|
* @param applyuserid token申请人用户id
|
* @return
|
*/
|
@RequestMapping(value = "/genTokenForApply", method = RequestMethod.GET)
|
public @ResponseBody String genTokenForApply(String resourceid,HttpServletRequest req,Long expiration,String identyinfo,String appUrl,Boolean isPubzy,String appId,String applyuserid,String isNever ) {
|
// 已经存在的token 直接返回token
|
Map<String, Object> param = new HashMap<>();
|
param.put("resourceid", Integer.parseInt(resourceid));
|
param.put("userid", applyuserid);
|
List<Map> maps = serverRegisterService.queryServer(param);
|
if (CollectionUtil.isNotEmpty(maps)) {
|
String tokenTemp = logservice.queryToken(param);
|
JSONObject json = new JSONObject();
|
boolean tokenIsExtend = ZiyuanRightManager.CheckTokenIsExtend(tokenTemp);
|
if (tokenIsExtend) {
|
json.put("code", 200);
|
json.put("data", tokenTemp);
|
return json.toJSONString();
|
}
|
String clientIp = req.getLocalAddr();
|
Jedis jedis = jedisUtils.getJedis();
|
try {
|
CustomerToken cutToken = new CustomerToken();
|
cutToken.setResourceId(resourceid);
|
cutToken.setUserid(applyuserid);
|
cutToken.setAppUrl(appUrl);
|
cutToken.setIsPubzy(isPubzy);
|
cutToken.setAppId(appId);
|
cutToken.setClientIp(req.getRemoteHost());
|
cutToken.setRemark(identyinfo);
|
if (expiration == null) {
|
expiration = expireSeconds * 30;
|
}
|
String token = expiration != null ? jwtUtils.generateToken(cutToken.toString(), expiration) : jwtUtils.generateToken(cutToken.toString(), expireSeconds); //默认给30天
|
SaveTokenRecord(expiration, identyinfo, token, cutToken, clientIp);
|
if (StringUtils.equals(isNever, "1")) {
|
jedis.set("zytoken:" + token, "1"); //永久有效
|
} else {
|
jedis.setex("zytoken:" + token, expiration != null ? expiration.intValue() : expireSeconds.intValue(), "1");
|
}
|
jedis.setex("zytoken:" + token, expiration != null ? expiration.intValue() : expireSeconds.intValue(), "1");
|
json.put("code", 200);
|
json.put("data", token);
|
json.put("message", "获取成功");
|
return json.toJSONString();
|
} catch (Exception e) {
|
e.printStackTrace();
|
} finally {
|
jedis.close();
|
}
|
return "error";
|
}
|
return "error";
|
}
|
}
|