[add]支持其他平台通过ApiKey调用系统相关接口
This commit is contained in:
@@ -9,6 +9,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.web.servlet.ServletComponentScan;
|
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
@@ -24,6 +25,7 @@ import java.util.Collections;
|
||||
@ServletComponentScan("com.genersoft.iot.vmp.conf")
|
||||
@SpringBootApplication
|
||||
@EnableScheduling
|
||||
@EnableCaching
|
||||
public class VManageBootstrap extends SpringBootServletInitializer {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(VManageBootstrap.class);
|
||||
|
||||
@@ -51,8 +51,11 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
if (StringUtils.isBlank(jwt)) {
|
||||
jwt = request.getParameter(JwtUtils.getHeader());
|
||||
if (StringUtils.isBlank(jwt)) {
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
jwt = request.getHeader(JwtUtils.getApiKeyHeader());
|
||||
if (StringUtils.isBlank(jwt)) {
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
package com.genersoft.iot.vmp.conf.security;
|
||||
|
||||
import com.genersoft.iot.vmp.conf.security.dto.JwtUser;
|
||||
import com.genersoft.iot.vmp.service.IUserApiKeyService;
|
||||
import com.genersoft.iot.vmp.service.IUserService;
|
||||
import com.genersoft.iot.vmp.storager.dao.dto.User;
|
||||
import com.genersoft.iot.vmp.storager.dao.dto.UserApiKey;
|
||||
import org.jose4j.jwk.JsonWebKey;
|
||||
import org.jose4j.jwk.JsonWebKeySet;
|
||||
import org.jose4j.jwk.RsaJsonWebKey;
|
||||
import org.jose4j.jwk.RsaJwkGenerator;
|
||||
import org.jose4j.jws.AlgorithmIdentifiers;
|
||||
@@ -20,8 +24,18 @@ import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class JwtUtils implements InitializingBean {
|
||||
@@ -30,6 +44,8 @@ public class JwtUtils implements InitializingBean {
|
||||
|
||||
public static final String HEADER = "access-token";
|
||||
|
||||
public static final String API_KEY_HEADER = "api-key";
|
||||
|
||||
private static final String AUDIENCE = "Audience";
|
||||
|
||||
private static final String keyId = "3e79646c4dbc408383a9eed09f2b85ae";
|
||||
@@ -37,17 +53,28 @@ public class JwtUtils implements InitializingBean {
|
||||
/**
|
||||
* token过期时间(分钟)
|
||||
*/
|
||||
public static final long expirationTime = 30 * 24 * 60;
|
||||
public static final long EXPIRATION_TIME = 30 * 24 * 60;
|
||||
|
||||
private static RsaJsonWebKey rsaJsonWebKey;
|
||||
|
||||
private static IUserService userService;
|
||||
|
||||
private static IUserApiKeyService userApiKeyService;
|
||||
|
||||
public static String getApiKeyHeader() {
|
||||
return API_KEY_HEADER;
|
||||
}
|
||||
|
||||
@Resource
|
||||
public void setUserService(IUserService userService) {
|
||||
JwtUtils.userService = userService;
|
||||
}
|
||||
|
||||
@Resource
|
||||
public void setUserApiKeyService(IUserApiKeyService userApiKeyService) {
|
||||
JwtUtils.userApiKeyService = userApiKeyService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
try {
|
||||
@@ -62,14 +89,38 @@ public class JwtUtils implements InitializingBean {
|
||||
* @throws JoseException JoseException
|
||||
*/
|
||||
private RsaJsonWebKey generateRsaJsonWebKey() throws JoseException {
|
||||
// 生成一个RSA密钥对,该密钥对将用于JWT的签名和验证,包装在JWK中
|
||||
RsaJsonWebKey rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);
|
||||
// 给JWK一个密钥ID
|
||||
rsaJsonWebKey.setKeyId(keyId);
|
||||
RsaJsonWebKey rsaJsonWebKey = null;
|
||||
try {
|
||||
URL url = getClass().getClassLoader().getResource("jwk.json");
|
||||
if (url != null) {
|
||||
URI uri = url.toURI();
|
||||
Path path = Paths.get(uri);
|
||||
if (Files.exists(path)) {
|
||||
byte[] allBytes = Files.readAllBytes(path);
|
||||
String jwkJson = new String(allBytes, StandardCharsets.UTF_8);
|
||||
final JsonWebKeySet jsonWebKeySet = new JsonWebKeySet(jwkJson);
|
||||
List<JsonWebKey> jsonWebKeys = jsonWebKeySet.getJsonWebKeys();
|
||||
if (!jsonWebKeys.isEmpty()) {
|
||||
JsonWebKey jsonWebKey = jsonWebKeys.get(0);
|
||||
if (jsonWebKey instanceof RsaJsonWebKey) {
|
||||
rsaJsonWebKey = (RsaJsonWebKey) jsonWebKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (URISyntaxException | IOException e) {
|
||||
// ignored
|
||||
}
|
||||
if (rsaJsonWebKey == null) {
|
||||
// 生成一个RSA密钥对,该密钥对将用于JWT的签名和验证,包装在JWK中
|
||||
rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);
|
||||
// 给JWK一个密钥ID
|
||||
rsaJsonWebKey.setKeyId(keyId);
|
||||
}
|
||||
return rsaJsonWebKey;
|
||||
}
|
||||
|
||||
public static String createToken(String username) {
|
||||
public static String createToken(String username, Long expirationTime, Map<String, Object> extra) {
|
||||
try {
|
||||
/*
|
||||
* “iss” (issuer) 发行人
|
||||
@@ -83,13 +134,17 @@ public class JwtUtils implements InitializingBean {
|
||||
claims.setGeneratedJwtId();
|
||||
claims.setIssuedAtToNow();
|
||||
// 令牌将过期的时间 分钟
|
||||
claims.setExpirationTimeMinutesInTheFuture(expirationTime);
|
||||
if (expirationTime != null) {
|
||||
claims.setExpirationTimeMinutesInTheFuture(expirationTime);
|
||||
}
|
||||
claims.setNotBeforeMinutesInThePast(0);
|
||||
claims.setSubject("login");
|
||||
claims.setAudience(AUDIENCE);
|
||||
//添加自定义参数,必须是字符串类型
|
||||
claims.setClaim("userName", username);
|
||||
|
||||
if (extra != null) {
|
||||
extra.forEach(claims::setClaim);
|
||||
}
|
||||
//jws
|
||||
JsonWebSignature jws = new JsonWebSignature();
|
||||
//签名算法RS256
|
||||
@@ -104,10 +159,17 @@ public class JwtUtils implements InitializingBean {
|
||||
} catch (JoseException e) {
|
||||
logger.error("[Token生成失败]: {}", e.getMessage());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String createToken(String username, Long expirationTime) {
|
||||
return createToken(username, expirationTime, null);
|
||||
}
|
||||
|
||||
public static String createToken(String username) {
|
||||
return createToken(username, EXPIRATION_TIME);
|
||||
}
|
||||
|
||||
public static String getHeader() {
|
||||
return HEADER;
|
||||
}
|
||||
@@ -118,8 +180,8 @@ public class JwtUtils implements InitializingBean {
|
||||
|
||||
try {
|
||||
JwtConsumer consumer = new JwtConsumerBuilder()
|
||||
.setRequireExpirationTime()
|
||||
.setMaxFutureValidityInMinutes(5256000)
|
||||
//.setRequireExpirationTime()
|
||||
//.setMaxFutureValidityInMinutes(5256000)
|
||||
.setAllowedClockSkewInSeconds(30)
|
||||
.setRequireSubject()
|
||||
//.setExpectedIssuer("")
|
||||
@@ -129,15 +191,27 @@ public class JwtUtils implements InitializingBean {
|
||||
|
||||
JwtClaims claims = consumer.processToClaims(token);
|
||||
NumericDate expirationTime = claims.getExpirationTime();
|
||||
// 判断是否即将过期, 默认剩余时间小于5分钟未即将过期
|
||||
// 剩余时间 (秒)
|
||||
long timeRemaining = LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8)) - expirationTime.getValue();
|
||||
if (timeRemaining < 5 * 60) {
|
||||
jwtUser.setStatus(JwtUser.TokenStatus.EXPIRING_SOON);
|
||||
if (expirationTime != null) {
|
||||
// 判断是否即将过期, 默认剩余时间小于5分钟未即将过期
|
||||
// 剩余时间 (秒)
|
||||
long timeRemaining = LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8)) - expirationTime.getValue();
|
||||
if (timeRemaining < 5 * 60) {
|
||||
jwtUser.setStatus(JwtUser.TokenStatus.EXPIRING_SOON);
|
||||
} else {
|
||||
jwtUser.setStatus(JwtUser.TokenStatus.NORMAL);
|
||||
}
|
||||
} else {
|
||||
jwtUser.setStatus(JwtUser.TokenStatus.NORMAL);
|
||||
}
|
||||
|
||||
Long apiKeyId = claims.getClaimValue("apiKeyId", Long.class);
|
||||
if (apiKeyId != null) {
|
||||
UserApiKey userApiKey = userApiKeyService.getUserApiKeyById(apiKeyId.intValue());
|
||||
if (userApiKey == null || !userApiKey.isEnable()) {
|
||||
jwtUser.setStatus(JwtUser.TokenStatus.EXPIRED);
|
||||
}
|
||||
}
|
||||
|
||||
String username = (String) claims.getClaimValue("userName");
|
||||
User user = userService.getUserByUsername(username);
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.genersoft.iot.vmp.service;
|
||||
|
||||
import com.genersoft.iot.vmp.storager.dao.dto.UserApiKey;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
|
||||
public interface IUserApiKeyService {
|
||||
int addApiKey(UserApiKey userApiKey);
|
||||
|
||||
boolean isApiKeyExists(String apiKey);
|
||||
|
||||
PageInfo<UserApiKey> getUserApiKeys(int page, int count);
|
||||
|
||||
int enable(Integer id);
|
||||
|
||||
int disable(Integer id);
|
||||
|
||||
int remark(Integer id, String remark);
|
||||
|
||||
int delete(Integer id);
|
||||
|
||||
UserApiKey getUserApiKeyById(Integer id);
|
||||
|
||||
int reset(Integer id, String apiKey);
|
||||
|
||||
}
|
||||
@@ -11,6 +11,8 @@ public interface IUserService {
|
||||
|
||||
boolean changePassword(int id, String password);
|
||||
|
||||
User getUserById(int id);
|
||||
|
||||
User getUserByUsername(String username);
|
||||
|
||||
int addUser(User user);
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.genersoft.iot.vmp.service.impl;
|
||||
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import com.genersoft.iot.vmp.service.IUserApiKeyService;
|
||||
import com.genersoft.iot.vmp.storager.dao.UserApiKeyMapper;
|
||||
import com.genersoft.iot.vmp.storager.dao.dto.UserApiKey;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@DS("master")
|
||||
public class UserApiKeyServiceImpl implements IUserApiKeyService {
|
||||
|
||||
@Autowired
|
||||
UserApiKeyMapper userApiKeyMapper;
|
||||
|
||||
@Autowired
|
||||
private RedisTemplate<Object, Object> redisTemplate;
|
||||
|
||||
@Override
|
||||
public int addApiKey(UserApiKey userApiKey) {
|
||||
return userApiKeyMapper.add(userApiKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApiKeyExists(String apiKey) {
|
||||
return userApiKeyMapper.isApiKeyExists(apiKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageInfo<UserApiKey> getUserApiKeys(int page, int count) {
|
||||
PageHelper.startPage(page, count);
|
||||
List<UserApiKey> userApiKeys = userApiKeyMapper.getUserApiKeys();
|
||||
return new PageInfo<>(userApiKeys);
|
||||
}
|
||||
|
||||
@Cacheable(cacheNames = "userApiKey", key = "#id", sync = true)
|
||||
@Override
|
||||
public UserApiKey getUserApiKeyById(Integer id) {
|
||||
return userApiKeyMapper.selectById(id);
|
||||
}
|
||||
|
||||
@CacheEvict(cacheNames = "userApiKey", key = "#id")
|
||||
@Override
|
||||
public int enable(Integer id) {
|
||||
return userApiKeyMapper.enable(id);
|
||||
}
|
||||
|
||||
@CacheEvict(cacheNames = "userApiKey", key = "#id")
|
||||
@Override
|
||||
public int disable(Integer id) {
|
||||
return userApiKeyMapper.disable(id);
|
||||
}
|
||||
|
||||
@CacheEvict(cacheNames = "userApiKey", key = "#id")
|
||||
@Override
|
||||
public int remark(Integer id, String remark) {
|
||||
return userApiKeyMapper.remark(id, remark);
|
||||
}
|
||||
|
||||
@CacheEvict(cacheNames = "userApiKey", key = "#id")
|
||||
@Override
|
||||
public int delete(Integer id) {
|
||||
return userApiKeyMapper.delete(id);
|
||||
}
|
||||
|
||||
@CacheEvict(cacheNames = "userApiKey", key = "#id")
|
||||
@Override
|
||||
public int reset(Integer id, String apiKey) {
|
||||
return userApiKeyMapper.apiKey(id, apiKey);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,6 +31,11 @@ public class UserServiceImpl implements IUserService {
|
||||
return userMapper.update(user) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getUserById(int id) {
|
||||
return userMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getUserByUsername(String username) {
|
||||
return userMapper.getUserByUsername(username);
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.genersoft.iot.vmp.storager.dao;
|
||||
|
||||
import com.genersoft.iot.vmp.storager.dao.dto.UserApiKey;
|
||||
import org.apache.ibatis.annotations.*;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
@Repository
|
||||
public interface UserApiKeyMapper {
|
||||
|
||||
@SelectKey(statement = "SELECT LAST_INSERT_ID() AS id", keyProperty = "id", before = false, resultType = Integer.class)
|
||||
@Insert("INSERT INTO wvp_user_api_key (user_id, app, api_key, expired_at, remark, enable, create_time, update_time) VALUES" +
|
||||
"(#{userId}, #{app}, #{apiKey}, #{expiredAt}, #{remark}, #{enable}, #{createTime}, #{updateTime})")
|
||||
int add(UserApiKey userApiKey);
|
||||
|
||||
@Update(value = {"<script>" +
|
||||
"UPDATE wvp_user_api_key " +
|
||||
"SET update_time = #{updateTime} " +
|
||||
"<if test=\"app != null\">, app = #{app}</if>" +
|
||||
"<if test=\"apiKey != null\">, api_key = #{apiKey}</if>" +
|
||||
"<if test=\"expiredAt != null\">, expired_at = #{expiredAt}</if>" +
|
||||
"<if test=\"remark != null\">, username = #{remark}</if>" +
|
||||
"<if test=\"enable != null\">, enable = #{enable}</if>" +
|
||||
"WHERE id = #{id}" +
|
||||
" </script>"})
|
||||
int update(UserApiKey userApiKey);
|
||||
|
||||
@Update("UPDATE wvp_user_api_key SET enable = true WHERE id = #{id}")
|
||||
int enable(@Param("id") int id);
|
||||
|
||||
@Update("UPDATE wvp_user_api_key SET enable = false WHERE id = #{id}")
|
||||
int disable(@Param("id") int id);
|
||||
|
||||
@Update("UPDATE wvp_user_api_key SET api_key = #{apiKey} WHERE id = #{id}")
|
||||
int apiKey(@Param("id") int id, @Param("apiKey") String apiKey);
|
||||
|
||||
@Update("UPDATE wvp_user_api_key SET remark = #{remark} WHERE id = #{id}")
|
||||
int remark(@Param("id") int id, @Param("remark") String remark);
|
||||
|
||||
@Delete("DELETE FROM wvp_user_api_key WHERE id = #{id}")
|
||||
int delete(@Param("id") int id);
|
||||
|
||||
@Select("SELECT uak.id, uak.user_id, uak.app, uak.api_key, uak.expired_at, uak.remark, uak.enable, uak.create_time, uak.update_time, u.username AS username FROM wvp_user_api_key uak LEFT JOIN wvp_user u on u.id = uak.user_id WHERE uak.id = #{id}")
|
||||
UserApiKey selectById(@Param("id") int id);
|
||||
|
||||
@Select("SELECT uak.id, uak.user_id, uak.app, uak.api_key, uak.expired_at, uak.remark, uak.enable, uak.create_time, uak.update_time, u.username AS username FROM wvp_user_api_key uak LEFT JOIN wvp_user u on u.id = uak.user_id WHERE uak.api_key = #{apiKey}")
|
||||
UserApiKey selectByApiKey(@Param("apiKey") String apiKey);
|
||||
|
||||
@Select("SELECT uak.id, uak.user_id, uak.app, uak.api_key, uak.expired_at, uak.remark, uak.enable, uak.create_time, uak.update_time, u.username AS username FROM wvp_user_api_key uak LEFT JOIN wvp_user u on u.id = uak.user_id")
|
||||
List<UserApiKey> selectAll();
|
||||
|
||||
@Select("SELECT uak.id, uak.user_id, uak.app, uak.api_key, uak.expired_at, uak.remark, uak.enable, uak.create_time, uak.update_time, u.username AS username FROM wvp_user_api_key uak LEFT JOIN wvp_user u on u.id = uak.user_id")
|
||||
List<UserApiKey> getUserApiKeys();
|
||||
|
||||
@Select("SELECT COUNT(0) FROM wvp_user_api_key WHERE api_key = #{apiKey}")
|
||||
boolean isApiKeyExists(@Param("apiKey") String apiKey);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
package com.genersoft.iot.vmp.storager.dao.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 用户信息
|
||||
*/
|
||||
@Schema(description = "用户ApiKey信息")
|
||||
public class UserApiKey implements Serializable {
|
||||
|
||||
/**
|
||||
* Id
|
||||
*/
|
||||
@Schema(description = "Id")
|
||||
private int id;
|
||||
|
||||
/**
|
||||
* 用户Id
|
||||
*/
|
||||
@Schema(description = "用户Id")
|
||||
private int userId;
|
||||
|
||||
/**
|
||||
* 应用名
|
||||
*/
|
||||
@Schema(description = "应用名")
|
||||
private String app;
|
||||
|
||||
/**
|
||||
* ApiKey
|
||||
*/
|
||||
@Schema(description = "ApiKey")
|
||||
private String apiKey;
|
||||
|
||||
/**
|
||||
* 过期时间(null=永不过期)
|
||||
*/
|
||||
@Schema(description = "过期时间(null=永不过期)")
|
||||
private String expiredAt;
|
||||
|
||||
/**
|
||||
* 备注信息
|
||||
*/
|
||||
@Schema(description = "备注信息")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 是否启用
|
||||
*/
|
||||
@Schema(description = "是否启用")
|
||||
private boolean enable;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@Schema(description = "创建时间")
|
||||
private String createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@Schema(description = "更新时间")
|
||||
private String updateTime;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String username;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(int userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getApp() {
|
||||
return app;
|
||||
}
|
||||
|
||||
public void setApp(String app) {
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
public String getApiKey() {
|
||||
return apiKey;
|
||||
}
|
||||
|
||||
public void setApiKey(String apiKey) {
|
||||
this.apiKey = apiKey;
|
||||
}
|
||||
|
||||
public String getExpiredAt() {
|
||||
return expiredAt;
|
||||
}
|
||||
|
||||
public void setExpiredAt(String expiredAt) {
|
||||
this.expiredAt = expiredAt;
|
||||
}
|
||||
|
||||
public String getRemark() {
|
||||
return remark;
|
||||
}
|
||||
|
||||
public void setRemark(String remark) {
|
||||
this.remark = remark;
|
||||
}
|
||||
|
||||
public boolean isEnable() {
|
||||
return enable;
|
||||
}
|
||||
|
||||
public void setEnable(boolean enable) {
|
||||
this.enable = enable;
|
||||
}
|
||||
|
||||
public String getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(String createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public String getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(String updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
package com.genersoft.iot.vmp.vmanager.user;
|
||||
|
||||
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||
import com.genersoft.iot.vmp.conf.security.JwtUtils;
|
||||
import com.genersoft.iot.vmp.conf.security.SecurityUtils;
|
||||
import com.genersoft.iot.vmp.service.IUserApiKeyService;
|
||||
import com.genersoft.iot.vmp.service.IUserService;
|
||||
import com.genersoft.iot.vmp.storager.dao.dto.User;
|
||||
import com.genersoft.iot.vmp.storager.dao.dto.UserApiKey;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Tag(name = "用户ApiKey管理")
|
||||
@RestController
|
||||
@RequestMapping("/api/userApiKey")
|
||||
public class UserApiKeyController {
|
||||
|
||||
public static final int EXPIRATION_TIME = Integer.MAX_VALUE;
|
||||
@Autowired
|
||||
private IUserService userService;
|
||||
|
||||
@Autowired
|
||||
private IUserApiKeyService userApiKeyService;
|
||||
|
||||
/**
|
||||
* 添加用户ApiKey
|
||||
*
|
||||
* @param userId
|
||||
* @param app
|
||||
* @param remark
|
||||
* @param expiresAt
|
||||
* @param enable
|
||||
*/
|
||||
@PostMapping("/add")
|
||||
@Operation(summary = "添加用户ApiKey", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "userId", description = "用户Id", required = true)
|
||||
@Parameter(name = "app", description = "应用名称", required = false)
|
||||
@Parameter(name = "remark", description = "备注信息", required = false)
|
||||
@Parameter(name = "expiredAt", description = "过期时间(不传代表永不过期)", required = false)
|
||||
@Transactional
|
||||
public synchronized void add(
|
||||
@RequestParam(required = true) int userId,
|
||||
@RequestParam(required = false) String app,
|
||||
@RequestParam(required = false) String remark,
|
||||
@RequestParam(required = false) String expiresAt,
|
||||
@RequestParam(required = false) Boolean enable
|
||||
) {
|
||||
User user = userService.getUserById(userId);
|
||||
if (user == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR400.getCode(), "用户不存在");
|
||||
}
|
||||
|
||||
Long expirationTime = null;
|
||||
if (expiresAt != null) {
|
||||
long timestamp = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestampMs(expiresAt);
|
||||
expirationTime = (timestamp - System.currentTimeMillis()) / (60 * 1000);
|
||||
if (expirationTime < 0) {
|
||||
throw new ControllerException(ErrorCode.ERROR400.getCode(), "过期时间不能早于当前时间");
|
||||
}
|
||||
}
|
||||
|
||||
UserApiKey userApiKey = new UserApiKey();
|
||||
userApiKey.setUserId(userId);
|
||||
userApiKey.setApp(app);
|
||||
userApiKey.setApiKey(null);
|
||||
userApiKey.setRemark(remark);
|
||||
userApiKey.setExpiredAt(expiresAt);
|
||||
userApiKey.setEnable(enable != null ? enable : false);
|
||||
userApiKey.setCreateTime(DateUtil.getNow());
|
||||
userApiKey.setUpdateTime(DateUtil.getNow());
|
||||
|
||||
int addResult = userApiKeyService.addApiKey(userApiKey);
|
||||
|
||||
if (addResult <= 0) {
|
||||
throw new ControllerException(ErrorCode.ERROR100);
|
||||
}
|
||||
|
||||
String apiKey;
|
||||
do {
|
||||
Map<String, Object> extra = new HashMap<>(1);
|
||||
extra.put("apiKeyId", userApiKey.getId());
|
||||
apiKey = JwtUtils.createToken(user.getUsername(), expirationTime, extra);
|
||||
} while (userApiKeyService.isApiKeyExists(apiKey));
|
||||
|
||||
int resetResult = userApiKeyService.reset(userApiKey.getId(), apiKey);
|
||||
|
||||
if (resetResult <= 0) {
|
||||
throw new ControllerException(ErrorCode.ERROR100);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询ApiKey
|
||||
*
|
||||
* @param page 当前页
|
||||
* @param count 每页查询数量
|
||||
* @return 分页ApiKey列表
|
||||
*/
|
||||
@GetMapping("/userApiKeys")
|
||||
@Operation(summary = "分页查询用户", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "page", description = "当前页", required = true)
|
||||
@Parameter(name = "count", description = "每页查询数量", required = true)
|
||||
@Transactional
|
||||
public PageInfo<UserApiKey> userApiKeys(@RequestParam(required = true) int page, @RequestParam(required = true) int count) {
|
||||
return userApiKeyService.getUserApiKeys(page, count);
|
||||
}
|
||||
|
||||
@PostMapping("/enable")
|
||||
@Operation(summary = "启用用户ApiKey", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "id", description = "用户ApiKeyId", required = true)
|
||||
@Transactional
|
||||
public void enable(@RequestParam(required = true) Integer id) {
|
||||
// 获取当前登录用户id
|
||||
int currenRoleId = SecurityUtils.getUserInfo().getRole().getId();
|
||||
if (currenRoleId != 1) {
|
||||
// 只用角色id为1才可以管理UserApiKey
|
||||
throw new ControllerException(ErrorCode.ERROR403);
|
||||
}
|
||||
UserApiKey userApiKey = userApiKeyService.getUserApiKeyById(id);
|
||||
if (userApiKey == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR400.getCode(), "ApiKey不存在");
|
||||
}
|
||||
|
||||
int enableResult = userApiKeyService.enable(id);
|
||||
|
||||
if (enableResult <= 0) {
|
||||
throw new ControllerException(ErrorCode.ERROR100);
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/disable")
|
||||
@Operation(summary = "停用用户ApiKey", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "id", description = "用户ApiKeyId", required = true)
|
||||
@Transactional
|
||||
public void disable(@RequestParam(required = true) Integer id) {
|
||||
// 获取当前登录用户id
|
||||
int currenRoleId = SecurityUtils.getUserInfo().getRole().getId();
|
||||
if (currenRoleId != 1) {
|
||||
// 只用角色id为1才可以管理UserApiKey
|
||||
throw new ControllerException(ErrorCode.ERROR403);
|
||||
}
|
||||
UserApiKey userApiKey = userApiKeyService.getUserApiKeyById(id);
|
||||
if (userApiKey == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR400.getCode(), "ApiKey不存在");
|
||||
}
|
||||
|
||||
int disableResult = userApiKeyService.disable(id);
|
||||
|
||||
if (disableResult <= 0) {
|
||||
throw new ControllerException(ErrorCode.ERROR100);
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/reset")
|
||||
@Operation(summary = "重置用户ApiKey", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "id", description = "用户ApiKeyId", required = true)
|
||||
@Transactional
|
||||
public void reset(@RequestParam(required = true) Integer id) {
|
||||
// 获取当前登录用户id
|
||||
int currenRoleId = SecurityUtils.getUserInfo().getRole().getId();
|
||||
if (currenRoleId != 1) {
|
||||
// 只用角色id为1才可以管理UserApiKey
|
||||
throw new ControllerException(ErrorCode.ERROR403);
|
||||
}
|
||||
UserApiKey userApiKey = userApiKeyService.getUserApiKeyById(id);
|
||||
if (userApiKey == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR400.getCode(), "ApiKey不存在");
|
||||
}
|
||||
User user = userService.getUserById(userApiKey.getUserId());
|
||||
if (user == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR400.getCode(), "用户不存在");
|
||||
}
|
||||
Long expirationTime = null;
|
||||
if (userApiKey.getExpiredAt() != null) {
|
||||
long timestamp = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestampMs(userApiKey.getExpiredAt());
|
||||
expirationTime = (timestamp - System.currentTimeMillis()) / (60 * 1000);
|
||||
if (expirationTime < 0) {
|
||||
throw new ControllerException(ErrorCode.ERROR400.getCode(), "ApiKey已失效");
|
||||
}
|
||||
}
|
||||
String apiKey;
|
||||
do {
|
||||
Map<String, Object> extra = new HashMap<>(1);
|
||||
extra.put("apiKeyId", userApiKey.getId());
|
||||
apiKey = JwtUtils.createToken(user.getUsername(), expirationTime, extra);
|
||||
} while (userApiKeyService.isApiKeyExists(apiKey));
|
||||
|
||||
int resetResult = userApiKeyService.reset(id, apiKey);
|
||||
|
||||
if (resetResult <= 0) {
|
||||
throw new ControllerException(ErrorCode.ERROR100);
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/remark")
|
||||
@Operation(summary = "备注用户ApiKey", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "id", description = "用户ApiKeyId", required = true)
|
||||
@Parameter(name = "remark", description = "用户ApiKey备注", required = false)
|
||||
@Transactional
|
||||
public void remark(@RequestParam(required = true) Integer id, @RequestParam(required = false) String remark) {
|
||||
// 获取当前登录用户id
|
||||
int currenRoleId = SecurityUtils.getUserInfo().getRole().getId();
|
||||
if (currenRoleId != 1) {
|
||||
// 只用角色id为1才可以管理UserApiKey
|
||||
throw new ControllerException(ErrorCode.ERROR403);
|
||||
}
|
||||
UserApiKey userApiKey = userApiKeyService.getUserApiKeyById(id);
|
||||
if (userApiKey == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR400.getCode(), "ApiKey不存在");
|
||||
}
|
||||
int remarkResult = userApiKeyService.remark(id, remark);
|
||||
|
||||
if (remarkResult <= 0) {
|
||||
throw new ControllerException(ErrorCode.ERROR100);
|
||||
}
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除用户ApiKey", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "id", description = "用户ApiKeyId", required = true)
|
||||
@Transactional
|
||||
public void delete(@RequestParam(required = true) Integer id) {
|
||||
// 获取当前登录用户id
|
||||
int currenRoleId = SecurityUtils.getUserInfo().getRole().getId();
|
||||
if (currenRoleId != 1) {
|
||||
// 只用角色id为1才可以管理UserApiKey
|
||||
throw new ControllerException(ErrorCode.ERROR403);
|
||||
}
|
||||
UserApiKey userApiKey = userApiKeyService.getUserApiKeyById(id);
|
||||
if (userApiKey == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR400.getCode(), "ApiKey不存在");
|
||||
}
|
||||
|
||||
int deleteResult = userApiKeyService.delete(id);
|
||||
|
||||
if (deleteResult <= 0) {
|
||||
throw new ControllerException(ErrorCode.ERROR100);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user