114 lines
4.2 KiB
Java
114 lines
4.2 KiB
Java
package com.sunyard.chsm.service;
|
|
|
|
import com.sunyard.chsm.auth.AppUser;
|
|
import com.sunyard.chsm.constant.SecurityConstant;
|
|
import com.sunyard.chsm.enums.EnableStatus;
|
|
import com.sunyard.chsm.mapper.ApplicationMapper;
|
|
import com.sunyard.chsm.model.entity.Application;
|
|
import com.sunyard.chsm.param.AppTokenReq;
|
|
import com.sunyard.chsm.param.AppTokenResp;
|
|
import com.sunyard.chsm.utils.CodecUtils;
|
|
import com.sunyard.chsm.utils.gm.BCSM3Utils;
|
|
import io.jsonwebtoken.Claims;
|
|
import io.jsonwebtoken.Header;
|
|
import io.jsonwebtoken.Jwts;
|
|
import io.jsonwebtoken.SignatureAlgorithm;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.util.Assert;
|
|
|
|
import javax.annotation.Resource;
|
|
import javax.validation.Valid;
|
|
import java.util.Collections;
|
|
import java.util.Date;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Objects;
|
|
import java.util.UUID;
|
|
|
|
/**
|
|
* @author liulu
|
|
* @since 2024/12/5
|
|
*/
|
|
@Slf4j
|
|
@Service
|
|
public class AppLoginService {
|
|
|
|
/**
|
|
* token 过期时间, 分钟
|
|
*/
|
|
@Value("${chsm.token.expireTime:720}")
|
|
private Integer tokenExpireTime;
|
|
@Resource
|
|
private ApplicationMapper applicationMapper;
|
|
|
|
public AppTokenResp getAppToken(AppTokenReq req) {
|
|
Long random = req.getRandom();
|
|
long now = System.currentTimeMillis();
|
|
Assert.isTrue(now - random <= 5 * 60 * 1000, "请求已超时");
|
|
String appKey = req.getAppKey();
|
|
Application application = applicationMapper.selectByAppKey(appKey);
|
|
Assert.isTrue(EnableStatus.ENABLED.getCode().equals(application.getStatus()), "此应用已停用");
|
|
String data = appKey + random + application.getAppSecret();
|
|
byte[] hmac = BCSM3Utils.hmac(application.getAppSecret().getBytes(), data.getBytes());
|
|
String serverHmac = CodecUtils.encodeHex(hmac);
|
|
if (!Objects.equals(req.getHmac(), serverHmac)) {
|
|
log.warn("appKey: {}, req hmac: {}, server hmac: {}", appKey, req.getHmac(), serverHmac);
|
|
throw new IllegalArgumentException("应用认证失败");
|
|
}
|
|
AppTokenResp resp = new AppTokenResp();
|
|
resp.setToken(genToken(application));
|
|
return resp;
|
|
}
|
|
|
|
private String genToken(Application app) {
|
|
Map<String, Object> claims = new HashMap<>();
|
|
claims.put("appId", app.getId());
|
|
claims.put("name", app.getName());
|
|
claims.put("serviceIds", Collections.singletonList(app.getId()));
|
|
Date now = new Date();
|
|
return Jwts.builder()
|
|
.setHeaderParam(Header.TYPE, Header.JWT_TYPE)
|
|
.setClaims(claims)
|
|
.setIssuedAt(now)
|
|
.setExpiration(new Date(now.getTime() + tokenExpireTime * 60 * 1000))
|
|
.setId(UUID.randomUUID().toString())
|
|
.signWith(SignatureAlgorithm.HS512, SecurityConstant.JWT_SIGN_KEY)
|
|
.compact();
|
|
}
|
|
|
|
public AppTokenResp getAppTokenForTest(@Valid AppTokenReq req) {
|
|
|
|
// Long random = req.getRandom();
|
|
// long now = System.currentTimeMillis();
|
|
// Assert.isTrue(now - random <= 5 * 60 * 1000, "请求已超时");
|
|
Application application = applicationMapper.selectByAppKey(req.getAppKey());
|
|
Assert.isTrue(EnableStatus.ENABLED.getCode().equals(application.getStatus()), "此应用已停用");
|
|
if (!Objects.equals(req.getHmac(), application.getAppSecret())) {
|
|
log.warn("appKey: {}, req hmac: {},", req.getAppKey(), req.getHmac());
|
|
throw new IllegalArgumentException("应用认证失败");
|
|
}
|
|
AppTokenResp resp = new AppTokenResp();
|
|
resp.setToken(genToken(application));
|
|
return resp;
|
|
}
|
|
|
|
|
|
public AppUser verifyToken(String token) {
|
|
Claims claims = Jwts.parser()
|
|
.setSigningKey(SecurityConstant.JWT_SIGN_KEY)
|
|
.parseClaimsJws(token)
|
|
.getBody();
|
|
|
|
AppUser user = new AppUser();
|
|
user.setAppId(claims.get("appId", Long.class));
|
|
user.setName(claims.get("name", String.class));
|
|
user.setServiceIds(claims.get("serviceIds", List.class));
|
|
return user;
|
|
}
|
|
|
|
|
|
}
|