Jeecgboot使用jwt跨系统交互
阅读时间:
4
min 文章字数:
791
字 发布日期:
2025-06-27
最近更新:
2025-10-29
阅读量:
-
SSO系统API
java
package org.dromara.maxkey.web.api.jwt;
import com.nimbusds.jwt.JWTClaimsSet;
import org.dromara.maxkey.authn.jwt.AuthTokenService;
import org.dromara.maxkey.entity.apps.Apps;
import org.dromara.maxkey.entity.idm.UserInfo;
import org.dromara.maxkey.persistence.service.AppsService;
import org.dromara.maxkey.persistence.service.UserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;
@Controller
@RequestMapping(value={"/api/jwt"})
public class JwtController {
private static final Logger logger = LoggerFactory.getLogger(JwtController.class);
@Autowired
private AuthTokenService authTokenService;
@Autowired
private UserInfoService userInfoService;
@Autowired
private AppsService appsService;
@RequestMapping(value = "/gen", method = RequestMethod.GET)
@ResponseBody
public Map<String, String> gen(@RequestParam String appId, @RequestParam String subject) {
HashMap<String, String> map = new HashMap<String, String>();
// 校验用户账号是否在SSO存在
UserInfo byAppIdAndUsername = userInfoService.findByUsername(subject);
if (byAppIdAndUsername == null) {
logger.debug("用户不存在");
map.put("code", "500");
map.put("message", "用户不存在");
return map;
}
Apps apps = appsService.get(appId, false);
if (apps == null) {
logger.debug("应用不存在");
map.put("code", "500");
map.put("message", "应用不存在");
return map;
}
String issuer = "https://sso.jwimol.com/";
int expires = 315360000; // 10年
String jwt = authTokenService.genJwt(subject, issuer, expires);
map.put("code", "200");
map.put("message", "success");
logger.debug("JWT : {}", jwt);
map.put("jwt", jwt);
return map;
}
@RequestMapping(value = "/valid", method = RequestMethod.GET)
@ResponseBody
public Map<String, String> valid(@RequestParam String jwt) {
HashMap<String, String> map = new HashMap<>();
try {
boolean b = authTokenService.validateJwtToken(jwt);
if (!b) {
map.put("code", "500");
map.put("message", "JWT验证失败");
return map;
}
JWTClaimsSet resolve = authTokenService.resolve(jwt);
logger.debug("JWT : {}", resolve);
logger.debug("JWT : {}", b);
map.put("code", "200");
map.put("message", "success");
} catch (Exception e) {
logger.error("JWT : {}", e.getMessage());
map.put("code", "500");
map.put("message", "JWT验证失败");
}
return map;
}
}被调用方改造
ShiroRealm.java
java
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
log.debug("===============Shiro身份认证开始============doGetAuthenticationInfo==========");
String token = (String) auth.getCredentials();
if (token == null) {
HttpServletRequest req = SpringContextUtils.getHttpServletRequest();
log.info("————————身份认证失败——————————IP地址: "+ oConvertUtils.getIpAddrByRequest(req) +",URL:"+req.getRequestURI());
throw new AuthenticationException("token为空!");
}
// 校验token有效性
LoginUser loginUser = null;
String systemResource = MaxKeyUtil.getSystemResource(token);
if (systemResource.equals("https://sso.com/")) {
Object tokenObj = redisUtil.get("max_key_token:" + token);
if (tokenObj != null) {
String cachedToken = tokenObj.toString();
if (cachedToken != null && !cachedToken.isEmpty()) {
String username = MaxKeyUtil.getSystemUsername(token);
loginUser = TokenUtils.getLoginUser(username, commonApi, redisUtil);
}
} else if( MaxKeyUtil.isValid(token) ) {
redisUtil.set("max_key_token:" + token, token, 3600);
String username = MaxKeyUtil.getSystemUsername(token);
loginUser = TokenUtils.getLoginUser(username, commonApi, redisUtil);
} else {
JwtUtil.responseError(SpringContextUtils.getHttpServletResponse(),401,"Token失效,请重新登录!");
}
} else {
try {
loginUser = this.checkUserTokenIsEffect(token);
} catch (AuthenticationException e) {
e.printStackTrace();
JwtUtil.responseError(SpringContextUtils.getHttpServletResponse(),401,e.getMessage());
return null;
}
}
return new SimpleAuthenticationInfo(loginUser, token, getName());
}MaxKeyUtil.java
java
@Slf4j
public class MaxKeyUtil {
private static final String MAX_KEY_URL = "http://10.128.34.16/maxkey-openapi/api/jwt/valid";
/**
* 判断max_key的token是否有效
*/
public static boolean isValid(String token) {
// 参数校验
if (token == null) {
return false;
}
try {
java.net.http.HttpClient client = java.net.http.HttpClient.newHttpClient();
java.net.URI uri = java.net.URI.create(MAX_KEY_URL + "?jwt=" + token);
java.net.http.HttpRequest request = java.net.http.HttpRequest.newBuilder()
.uri(uri)
.GET()
.build();
java.net.http.HttpResponse<String> response = client.send(request, java.net.http.HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
return true;
} else {
log.error("MAX_KEY token验证失败,状态码: {}", response.statusCode());
return false;
}
} catch (Exception e) {
log.error("MAX_KEY token验证异常: ", e);
return false;
}
}
/**
* 解析token获取username
*
* @param token JWT令牌
* @return username (sub字段)
*/
public static String getSystemUsername(String token) {
try {
DecodedJWT jwt = JWT.decode(token);
String iss = jwt.getClaim("sub").asString();
if (StringUtils.isBlank(iss)) {
return "system";
}
return iss;
} catch (JWTDecodeException e) {
log.warn(e.getMessage(), e);
return "system";
}
}
/**
* 获取系统资源标识
*
* @param token
* @return
*/
public static String getSystemResource(String token) {
try {
// 解析JWT令牌并获取issuer声明
DecodedJWT jwt = JWT.decode(token);
String iss = jwt.getClaim("iss").asString();
if (StringUtils.isBlank(iss)) {
return "system";
}
return iss;
} catch (JWTDecodeException e) {
// JWT解析异常时记录警告日志并返回默认值
log.warn(e.getMessage(), e);
return "system";
}
}
}