From 74d88a8fcce6539d62ac7da622d3f2888c03e6cf Mon Sep 17 00:00:00 2001 From: EightMonth Date: Thu, 4 Jan 2024 11:09:58 +0800 Subject: [PATCH 1/3] =?UTF-8?q?springboot=20sas=E5=8D=87=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jeecg-boot-base-core/pom.xml | 14 + .../java/org/jeecg/common/api/CommonAPI.java | 20 ++ .../jeecg/common/aspect/AutoLogAspect.java | 4 +- .../exception/JeecgBootExceptionHandler.java | 19 ++ .../exception/JeecgCaptchaException.java | 28 ++ .../base/controller/JeecgController.java | 6 +- .../org/jeecg/common/system/util/JwtUtil.java | 8 +- .../org/jeecg/common/system/vo/LoginUser.java | 34 ++- ...edisOAuth2AuthorizationConsentService.java | 51 ++++ .../JeecgRedisOAuth2AuthorizationService.java | 180 +++++++++++ .../jeecg/config/security/SecurityConfig.java | 271 +++++++++++++++++ .../PasswordGrantAuthenticationConvert.java | 80 +++++ .../PasswordGrantAuthenticationProvider.java | 283 ++++++++++++++++++ .../PasswordGrantAuthenticationToken.java | 19 ++ .../org/jeecg/config/shiro/ShiroConfig.java | 2 +- .../org/jeecg/config/shiro/ShiroRealm.java | 2 +- .../test/controller/JeecgDemoController.java | 4 +- .../controller/JeecgOrderMainController.java | 4 +- .../service/impl/JeecgDemoServiceImpl.java | 4 +- .../api/fallback/SysBaseAPIFallback.java | 14 + .../modules/aop/TenantPackUserLogAspect.java | 4 +- .../controller/QuartzJobController.java | 4 +- .../system/controller/LoginController.java | 4 +- .../controller/SysAnnouncementController.java | 8 +- .../SysAnnouncementSendController.java | 8 +- .../controller/SysCategoryController.java | 3 +- .../controller/SysCommentController.java | 4 +- .../controller/SysDepartController.java | 6 +- .../SysDepartPermissionController.java | 4 +- .../controller/SysDepartRoleController.java | 6 +- .../system/controller/SysDictController.java | 3 +- .../controller/SysPermissionController.java | 13 +- .../controller/SysPositionController.java | 3 +- .../system/controller/SysRoleController.java | 6 +- .../controller/SysTenantController.java | 30 +- .../system/controller/ThirdAppController.java | 6 +- .../modules/system/entity/SysDataLog.java | 4 +- .../impl/SysAnnouncementServiceImpl.java | 10 +- .../system/service/impl/SysBaseApiImpl.java | 24 +- .../service/impl/SysDepartServiceImpl.java | 4 +- .../impl/SysTenantPackServiceImpl.java | 4 +- .../service/impl/SysTenantServiceImpl.java | 12 +- .../impl/SysThirdAccountServiceImpl.java | 4 +- .../impl/SysUserDepartServiceImpl.java | 6 +- .../service/impl/SysUserServiceImpl.java | 6 +- .../src/main/resources/application-dev.yml | 8 +- .../src/main/resources/application-prod.yml | 19 +- 47 files changed, 1174 insertions(+), 86 deletions(-) create mode 100644 jeecg-boot-base-core/src/main/java/org/jeecg/common/exception/JeecgCaptchaException.java create mode 100644 jeecg-boot-base-core/src/main/java/org/jeecg/config/security/JeecgRedisOAuth2AuthorizationConsentService.java create mode 100644 jeecg-boot-base-core/src/main/java/org/jeecg/config/security/JeecgRedisOAuth2AuthorizationService.java create mode 100644 jeecg-boot-base-core/src/main/java/org/jeecg/config/security/SecurityConfig.java create mode 100644 jeecg-boot-base-core/src/main/java/org/jeecg/config/security/password/PasswordGrantAuthenticationConvert.java create mode 100644 jeecg-boot-base-core/src/main/java/org/jeecg/config/security/password/PasswordGrantAuthenticationProvider.java create mode 100644 jeecg-boot-base-core/src/main/java/org/jeecg/config/security/password/PasswordGrantAuthenticationToken.java diff --git a/jeecg-boot-base-core/pom.xml b/jeecg-boot-base-core/pom.xml index b8bb6cbd7..018a026c0 100644 --- a/jeecg-boot-base-core/pom.xml +++ b/jeecg-boot-base-core/pom.xml @@ -230,6 +230,20 @@ + + + org.springframework.boot + spring-boot-starter-oauth2-authorization-server + + + org.springframework.boot + spring-boot-starter-oauth2-resource-server + + + + org.springframework.security + spring-security-cas + org.apache.shiro diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/api/CommonAPI.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/api/CommonAPI.java index 97823987c..0013f4ef4 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/common/api/CommonAPI.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/api/CommonAPI.java @@ -127,4 +127,24 @@ public interface CommonAPI { */ List translateDictFromTableByKeys(String table, String text, String code, String keys); + /** + * 登录加载系统字典 + * @return + */ + Map> queryAllDictItems(); + + /** + * 查询SysDepart集合 + * @param userId + * @return + */ + List queryUserDeparts(String userId); + + /** + * 根据用户名设置部门ID + * @param username + * @param orgCode + */ + void updateUserDepart(String username,String orgCode,Integer loginTenantId); + } diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/AutoLogAspect.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/AutoLogAspect.java index 71f97672c..44443e0cb 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/AutoLogAspect.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/AutoLogAspect.java @@ -1,5 +1,6 @@ package org.jeecg.common.aspect; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.serializer.PropertyFilter; import org.apache.shiro.SecurityUtils; @@ -21,6 +22,7 @@ import org.jeecg.common.util.IpUtils; import org.jeecg.common.util.SpringContextUtils; import org.jeecg.common.util.oConvertUtils; import org.springframework.core.LocalVariableTableParameterNameDiscoverer; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; import org.springframework.validation.BindingResult; import org.springframework.web.multipart.MultipartFile; @@ -100,7 +102,7 @@ public class AutoLogAspect { //设置IP地址 dto.setIp(IpUtils.getIpAddr(request)); //获取登录用户信息 - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; if(sysUser!=null){ dto.setUserid(sysUser.getUsername()); dto.setUsername(sysUser.getRealname()); diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/exception/JeecgBootExceptionHandler.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/exception/JeecgBootExceptionHandler.java index 82e19cf9f..6e92c2c64 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/common/exception/JeecgBootExceptionHandler.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/exception/JeecgBootExceptionHandler.java @@ -17,6 +17,8 @@ import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.multipart.MaxUploadSizeExceededException; import org.springframework.web.servlet.NoHandlerFoundException; +import javax.naming.AuthenticationException; + /** * 异常处理器 * @@ -27,6 +29,23 @@ import org.springframework.web.servlet.NoHandlerFoundException; @Slf4j public class JeecgBootExceptionHandler { + /** + * 验证码错误异常 + */ + + @ExceptionHandler(JeecgCaptchaException.class) + public Result handleJeecgCaptchaException(JeecgCaptchaException e) { + log.error(e.getMessage(), e); + return Result.error(e.getCode(), e.getMessage()); + } + + @ExceptionHandler(AuthenticationException.class) + @ResponseStatus(HttpStatus.UNAUTHORIZED) + public Result handleJeecgCaptchaException(AuthenticationException e) { + log.error(e.getMessage(), e); + return Result.error(401, e.getMessage()); + } + /** * 处理自定义异常 */ diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/exception/JeecgCaptchaException.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/exception/JeecgCaptchaException.java new file mode 100644 index 000000000..cf2777a39 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/exception/JeecgCaptchaException.java @@ -0,0 +1,28 @@ +package org.jeecg.common.exception; + +import lombok.Data; + +/** + * @author kezhijie@wuhandsj.com + * @date 2024/1/2 11:38 + */ +@Data +public class JeecgCaptchaException extends RuntimeException{ + + private Integer code; + + private static final long serialVersionUID = -9093410345065209053L; + + public JeecgCaptchaException(Integer code, String message) { + super(message); + this.code = code; + } + + public JeecgCaptchaException(String message, Throwable cause) { + super(message, cause); + } + + public JeecgCaptchaException(Throwable cause) { + super(cause); + } +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/base/controller/JeecgController.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/base/controller/JeecgController.java index b4505d78b..e9f577276 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/base/controller/JeecgController.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/base/controller/JeecgController.java @@ -1,5 +1,6 @@ package org.jeecg.common.system.base.controller; +import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -19,6 +20,7 @@ import org.jeecgframework.poi.excel.entity.ImportParams; import org.jeecgframework.poi.excel.entity.enmus.ExcelType; import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.servlet.ModelAndView; @@ -51,7 +53,7 @@ public class JeecgController> { protected ModelAndView exportXls(HttpServletRequest request, T object, Class clazz, String title) { // Step.1 组装查询条件 QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(object, request.getParameterMap()); - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; // 过滤选中数据 String selections = request.getParameter("selections"); @@ -89,7 +91,7 @@ public class JeecgController> { protected ModelAndView exportXlsSheet(HttpServletRequest request, T object, Class clazz, String title,String exportFields,Integer pageNum) { // Step.1 组装查询条件 QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(object, request.getParameterMap()); - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; // Step.2 计算分页sheet数据 double total = service.count(); int count = (int)Math.ceil(total/pageNum); diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/util/JwtUtil.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/util/JwtUtil.java index 7365ece60..a059f857d 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/util/JwtUtil.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/util/JwtUtil.java @@ -1,5 +1,7 @@ package org.jeecg.common.system.util; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSONObject; import com.auth0.jwt.JWT; import com.auth0.jwt.JWTVerifier; import com.auth0.jwt.algorithms.Algorithm; @@ -29,6 +31,7 @@ import org.jeecg.common.system.vo.SysUserCacheInfo; import org.jeecg.common.util.DateUtils; import org.jeecg.common.util.SpringContextUtils; import org.jeecg.common.util.oConvertUtils; +import org.springframework.security.core.context.SecurityContextHolder; /** * @Author Scott @@ -95,7 +98,8 @@ public class JwtUtil { public static String getUsername(String token) { try { DecodedJWT jwt = JWT.decode(token); - return jwt.getClaim("username").asString(); + LoginUser loginUser = JSONObject.parseObject(jwt.getClaim("sub").asString(), LoginUser.class); + return loginUser.getUsername(); } catch (JWTDecodeException e) { return null; } @@ -177,7 +181,7 @@ public class JwtUtil { //2.通过shiro获取登录用户信息 LoginUser sysUser = null; try { - sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; } catch (Exception e) { log.warn("SecurityUtils.getSubject() 获取用户信息异常:" + e.getMessage()); } diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/vo/LoginUser.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/vo/LoginUser.java index 44656a7f8..c0a83364c 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/vo/LoginUser.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/vo/LoginUser.java @@ -7,6 +7,8 @@ import lombok.experimental.Accessors; import org.jeecg.common.desensitization.annotation.SensitiveField; import org.springframework.format.annotation.DateTimeFormat; +import java.io.Serializable; +import java.text.SimpleDateFormat; import java.util.Date; /** @@ -20,8 +22,10 @@ import java.util.Date; @Data @EqualsAndHashCode(callSuper = false) @Accessors(chain = true) -public class LoginUser { +public class LoginUser implements Serializable { + + private static final long serialVersionUID = -7143159031677245866L; /** * 登录人id */ @@ -127,4 +131,32 @@ public class LoginUser { /**设备id uniapp推送用*/ private String clientId; + @SensitiveField + private String salt; + + @Override + public String toString() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return "{" + + "\"id\":\"" + id + '"' + + ", \"username\":\"" + username + '"' + + ", \"realname\":\"" + realname + '"' + + ", \"password\":\"'" + password + '"' + + ", \"orgCode\":\"" + orgCode + '"' + + ", \"avatar\":\"" + avatar + '"' + + ", \"sex\":" + sex + + ", \"email\":\"" + email + '"' + + ", \"phone\":\"" + phone + '"' + + ", \"status\":" + status + + ", \"delFlag\":" + delFlag + + ", \"activitiSync\":" + activitiSync + + ", \"userIdentity\":" + userIdentity + + ", \"departIds\":\"" + departIds + '"' + + ", \"post\":\"" + post + '"' + + ", \"telephone\":\"" + telephone + '"' + + ", \"relTenantIds\":\"" + relTenantIds + '"' + + ", \"clientId\":\"" + clientId + '"' + + ", \"salt\":\"" + salt + '"' + + '}'; + } } diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/JeecgRedisOAuth2AuthorizationConsentService.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/JeecgRedisOAuth2AuthorizationConsentService.java new file mode 100644 index 000000000..5ca2113ae --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/JeecgRedisOAuth2AuthorizationConsentService.java @@ -0,0 +1,51 @@ +package org.jeecg.config.security; + +import lombok.RequiredArgsConstructor; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsent; +import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService; +import org.springframework.stereotype.Component; +import org.springframework.util.Assert; + +import java.util.concurrent.TimeUnit; + +@Component +@RequiredArgsConstructor +public class JeecgRedisOAuth2AuthorizationConsentService implements OAuth2AuthorizationConsentService { + + private final RedisTemplate redisTemplate; + + private final static Long TIMEOUT = 10L; + + @Override + public void save(OAuth2AuthorizationConsent authorizationConsent) { + Assert.notNull(authorizationConsent, "authorizationConsent cannot be null"); + + redisTemplate.opsForValue().set(buildKey(authorizationConsent), authorizationConsent, TIMEOUT, + TimeUnit.MINUTES); + + } + + @Override + public void remove(OAuth2AuthorizationConsent authorizationConsent) { + Assert.notNull(authorizationConsent, "authorizationConsent cannot be null"); + redisTemplate.delete(buildKey(authorizationConsent)); + } + + @Override + public OAuth2AuthorizationConsent findById(String registeredClientId, String principalName) { + Assert.hasText(registeredClientId, "registeredClientId cannot be empty"); + Assert.hasText(principalName, "principalName cannot be empty"); + return (OAuth2AuthorizationConsent) redisTemplate.opsForValue() + .get(buildKey(registeredClientId, principalName)); + } + + private static String buildKey(String registeredClientId, String principalName) { + return "token:consent:" + registeredClientId + ":" + principalName; + } + + private static String buildKey(OAuth2AuthorizationConsent authorizationConsent) { + return buildKey(authorizationConsent.getRegisteredClientId(), authorizationConsent.getPrincipalName()); + } + +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/JeecgRedisOAuth2AuthorizationService.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/JeecgRedisOAuth2AuthorizationService.java new file mode 100644 index 000000000..cdbb7dc53 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/JeecgRedisOAuth2AuthorizationService.java @@ -0,0 +1,180 @@ +package org.jeecg.config.security; + +import cn.hutool.core.collection.CollUtil; +import lombok.RequiredArgsConstructor; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.lang.Nullable; +import org.springframework.security.core.Authentication; +import org.springframework.security.oauth2.core.OAuth2AccessToken; +import org.springframework.security.oauth2.core.OAuth2RefreshToken; +import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; +import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; +import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationCode; +import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; +import org.springframework.security.oauth2.server.authorization.OAuth2TokenType; +import org.springframework.stereotype.Component; +import org.springframework.util.Assert; + +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * @author EightMonth + */ +@Component +@RequiredArgsConstructor +public class JeecgRedisOAuth2AuthorizationService implements OAuth2AuthorizationService { + + private final static Long TIMEOUT = 10L; + + private static final String AUTHORIZATION = "token"; + + private final RedisTemplate redisTemplate; + + @Override + public void save(OAuth2Authorization authorization) { + Assert.notNull(authorization, "authorization cannot be null"); + + if (isState(authorization)) { + String token = authorization.getAttribute("state"); + redisTemplate.setValueSerializer(RedisSerializer.java()); + redisTemplate.opsForValue().set(buildKey(OAuth2ParameterNames.STATE, token), authorization, TIMEOUT, + TimeUnit.MINUTES); + } + + if (isCode(authorization)) { + OAuth2Authorization.Token authorizationCode = authorization + .getToken(OAuth2AuthorizationCode.class); + OAuth2AuthorizationCode authorizationCodeToken = authorizationCode.getToken(); + long between = ChronoUnit.MINUTES.between(authorizationCodeToken.getIssuedAt(), + authorizationCodeToken.getExpiresAt()); + redisTemplate.setValueSerializer(RedisSerializer.java()); + redisTemplate.opsForValue().set(buildKey(OAuth2ParameterNames.CODE, authorizationCodeToken.getTokenValue()), + authorization, between, TimeUnit.MINUTES); + } + + if (isRefreshToken(authorization)) { + OAuth2RefreshToken refreshToken = authorization.getRefreshToken().getToken(); + long between = ChronoUnit.SECONDS.between(refreshToken.getIssuedAt(), refreshToken.getExpiresAt()); + redisTemplate.setValueSerializer(RedisSerializer.java()); + redisTemplate.opsForValue().set(buildKey(OAuth2ParameterNames.REFRESH_TOKEN, refreshToken.getTokenValue()), + authorization, between, TimeUnit.SECONDS); + } + + if (isAccessToken(authorization)) { + OAuth2AccessToken accessToken = authorization.getAccessToken().getToken(); + long between = ChronoUnit.SECONDS.between(accessToken.getIssuedAt(), accessToken.getExpiresAt()); + redisTemplate.setValueSerializer(RedisSerializer.java()); + redisTemplate.opsForValue().set(buildKey(OAuth2ParameterNames.ACCESS_TOKEN, accessToken.getTokenValue()), + authorization, between, TimeUnit.SECONDS); + + // 扩展记录 access-token 、username 的关系 1::token::username::admin::xxx + String tokenUsername = String.format("%s::%s::%s", AUTHORIZATION, authorization.getPrincipalName(), accessToken.getTokenValue()); + redisTemplate.opsForValue().set(tokenUsername, accessToken.getTokenValue(), between, TimeUnit.SECONDS); + } + } + + @Override + public void remove(OAuth2Authorization authorization) { + Assert.notNull(authorization, "authorization cannot be null"); + + List keys = new ArrayList<>(); + if (isState(authorization)) { + String token = authorization.getAttribute("state"); + keys.add(buildKey(OAuth2ParameterNames.STATE, token)); + } + + if (isCode(authorization)) { + OAuth2Authorization.Token authorizationCode = authorization + .getToken(OAuth2AuthorizationCode.class); + OAuth2AuthorizationCode authorizationCodeToken = authorizationCode.getToken(); + keys.add(buildKey(OAuth2ParameterNames.CODE, authorizationCodeToken.getTokenValue())); + } + + if (isRefreshToken(authorization)) { + OAuth2RefreshToken refreshToken = authorization.getRefreshToken().getToken(); + keys.add(buildKey(OAuth2ParameterNames.REFRESH_TOKEN, refreshToken.getTokenValue())); + } + + if (isAccessToken(authorization)) { + OAuth2AccessToken accessToken = authorization.getAccessToken().getToken(); + keys.add(buildKey(OAuth2ParameterNames.ACCESS_TOKEN, accessToken.getTokenValue())); + + // 扩展记录 access-token 、username 的关系 1::token::username::admin::xxx + String key = String.format("%s::%s::%s", AUTHORIZATION, authorization.getPrincipalName(), accessToken.getTokenValue()); + keys.add(key); + } + + redisTemplate.delete(keys); + } + + @Override + @Nullable + public OAuth2Authorization findById(String id) { + throw new UnsupportedOperationException(); + } + + @Override + @Nullable + public OAuth2Authorization findByToken(String token, @Nullable OAuth2TokenType tokenType) { + Assert.hasText(token, "token cannot be empty"); + Assert.notNull(tokenType, "tokenType cannot be empty"); + redisTemplate.setValueSerializer(RedisSerializer.java()); + return (OAuth2Authorization) redisTemplate.opsForValue().get(buildKey(tokenType.getValue(), token)); + } + + private String buildKey(String type, String id) { + return String.format("%s::%s::%s", AUTHORIZATION, type, id); + } + + private static boolean isState(OAuth2Authorization authorization) { + return Objects.nonNull(authorization.getAttribute("state")); + } + + private static boolean isCode(OAuth2Authorization authorization) { + OAuth2Authorization.Token authorizationCode = authorization + .getToken(OAuth2AuthorizationCode.class); + return Objects.nonNull(authorizationCode); + } + + private static boolean isRefreshToken(OAuth2Authorization authorization) { + return Objects.nonNull(authorization.getRefreshToken()); + } + + private static boolean isAccessToken(OAuth2Authorization authorization) { + return Objects.nonNull(authorization.getAccessToken()); + } + + /** + * 扩展方法根据 username 查询是否存在存储的 + * @param authentication + * @return + */ + public void removeByUsername(Authentication authentication) { + // 根据 username查询对应access-token + String authenticationName = authentication.getName(); + + // 扩展记录 access-token 、username 的关系 1::token::username::admin::xxx + String tokenUsernameKey = String.format("%s::%s::*", AUTHORIZATION, authenticationName); + Set keys = redisTemplate.keys(tokenUsernameKey); + if (CollUtil.isEmpty(keys)) { + return; + } + + List tokenList = redisTemplate.opsForValue().multiGet(keys); + + for (Object token : tokenList) { + // 根据token 查询存储的 OAuth2Authorization + OAuth2Authorization authorization = this.findByToken((String) token, OAuth2TokenType.ACCESS_TOKEN); + // 根据 OAuth2Authorization 删除相关令牌 + this.remove(authorization); + } + + } + +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/SecurityConfig.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/SecurityConfig.java new file mode 100644 index 000000000..cdec413f9 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/SecurityConfig.java @@ -0,0 +1,271 @@ +package org.jeecg.config.security; + +import com.nimbusds.jose.jwk.JWKSet; +import com.nimbusds.jose.jwk.RSAKey; +import com.nimbusds.jose.jwk.source.ImmutableJWKSet; +import com.nimbusds.jose.jwk.source.JWKSource; +import com.nimbusds.jose.proc.SecurityContext; +import lombok.AllArgsConstructor; +import org.jeecg.common.api.CommonAPI; +import org.jeecg.common.util.RedisUtil; +import org.jeecg.config.JeecgBaseConfig; +import org.jeecg.config.security.password.PasswordGrantAuthenticationConvert; +import org.jeecg.config.security.password.PasswordGrantAuthenticationProvider; +import org.jeecg.modules.base.service.BaseCommonService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.security.servlet.PathRequest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.http.MediaType; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.security.config.Customizer; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.factory.PasswordEncoderFactories; +import org.springframework.security.crypto.password.NoOpPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames; +import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames; +import org.springframework.security.oauth2.jwt.JwsHeader; +import org.springframework.security.oauth2.jwt.JwtClaimsSet; +import org.springframework.security.oauth2.jwt.JwtDecoder; +import org.springframework.security.oauth2.jwt.NimbusJwtEncoder; +import org.springframework.security.oauth2.server.authorization.*; +import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository; +import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; +import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; +import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer; +import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings; +import org.springframework.security.oauth2.server.authorization.token.*; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher; +import org.springframework.web.cors.CorsConfiguration; + +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.time.Instant; +import java.util.Arrays; +import java.util.Date; +import java.util.UUID; + +/** + * @author eightmonth@qq.com + * @date 2024/1/2 9:29 + */ +@Configuration +@EnableWebSecurity +@EnableMethodSecurity(jsr250Enabled = true, securedEnabled = true) +@AllArgsConstructor +public class SecurityConfig { + + private JdbcTemplate jdbcTemplate; + private OAuth2AuthorizationService authorizationService; + private final CommonAPI commonAPI; + private final RedisUtil redisUtil; + private final JeecgBaseConfig jeecgBaseConfig; + private final BaseCommonService baseCommonService; + + @Bean + @Order(1) + public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) + throws Exception { + OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); + http.getConfigurer(OAuth2AuthorizationServerConfigurer.class) + .tokenEndpoint(tokenEndpoint -> tokenEndpoint.accessTokenRequestConverter(new PasswordGrantAuthenticationConvert()) + .authenticationProvider(new PasswordGrantAuthenticationProvider(jwtCustomizer(), authorizationService, tokenGenerator(), commonAPI, redisUtil, jeecgBaseConfig, baseCommonService))) + //开启OpenID Connect 1.0(其中oidc为OpenID Connect的缩写)。 访问 /.well-known/openid-configuration即可获取认证信息 + .oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0 + http + //将需要认证的请求,重定向到login页面行登录认证。 + .exceptionHandling((exceptions) -> exceptions + .defaultAuthenticationEntryPointFor( + new LoginUrlAuthenticationEntryPoint("/sys/login"), + new MediaTypeRequestMatcher(MediaType.TEXT_HTML) + ) + ) + // 使用jwt处理接收到的access token + .oauth2ResourceServer(oauth2ResourceServer -> + oauth2ResourceServer.jwt(Customizer.withDefaults())); + + return http.build(); + } + + @Bean + @Order(2) + public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) + throws Exception { + http + //设置所有请求都需要认证,未认证的请求都被重定向到login页面进行登录 + .authorizeHttpRequests((authorize) -> authorize + .requestMatchers(AntPathRequestMatcher.antMatcher("/sys/cas/client/validateLogin")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/sys/randomImage/**")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/sys/checkCaptcha")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/sys/login")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/sys/mLogin")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/sys/logout")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/sys/thirdLogin/**")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/sys/getEncryptedString")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/sys/sms")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/sys/phoneLogin")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/sys/user/checkOnlyUser")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/sys/user/register")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/sys/user/phoneVerification")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/sys/user/passwordChange")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/auth/2step-code")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/sys/common/static/**")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/sys/common/pdf/**")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/generic/**")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/sys/getLoginQrcode/**")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/sys/getQrcodeToken/**")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/sys/checkAuth")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/doc.html")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/**/*.js")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/**/*.css")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/**/*.html")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/**/*.svg")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/**/*.pdf")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/**/*.jpg")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/**/*.png")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/**/*.gif")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/**/*.ico")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/**/*.ttf")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/**/*.woff")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/**/*.woff2")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/druid/**")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/swagger-ui.html")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/swagger**/**")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/webjars/**")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/v3/**")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/WW_verify*")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/sys/annountCement/show/**")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/jmreport/**")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/**/*.js.map")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/**/*.css.map")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/drag/view")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/drag/page/queryById")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/drag/onlDragDatasetHead/getAllChartData")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/drag/onlDragDatasetHead/getTotalData")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/drag/mock/json/**")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/test/bigScreen/**")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/bigscreen/template1/**")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/bigscreen/template1/**")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/websocket/**")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/newsWebsocket/**")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/vxeSocket/**")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/test/seata/**")).permitAll() + .requestMatchers(AntPathRequestMatcher.antMatcher("/error")).permitAll() + .anyRequest().authenticated() + ) + .cors(cors -> cors + .configurationSource(req -> { + CorsConfiguration config = new CorsConfiguration(); + config.applyPermitDefaultValues(); + config.setAllowedMethods(Arrays.asList("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS")); + return config; + })) + .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults())); + return http.build(); + } + + /** + * 注册客户端信息 + */ + @Bean + public RegisteredClientRepository registeredClientRepository() { + return new JdbcRegisteredClientRepository(jdbcTemplate); + } + + /** + *配置 JWK,为JWT(id_token)提供加密密钥,用于加密/解密或签名/验签 + * JWK详细见:https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key-41 + */ + @Bean + public JWKSource jwkSource() { + KeyPair keyPair = generateRsaKey(); + RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); + RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); + RSAKey rsaKey = new RSAKey.Builder(publicKey) + .privateKey(privateKey) + .keyID(UUID.randomUUID().toString()) + .build(); + JWKSet jwkSet = new JWKSet(rsaKey); + return new ImmutableJWKSet<>(jwkSet); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return NoOpPasswordEncoder.getInstance(); + } + + /** + *生成RSA密钥对,给上面jwkSource() 方法的提供密钥对 + */ + private static KeyPair generateRsaKey() { + KeyPair keyPair; + try { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + keyPairGenerator.initialize(2048); + keyPair = keyPairGenerator.generateKeyPair(); + } + catch (Exception ex) { + throw new IllegalStateException(ex); + } + return keyPair; + } + + /** + * 配置jwt解析器 + */ + @Bean + public JwtDecoder jwtDecoder(JWKSource jwkSource) { + return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource); + } + + /** + *配置认证服务器请求地址 + */ + @Bean + public AuthorizationServerSettings authorizationServerSettings() { + return AuthorizationServerSettings.builder().build(); + } + + /** + *配置token生成器 + */ + @Bean + OAuth2TokenGenerator tokenGenerator() { + JwtGenerator jwtGenerator = new JwtGenerator(new NimbusJwtEncoder(jwkSource())); + OAuth2AccessTokenGenerator accessTokenGenerator = new OAuth2AccessTokenGenerator(); + OAuth2RefreshTokenGenerator refreshTokenGenerator = new OAuth2RefreshTokenGenerator(); + return new DelegatingOAuth2TokenGenerator( + jwtGenerator, accessTokenGenerator, refreshTokenGenerator); + } + + @Bean + public OAuth2TokenCustomizer jwtCustomizer() { + return context -> { + JwsHeader.Builder headers = context.getJwsHeader(); + JwtClaimsSet.Builder claims = context.getClaims(); + if (context.getTokenType().equals(OAuth2TokenType.ACCESS_TOKEN)) { + // 自定义 access_token headers/claims + claims.claim("username", context.getPrincipal().getName()); + + } else if (context.getTokenType().getValue().equals(OidcParameterNames.ID_TOKEN)) { + // 自定义 id_token headers/claims for + claims.claim(IdTokenClaimNames.AUTH_TIME, Date.from(Instant.now())); + + } + }; + } + +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/password/PasswordGrantAuthenticationConvert.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/password/PasswordGrantAuthenticationConvert.java new file mode 100644 index 000000000..b90d9cca0 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/password/PasswordGrantAuthenticationConvert.java @@ -0,0 +1,80 @@ +package org.jeecg.config.security.password; + +import jakarta.servlet.http.HttpServletRequest; +import org.jeecg.common.constant.CommonConstant; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.core.OAuth2AuthenticationException; +import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; +import org.springframework.security.web.authentication.AuthenticationConverter; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.util.StringUtils; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author kezhijie@co-mall.com + * @date 2024/1/1 + */ +public class PasswordGrantAuthenticationConvert implements AuthenticationConverter { + @Override + public Authentication convert(HttpServletRequest request) { + + String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE); + if (!AuthorizationGrantType.PASSWORD.getValue().equals(grantType)) { + return null; + } + + Authentication clientPrincipal = SecurityContextHolder.getContext().getAuthentication(); + + //从request中提取请求参数,然后存入MultiValueMap + MultiValueMap parameters = getParameters(request); + + // username (REQUIRED) + String username = parameters.getFirst(OAuth2ParameterNames.USERNAME); + if (!StringUtils.hasText(username) || + parameters.get(OAuth2ParameterNames.USERNAME).size() != 1) { + throw new OAuth2AuthenticationException("无效请求,用户名不能为空!"); + } + String password = parameters.getFirst(OAuth2ParameterNames.PASSWORD); + if (!StringUtils.hasText(password) || + parameters.get(OAuth2ParameterNames.PASSWORD).size() != 1) { + throw new OAuth2AuthenticationException("无效请求,密码不能为空!"); + } + + //收集要传入PasswordGrantAuthenticationToken构造方法的参数, + //该参数接下来在PasswordGrantAuthenticationProvider中使用 + Map additionalParameters = new HashMap<>(); + //遍历从request中提取的参数,排除掉grant_type、client_id、code等字段参数,其他参数收集到additionalParameters中 + parameters.forEach((key, value) -> { + if (!key.equals(OAuth2ParameterNames.GRANT_TYPE) && + !key.equals(OAuth2ParameterNames.CLIENT_ID) && + !key.equals(OAuth2ParameterNames.CODE)) { + additionalParameters.put(key, value.get(0)); + } + }); + + //返回自定义的PasswordGrantAuthenticationToken对象 + return new PasswordGrantAuthenticationToken(clientPrincipal, additionalParameters); + + } + + /** + *从request中提取请求参数,然后存入MultiValueMap + */ + private static MultiValueMap getParameters(HttpServletRequest request) { + Map parameterMap = request.getParameterMap(); + MultiValueMap parameters = new LinkedMultiValueMap<>(parameterMap.size()); + parameterMap.forEach((key, values) -> { + if (values.length > 0) { + for (String value : values) { + parameters.add(key, value); + } + } + }); + return parameters; + } +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/password/PasswordGrantAuthenticationProvider.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/password/PasswordGrantAuthenticationProvider.java new file mode 100644 index 000000000..c99b6d5c2 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/password/PasswordGrantAuthenticationProvider.java @@ -0,0 +1,283 @@ +package org.jeecg.config.security.password; + +import lombok.extern.slf4j.Slf4j; +import org.jeecg.common.api.CommonAPI; +import org.jeecg.common.constant.CommonConstant; +import org.jeecg.common.exception.JeecgBootException; +import org.jeecg.common.exception.JeecgCaptchaException; +import org.jeecg.common.system.vo.LoginUser; +import org.jeecg.common.system.vo.SysDepartModel; +import org.jeecg.common.util.Md5Util; +import org.jeecg.common.util.PasswordUtil; +import org.jeecg.common.util.RedisUtil; +import org.jeecg.common.util.oConvertUtils; +import org.jeecg.config.JeecgBaseConfig; +import org.jeecg.modules.base.service.BaseCommonService; +import org.springframework.http.HttpStatus; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.oauth2.core.*; +import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; +import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; +import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; +import org.springframework.security.oauth2.server.authorization.OAuth2TokenType; +import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AccessTokenAuthenticationToken; +import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken; +import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; +import org.springframework.security.oauth2.server.authorization.context.AuthorizationServerContextHolder; +import org.springframework.security.oauth2.server.authorization.token.*; +import org.springframework.util.Assert; + +import java.security.Principal; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @author EightMonth + * @date 2024/1/1 + */ +@Slf4j +public class PasswordGrantAuthenticationProvider implements AuthenticationProvider { + + private static final String ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc6749#section-5.2"; + + private final OAuth2AuthorizationService authorizationService; + private final OAuth2TokenGenerator tokenGenerator; + private final CommonAPI commonAPI; + private final RedisUtil redisUtil; + private final JeecgBaseConfig jeecgBaseConfig; + private final BaseCommonService baseCommonService; + private final OAuth2TokenCustomizer oAuth2TokenCustomizer; + + public PasswordGrantAuthenticationProvider(OAuth2TokenCustomizer oAuth2TokenCustomizer, OAuth2AuthorizationService authorizationService, OAuth2TokenGenerator tokenGenerator, CommonAPI commonAPI, RedisUtil redisUtil, JeecgBaseConfig jeecgBaseConfig, BaseCommonService baseCommonService) { + Assert.notNull(authorizationService, "authorizationService cannot be null"); + Assert.notNull(tokenGenerator, "tokenGenerator cannot be null"); + this.authorizationService = authorizationService; + this.tokenGenerator = tokenGenerator; + this.commonAPI = commonAPI; + this.redisUtil = redisUtil; + this.jeecgBaseConfig = jeecgBaseConfig; + this.baseCommonService = baseCommonService; + this.oAuth2TokenCustomizer = oAuth2TokenCustomizer; + } + + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + PasswordGrantAuthenticationToken passwordGrantAuthenticationToken = (PasswordGrantAuthenticationToken) authentication; + Map additionalParameter = passwordGrantAuthenticationToken.getAdditionalParameters(); + + // 授权类型 + AuthorizationGrantType authorizationGrantType = passwordGrantAuthenticationToken.getGrantType(); + // 用户名 + String username = (String) additionalParameter.get(OAuth2ParameterNames.USERNAME); + // 密码 + String password = (String) additionalParameter.get(OAuth2ParameterNames.PASSWORD); + //请求参数权限范围 + String requestScopesStr = (String)additionalParameter.getOrDefault(OAuth2ParameterNames.SCOPE, "*"); + //请求参数权限范围专场集合 + Set requestScopeSet = Stream.of(requestScopesStr.split(" ")).collect(Collectors.toSet()); + // 验证码 + String captcha = (String) additionalParameter.get("captcha"); + String checkKey = (String) additionalParameter.get("checkKey"); + + + if(isLoginFailOvertimes(username)){ + throw new JeecgBootException("该用户登录失败次数过多,请于10分钟后再次登录!"); + } + + if(captcha==null){ + throw new JeecgBootException("验证码无效"); + } + String lowerCaseCaptcha = captcha.toLowerCase(); + // 加入密钥作为混淆,避免简单的拼接,被外部利用,用户自定义该密钥即可 + String origin = lowerCaseCaptcha+checkKey+jeecgBaseConfig.getSignatureSecret(); + String realKey = Md5Util.md5Encode(origin, "utf-8"); + Object checkCode = redisUtil.get(realKey); + //当进入登录页时,有一定几率出现验证码错误 #1714 + if(checkCode==null || !checkCode.toString().equals(lowerCaseCaptcha)) { + log.warn("验证码错误,key= {} , Ui checkCode= {}, Redis checkCode = {}", checkKey, lowerCaseCaptcha, checkCode); + // 改成特殊的code 便于前端判断 + throw new JeecgCaptchaException(HttpStatus.PRECONDITION_FAILED.value(), "验证码错误"); + } + + OAuth2ClientAuthenticationToken clientPrincipal = getAuthenticatedClientElseThrowInvalidClient(passwordGrantAuthenticationToken); + RegisteredClient registeredClient = clientPrincipal.getRegisteredClient(); + + if (!registeredClient.getAuthorizationGrantTypes().contains(authorizationGrantType)) { + throw new JeecgBootException("非法登录"); + } + + LoginUser loginUser = commonAPI.getUserByName(username); + // 检查用户可行性 + checkUserIsEffective(loginUser); + + // 不使用spring security passwordEncoder针对密码进行匹配,使用自有加密匹配,针对 spring security使用noop传输 + password = PasswordUtil.encrypt(username, password, loginUser.getSalt()); + if (!password.equals(loginUser.getPassword())) { + addLoginFailOvertimes(username); + throw new JeecgBootException("用户名或密码不正确"); + } + + //由于在上面已验证过用户名、密码,现在构建一个已认证的对象UsernamePasswordAuthenticationToken + UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = UsernamePasswordAuthenticationToken.authenticated(loginUser,clientPrincipal,new ArrayList<>()); + + DefaultOAuth2TokenContext.Builder tokenContextBuilder = DefaultOAuth2TokenContext.builder() + .put("username", username) + .registeredClient(registeredClient) + .principal(usernamePasswordAuthenticationToken) + .authorizationServerContext(AuthorizationServerContextHolder.getContext()) + .authorizationGrantType(authorizationGrantType) + .authorizedScopes(requestScopeSet) + .authorizationGrant(passwordGrantAuthenticationToken); + + OAuth2Authorization.Builder authorizationBuilder = OAuth2Authorization.withRegisteredClient(registeredClient) + .principalName(clientPrincipal.getName()) + .authorizedScopes(requestScopeSet) + .attribute(Principal.class.getName(), username) + .authorizationGrantType(authorizationGrantType); + + + // ----- Access token ----- + OAuth2TokenContext tokenContext = tokenContextBuilder.tokenType(OAuth2TokenType.ACCESS_TOKEN).build(); + OAuth2Token generatedAccessToken = this.tokenGenerator.generate(tokenContext); + if (generatedAccessToken == null) { + OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.SERVER_ERROR, + "无法生成访问token,请联系管理系。", ERROR_URI); + throw new OAuth2AuthenticationException(error); + } + OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, + generatedAccessToken.getTokenValue(), generatedAccessToken.getIssuedAt(), + generatedAccessToken.getExpiresAt(), tokenContext.getAuthorizedScopes()); + if (generatedAccessToken instanceof ClaimAccessor) { + authorizationBuilder.token(accessToken, (metadata) -> { + metadata.put(OAuth2Authorization.Token.CLAIMS_METADATA_NAME, ((ClaimAccessor) generatedAccessToken).getClaims()); + }); + } else { + authorizationBuilder.accessToken(accessToken); + } + + // ----- Refresh token ----- + OAuth2RefreshToken refreshToken = null; + if (registeredClient.getAuthorizationGrantTypes().contains(AuthorizationGrantType.REFRESH_TOKEN) && + // 不向公共客户端颁发刷新令牌 + !clientPrincipal.getClientAuthenticationMethod().equals(ClientAuthenticationMethod.NONE)) { + + tokenContext = tokenContextBuilder.tokenType(OAuth2TokenType.REFRESH_TOKEN).build(); + OAuth2Token generatedRefreshToken = this.tokenGenerator.generate(tokenContext); + if (!(generatedRefreshToken instanceof OAuth2RefreshToken)) { + OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.SERVER_ERROR, + "无法生成刷新token,请联系管理员。", ERROR_URI); + throw new OAuth2AuthenticationException(error); + } + + refreshToken = (OAuth2RefreshToken) generatedRefreshToken; + authorizationBuilder.refreshToken(refreshToken); + } + + OAuth2Authorization authorization = authorizationBuilder.build(); + + authorizationService.save(authorization); + + // 登录成功,删除redis中的验证码 + redisUtil.del(realKey); + redisUtil.del(CommonConstant.LOGIN_FAIL + username); + baseCommonService.addLog("用户名: " + username + ",登录成功!", CommonConstant.LOG_TYPE_1, null,loginUser); + + Map addition = new HashMap<>(); + // 设置登录用户信息 + addition.put("userInfo", loginUser); + addition.put("sysAllDictItems", commonAPI.queryAllDictItems()); + + List departs = commonAPI.queryUserDeparts(loginUser.getId()); + addition.put("departs", departs); + if (departs == null || departs.size() == 0) { + addition.put("multi_depart", 0); + } else if (departs.size() == 1) { + commonAPI.updateUserDepart(username, departs.get(0).getOrgCode(),null); + addition.put("multi_depart", 1); + } else { + //查询当前是否有登录部门 + if(oConvertUtils.isEmpty(loginUser.getOrgCode())){ + commonAPI.updateUserDepart(username, departs.get(0).getOrgCode(),null); + } + addition.put("multi_depart", 2); + } + + return new OAuth2AccessTokenAuthenticationToken(registeredClient, clientPrincipal, accessToken, refreshToken, addition); + } + + @Override + public boolean supports(Class authentication) { + return PasswordGrantAuthenticationToken.class.isAssignableFrom(authentication); + } + + private static OAuth2ClientAuthenticationToken getAuthenticatedClientElseThrowInvalidClient(Authentication authentication) { + OAuth2ClientAuthenticationToken clientPrincipal = null; + if (OAuth2ClientAuthenticationToken.class.isAssignableFrom(authentication.getPrincipal().getClass())) { + clientPrincipal = (OAuth2ClientAuthenticationToken) authentication.getPrincipal(); + } + if (clientPrincipal != null && clientPrincipal.isAuthenticated()) { + return clientPrincipal; + } + throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_CLIENT); + } + + /** + * 登录失败超出次数5 返回true + * @param username + * @return + */ + private boolean isLoginFailOvertimes(String username){ + String key = CommonConstant.LOGIN_FAIL + username; + Object failTime = redisUtil.get(key); + if(failTime!=null){ + Integer val = Integer.parseInt(failTime.toString()); + if(val>5){ + return true; + } + } + return false; + } + + /** + * 记录登录失败次数 + * @param username + */ + private void addLoginFailOvertimes(String username){ + String key = CommonConstant.LOGIN_FAIL + username; + Object failTime = redisUtil.get(key); + Integer val = 0; + if(failTime!=null){ + val = Integer.parseInt(failTime.toString()); + } + // 10分钟 + redisUtil.set(key, ++val, 10); + } + + /** + * 校验用户是否有效 + */ + private void checkUserIsEffective(LoginUser loginUser) { + //情况1:根据用户信息查询,该用户不存在 + if (Objects.isNull(loginUser)) { + baseCommonService.addLog("用户登录失败,用户不存在!", CommonConstant.LOG_TYPE_1, null); + throw new JeecgBootException("该用户不存在,请注册"); + } + //情况2:根据用户信息查询,该用户已注销 + //update-begin---author:王帅 Date:20200601 for:if条件永远为falsebug------------ + if (CommonConstant.DEL_FLAG_1.equals(loginUser.getDelFlag())) { + //update-end---author:王帅 Date:20200601 for:if条件永远为falsebug------------ + baseCommonService.addLog("用户登录失败,用户名:" + loginUser.getUsername() + "已注销!", CommonConstant.LOG_TYPE_1, null); + throw new JeecgBootException("该用户已注销"); + } + //情况3:根据用户信息查询,该用户已冻结 + if (CommonConstant.USER_FREEZE.equals(loginUser.getStatus())) { + baseCommonService.addLog("用户登录失败,用户名:" + loginUser.getUsername() + "已冻结!", CommonConstant.LOG_TYPE_1, null); + throw new JeecgBootException("该用户已冻结"); + } + } + +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/password/PasswordGrantAuthenticationToken.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/password/PasswordGrantAuthenticationToken.java new file mode 100644 index 000000000..9b81873f3 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/password/PasswordGrantAuthenticationToken.java @@ -0,0 +1,19 @@ +package org.jeecg.config.security.password; + +import org.springframework.security.core.Authentication; +import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationGrantAuthenticationToken; + +import java.util.Map; + +/** + * @author kezhijie@co-mall.com + * @date 2024/1/1 + */ +public class PasswordGrantAuthenticationToken extends OAuth2AuthorizationGrantAuthenticationToken { + + public PasswordGrantAuthenticationToken(Authentication clientPrincipal, Map additionalParameters) { + super(new AuthorizationGrantType(AuthorizationGrantType.PASSWORD.getValue()), clientPrincipal, additionalParameters); + } + +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java index 59d3c4cab..136751b7c 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java @@ -40,7 +40,7 @@ import java.util.stream.Collectors; */ @Slf4j -@Configuration +//@Configuration public class ShiroConfig { @Resource diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroRealm.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroRealm.java index 5b4bd1bc7..1d1b59f61 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroRealm.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroRealm.java @@ -32,7 +32,7 @@ import java.util.Set; * @Date: 2019-4-23 8:13 * @Version: 1.1 */ -@Component +//@Component @Slf4j public class ShiroRealm extends AuthorizingRealm { @Lazy diff --git a/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/controller/JeecgDemoController.java b/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/controller/JeecgDemoController.java index 009710fa8..e29b90749 100644 --- a/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/controller/JeecgDemoController.java +++ b/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/controller/JeecgDemoController.java @@ -477,8 +477,8 @@ public class JeecgDemoController extends JeecgController test() { //解决shiro报错No SecurityManager accessible to the calling code, either bound to the org.apache.shiro // https://blog.csdn.net/Japhet_jiu/article/details/131177210 - DefaultSecurityManager securityManager = new DefaultSecurityManager(); - SecurityUtils.setSecurityManager(securityManager); +// DefaultSecurityManager securityManager = new DefaultSecurityManager(); +// SecurityUtils.setSecurityManager(securityManager); return Mono.just("测试"); } diff --git a/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/controller/JeecgOrderMainController.java b/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/controller/JeecgOrderMainController.java index 601d9aae6..fa74020e6 100644 --- a/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/controller/JeecgOrderMainController.java +++ b/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/controller/JeecgOrderMainController.java @@ -5,6 +5,7 @@ import java.util.Arrays; import java.util.List; import java.util.Map; +import com.alibaba.fastjson.JSON; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -30,6 +31,7 @@ import org.jeecgframework.poi.excel.entity.ImportParams; import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -184,7 +186,7 @@ public class JeecgOrderMainController extends JeecgController pageList = new ArrayList(); diff --git a/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/service/impl/JeecgDemoServiceImpl.java b/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/service/impl/JeecgDemoServiceImpl.java index 1bcb77469..6b5f87cfc 100644 --- a/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/service/impl/JeecgDemoServiceImpl.java +++ b/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/service/impl/JeecgDemoServiceImpl.java @@ -1,5 +1,6 @@ package org.jeecg.modules.demo.test.service.impl; +import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -12,6 +13,7 @@ import org.jeecg.modules.demo.test.mapper.JeecgDemoMapper; import org.jeecg.modules.demo.test.service.IJeecgDemoService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -81,7 +83,7 @@ public class JeecgDemoServiceImpl extends ServiceImpl noAuthList = new ArrayList<>(); diff --git a/jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/fallback/SysBaseAPIFallback.java b/jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/fallback/SysBaseAPIFallback.java index c2907745d..e47caef74 100644 --- a/jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/fallback/SysBaseAPIFallback.java +++ b/jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/fallback/SysBaseAPIFallback.java @@ -433,4 +433,18 @@ public class SysBaseAPIFallback implements ISysBaseAPI { return false; } + @Override + public Map> queryAllDictItems() { + return null; + } + + @Override + public List queryUserDeparts(String userId) { + return null; + } + + @Override + public void updateUserDepart(String username, String orgCode, Integer loginTenantId) { + + } } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/aop/TenantPackUserLogAspect.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/aop/TenantPackUserLogAspect.java index 5c76c685f..4014cec9c 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/aop/TenantPackUserLogAspect.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/aop/TenantPackUserLogAspect.java @@ -1,5 +1,6 @@ package org.jeecg.modules.aop; +import com.alibaba.fastjson.JSON; import org.apache.shiro.SecurityUtils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.AfterThrowing; @@ -12,6 +13,7 @@ import org.jeecg.common.system.vo.LoginUser; import org.jeecg.modules.base.service.BaseCommonService; import org.jeecg.modules.system.entity.SysTenantPack; import org.jeecg.modules.system.entity.SysTenantPackUser; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; import jakarta.annotation.Resource; @@ -78,7 +80,7 @@ public class TenantPackUserLogAspect { dto.setOperateType(opType); dto.setTenantId(tenantId); //获取登录用户信息 - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; if(sysUser!=null){ dto.setUserid(sysUser.getUsername()); dto.setUsername(sysUser.getRealname()); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/quartz/controller/QuartzJobController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/quartz/controller/QuartzJobController.java index 3c625e448..71dbcb393 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/quartz/controller/QuartzJobController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/quartz/controller/QuartzJobController.java @@ -1,5 +1,6 @@ package org.jeecg.modules.quartz.controller; +import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -25,6 +26,7 @@ import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; @@ -214,7 +216,7 @@ public class QuartzJobController { mv.addObject(NormalExcelConstants.CLASS, QuartzJob.class); //获取当前登录用户 //update-begin---author:wangshuai ---date:20211227 for:[JTC-116]导出人写死了------------ - LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser user = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("定时任务列表数据", "导出人:"+user.getRealname(), "导出信息")); //update-end---author:wangshuai ---date:20211227 for:[JTC-116]导出人写死了------------ mv.addObject(NormalExcelConstants.DATA_LIST, pageList); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/LoginController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/LoginController.java index a390f05e3..97942517d 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/LoginController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/LoginController.java @@ -1,6 +1,7 @@ package org.jeecg.modules.system.controller; import cn.hutool.core.util.RandomUtil; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.aliyuncs.exceptions.ClientException; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -32,6 +33,7 @@ import org.jeecg.modules.system.util.RandImageUtil; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; import jakarta.annotation.Resource; @@ -277,7 +279,7 @@ public class LoginController { Result result = new Result(); String username = user.getUsername(); if(oConvertUtils.isEmpty(username)) { - LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; username = sysUser.getUsername(); } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementController.java index 240c75bf9..288a0998c 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementController.java @@ -1,5 +1,6 @@ package org.jeecg.modules.system.controller; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -41,6 +42,7 @@ import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.http.HttpStatus; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -335,7 +337,7 @@ public class SysAnnouncementController { public Result> listByUser(@RequestParam(required = false, defaultValue = "5") Integer pageSize) { Result> result = new Result>(); Map sysMsgMap = new HashMap(5); - LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; String userId = sysUser.getId(); // //补推送数据(用户和通知的关系表) @@ -378,7 +380,7 @@ public class SysAnnouncementController { //导出文件名称 mv.addObject(NormalExcelConstants.FILE_NAME, "系统通告列表"); mv.addObject(NormalExcelConstants.CLASS, SysAnnouncement.class); - LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser user = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("系统通告列表数据", "导出人:"+user.getRealname(), "导出信息")); mv.addObject(NormalExcelConstants.DATA_LIST, pageList); return mv; @@ -546,7 +548,7 @@ public class SysAnnouncementController { JSONObject obj = new JSONObject(); obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER); - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; webSocket.sendMessage(sysUser.getId(), obj.toJSONString()); // 4、性能统计耗时 diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementSendController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementSendController.java index 72b9d9e47..659d2ec35 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementSendController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementSendController.java @@ -3,6 +3,7 @@ package org.jeecg.modules.system.controller; import java.util.Arrays; import java.util.Date; +import com.alibaba.fastjson.JSON; import jakarta.servlet.http.HttpServletRequest; import org.apache.shiro.SecurityUtils; @@ -18,6 +19,7 @@ import org.jeecg.modules.system.entity.SysAnnouncementSend; import org.jeecg.modules.system.model.AnnouncementSendModel; import org.jeecg.modules.system.service.ISysAnnouncementSendService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -194,7 +196,7 @@ public class SysAnnouncementSendController { public Result editById(@RequestBody JSONObject json) { Result result = new Result(); String anntId = json.getString("anntId"); - LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; String userId = sysUser.getId(); LambdaUpdateWrapper updateWrapper = new UpdateWrapper().lambda(); updateWrapper.set(SysAnnouncementSend::getReadFlag, CommonConstant.HAS_READ_FLAG); @@ -219,7 +221,7 @@ public class SysAnnouncementSendController { @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, @RequestParam(name="pageSize", defaultValue="10") Integer pageSize) { Result> result = new Result>(); - LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; String userId = sysUser.getId(); announcementSendModel.setUserId(userId); announcementSendModel.setPageNo((pageNo-1)*pageSize); @@ -238,7 +240,7 @@ public class SysAnnouncementSendController { @PutMapping(value = "/readAll") public Result readAll() { Result result = new Result(); - LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; String userId = sysUser.getId(); LambdaUpdateWrapper updateWrapper = new UpdateWrapper().lambda(); updateWrapper.set(SysAnnouncementSend::getReadFlag, CommonConstant.HAS_READ_FLAG); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysCategoryController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysCategoryController.java index 969bb6c84..773f9116d 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysCategoryController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysCategoryController.java @@ -27,6 +27,7 @@ import org.jeecgframework.poi.excel.entity.ExportParams; import org.jeecgframework.poi.excel.entity.ImportParams; import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; @@ -237,7 +238,7 @@ public class SysCategoryController { //导出文件名称 mv.addObject(NormalExcelConstants.FILE_NAME, "分类字典列表"); mv.addObject(NormalExcelConstants.CLASS, SysCategory.class); - LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser user = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("分类字典列表数据", "导出人:"+user.getRealname(), "导出信息")); return mv; } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysCommentController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysCommentController.java index e4844baa9..f3169d9a6 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysCommentController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysCommentController.java @@ -1,5 +1,6 @@ package org.jeecg.modules.system.controller; +import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -20,6 +21,7 @@ import org.jeecg.modules.system.vo.SysCommentFileVo; import org.jeecg.modules.system.vo.SysCommentVO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; @@ -126,7 +128,7 @@ public class SysCommentController extends JeecgController> queryMyDeptTreeList() { Result> result = new Result<>(); - LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser user = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; try { if(oConvertUtils.isNotEmpty(user.getUserIdentity()) && user.getUserIdentity().equals( CommonConstant.USER_IDENTITY_2 )){ //update-begin--Author:liusq Date:20210624 for:部门查询ids为空后的前端显示问题 issues/I3UD06 @@ -320,7 +322,7 @@ public class SysDepartController { public Result> searchBy(@RequestParam(name = "keyWord", required = true) String keyWord,@RequestParam(name = "myDeptSearch", required = false) String myDeptSearch) { Result> result = new Result>(); //部门查询,myDeptSearch为1时为我的部门查询,登录用户为上级时查只查负责部门下数据 - LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser user = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; String departIds = null; if(oConvertUtils.isNotEmpty(user.getUserIdentity()) && user.getUserIdentity().equals( CommonConstant.USER_IDENTITY_2 )){ departIds = user.getDepartIds(); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDepartPermissionController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDepartPermissionController.java index 272384edb..8042220b0 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDepartPermissionController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDepartPermissionController.java @@ -1,5 +1,6 @@ package org.jeecg.modules.system.controller; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; @@ -28,6 +29,7 @@ import org.jeecg.modules.system.service.ISysDepartRolePermissionService; import org.jeecg.modules.system.service.ISysPermissionDataRuleService; import org.jeecg.modules.system.service.ISysPermissionService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; @@ -258,7 +260,7 @@ public class SysDepartPermissionController extends JeecgController queryWrapper = QueryGenerator.initQueryWrapper(sysDepartRole, req.getParameterMap()); Page page = new Page(pageNo, pageSize); - LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser user = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; List deptIds = null; // if(oConvertUtils.isEmpty(deptId)){ // if(oConvertUtils.isNotEmpty(user.getUserIdentity()) && user.getUserIdentity().equals(CommonConstant.USER_IDENTITY_2) ){ @@ -198,7 +200,7 @@ public class SysDepartRoleController extends JeecgController result = new Result(); try { //直接获取当前用户不适用前端token - LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser loginUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class); if (oConvertUtils.isEmpty(loginUser)) { return Result.error("请登录系统!"); } @@ -320,7 +319,7 @@ public class SysPermissionController { public Result getPermCode() { try { // 直接获取当前用户 - LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser loginUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; if (oConvertUtils.isEmpty(loginUser)) { return Result.error("请登录系统!"); } @@ -560,7 +559,7 @@ public class SysPermissionController { String lastPermissionIds = json.getString("lastpermissionIds"); this.sysRolePermissionService.saveRolePermission(roleId, permissionIds, lastPermissionIds); //update-begin---author:wangshuai ---date:20220316 for:[VUEN-234]用户管理角色授权添加敏感日志------------ - LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser loginUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; baseCommonService.addLog("修改角色ID: "+roleId+" 的权限配置,操作人: " +loginUser.getUsername() ,CommonConstant.LOG_TYPE_2, 2); //update-end---author:wangshuai ---date:20220316 for:[VUEN-234]用户管理角色授权添加敏感日志------------ result.success("保存成功!"); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysPositionController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysPositionController.java index e55c1f392..8364fdcfb 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysPositionController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysPositionController.java @@ -29,6 +29,7 @@ import org.jeecgframework.poi.excel.entity.ExportParams; import org.jeecgframework.poi.excel.entity.ImportParams; import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; @@ -242,7 +243,7 @@ public class SysPositionController { //Step.2 AutoPoi 导出Excel ModelAndView mv = new ModelAndView(new JeecgEntityExcelView()); List pageList = sysPositionService.list(queryWrapper); - LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser user = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; //导出文件名称 mv.addObject(NormalExcelConstants.FILE_NAME, "职务表列表"); mv.addObject(NormalExcelConstants.CLASS, SysPosition.class); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysRoleController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysRoleController.java index 072005387..dcd373c9a 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysRoleController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysRoleController.java @@ -10,6 +10,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import com.alibaba.fastjson.JSON; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -34,6 +35,7 @@ import org.jeecgframework.poi.excel.entity.ImportParams; import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -178,7 +180,7 @@ public class SysRoleController { //如果是saas隔离的情况下,判断当前租户id是否是当前租户下的 if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) { //获取当前用户 - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; Integer tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0); String username = "admin"; if (!tenantId.equals(role.getTenantId()) && !username.equals(sysUser.getUsername())) { @@ -207,7 +209,7 @@ public class SysRoleController { //如果是saas隔离的情况下,判断当前租户id是否是当前租户下的 if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){ //获取当前用户 - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; int tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0); Long getRoleCount = sysRoleService.getRoleCountByTenantId(id, tenantId); String username = "admin"; diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysTenantController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysTenantController.java index 8eae0f916..4246d0399 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysTenantController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysTenantController.java @@ -2,6 +2,7 @@ package org.jeecg.modules.system.controller; import cn.hutool.core.util.RandomUtil; +import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -33,6 +34,7 @@ import org.jeecg.modules.system.vo.tenant.TenantPackModel; import org.jeecg.modules.system.vo.tenant.TenantPackUser; import org.jeecg.modules.system.vo.tenant.TenantPackUserCount; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; import jakarta.servlet.http.HttpServletRequest; @@ -182,7 +184,7 @@ public class SysTenantController { //如果是saas隔离的情况下,判断当前租户id是否是当前租户下的 if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) { //获取当前用户 - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; SysTenant sysTenant = sysTenantService.getById(id); String username = "admin"; @@ -218,7 +220,7 @@ public class SysTenantController { //如果是saas隔离的情况下,判断当前租户id是否是当前租户下的 if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) { //获取当前用户 - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; SysTenant sysTenant = sysTenantService.getById(id); String username = "admin"; @@ -253,7 +255,7 @@ public class SysTenantController { } //------------------------------------------------------------------------------------------------ //获取登录用户信息 - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; //是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】, admin给特权可以管理所有租户 if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL && !"admin".equals(sysUser.getUsername())){ Integer loginSessionTenant = oConvertUtils.getInt(TenantContext.getTenant()); @@ -369,7 +371,7 @@ public class SysTenantController { public Result> getCurrentUserTenant() { Result> result = new Result>(); try { - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; //update-begin---author:wangshuai ---date:20221223 for:[QQYUN-3371]租户逻辑改造,改成关系表------------ List tenantIdList = relationService.getTenantIdsByUserId(sysUser.getId()); Map map = new HashMap(5); @@ -436,7 +438,7 @@ public class SysTenantController { @RequestParam("tenantId") String tenantId){ Result result = new Result<>(); //是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】 - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL && !"admin".equals(sysUser.getUsername())){ Integer loginSessionTenant = oConvertUtils.getInt(TenantContext.getTenant()); if(loginSessionTenant!=null && !loginSessionTenant.equals(Integer.valueOf(tenantId))){ @@ -482,7 +484,7 @@ public class SysTenantController { @PostMapping("/saveTenantJoinUser") public Result saveTenantJoinUser(@RequestBody SysTenant sysTenant){ Result result = new Result<>(); - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; Integer tenantId = sysTenantService.saveTenantJoinUser(sysTenant, sysUser.getId()); result.setSuccess(true); result.setMessage("创建成功"); @@ -496,7 +498,7 @@ public class SysTenantController { */ @PostMapping("/joinTenantByHouseNumber") public Result joinTenantByHouseNumber(@RequestBody SysTenant sysTenant){ - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; Integer tenantId = sysTenantService.joinTenantByHouseNumber(sysTenant, sysUser.getId()); Result result = new Result<>(); if(tenantId != 0){ @@ -531,7 +533,7 @@ public class SysTenantController { SysUser user, HttpServletRequest req) { Page page = new Page(pageNo, pageSize); - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; String tenantId = oConvertUtils.getString(TenantContext.getTenant(), "0"); IPage list = relationService.getUserTenantPageList(page, Arrays.asList(userTenantStatus.split(SymbolConstant.COMMA)), user, Integer.valueOf(tenantId)); return Result.ok(list); @@ -546,7 +548,7 @@ public class SysTenantController { @GetMapping("/getTenantListByUserId") //@RequiresPermissions("system:tenant:getTenantListByUserId") public Result> getTenantListByUserId(@RequestParam(name = "userTenantStatus", required = false) String userTenantStatus) { - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; List list = null; if (oConvertUtils.isNotEmpty(userTenantStatus)) { list = Arrays.asList(userTenantStatus.split(SymbolConstant.COMMA)); @@ -579,7 +581,7 @@ public class SysTenantController { @PutMapping("/cancelTenant") //@RequiresPermissions("system:tenant:cancelTenant") public Result cancelTenant(@RequestBody SysTenant sysTenant,HttpServletRequest request) { - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; SysTenant tenant = sysTenantService.getById(sysTenant.getId()); if (null == tenant) { return Result.error("未找到当前租户信息"); @@ -622,7 +624,7 @@ public class SysTenantController { */ @PutMapping("/cancelApplyTenant") public Result cancelApplyTenant(@RequestParam("tenantId") String tenantId){ - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; sysTenantService.leaveTenant(sysUser.getId(),tenantId); return Result.ok("取消申请成功"); } @@ -661,7 +663,7 @@ public class SysTenantController { */ @DeleteMapping("/exitUserTenant") public Result exitUserTenant(@RequestBody SysTenant sysTenant,HttpServletRequest request){ - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; //验证用户是否已存在 Integer count = relationService.userTenantIzExist(sysUser.getId(),sysTenant.getId()); if (count == 0) { @@ -883,7 +885,7 @@ public class SysTenantController { public Result> getTenantPageListByUserId(SysUserTenantVo sysUserTenantVo, @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, @RequestParam(name="pageSize", defaultValue="10") Integer pageSize) { - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; List list = null; String userTenantStatus = sysUserTenantVo.getUserTenantStatus(); if (oConvertUtils.isNotEmpty(userTenantStatus)) { @@ -901,7 +903,7 @@ public class SysTenantController { public Result agreeOrRefuseJoinTenant(@RequestParam("tenantId") Integer tenantId, @RequestParam("status") String status){ //是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】 - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; String userId = sysUser.getId(); SysTenant tenant = sysTenantService.getById(tenantId); if(null == tenant){ diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/ThirdAppController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/ThirdAppController.java index 22bd2e7ec..27633fe4c 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/ThirdAppController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/ThirdAppController.java @@ -1,6 +1,7 @@ package org.jeecg.modules.system.controller; import cn.hutool.core.collection.CollectionUtil; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.jeecg.dingtalk.api.core.response.Response; @@ -24,6 +25,7 @@ import org.jeecg.modules.system.service.impl.ThirdAppDingtalkServiceImpl; import org.jeecg.modules.system.service.impl.ThirdAppWechatEnterpriseServiceImpl; import org.jeecg.modules.system.vo.thirdapp.SyncInfoVo; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; import jakarta.servlet.http.HttpServletRequest; @@ -477,7 +479,7 @@ public class ThirdAppController { */ @GetMapping("/getThirdAccountByUserId") public Result> getThirdAccountByUserId(@RequestParam(name="thirdType") String thirdType){ - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; LambdaQueryWrapper query = new LambdaQueryWrapper<>(); //根据id查询 query.eq(SysThirdAccount::getSysUserId,sysUser.getId()); @@ -508,7 +510,7 @@ public class ThirdAppController { */ @DeleteMapping("/deleteThirdAccount") public Result deleteThirdAccountById(@RequestBody SysThirdAccount sysThirdAccount){ - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; if(!sysUser.getId().equals(sysThirdAccount.getSysUserId())){ return Result.error("无权修改他人信息"); } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysDataLog.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysDataLog.java index 3eca93234..844fbe790 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysDataLog.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysDataLog.java @@ -1,5 +1,6 @@ package org.jeecg.modules.system.entity; +import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.fasterxml.jackson.annotation.JsonFormat; @@ -10,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.shiro.SecurityUtils; import org.jeecg.common.system.vo.LoginUser; import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.security.core.context.SecurityContextHolder; import java.io.Serializable; import java.util.Date; @@ -93,7 +95,7 @@ public class SysDataLog implements Serializable { */ public void autoSetCreateName() { try { - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; this.setCreateName(sysUser.getRealname()); } catch (Exception e) { log.warn("SecurityUtils.getSubject() 获取用户信息异常:" + e.getMessage()); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysAnnouncementServiceImpl.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysAnnouncementServiceImpl.java index 3972a95e5..ca1805274 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysAnnouncementServiceImpl.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysAnnouncementServiceImpl.java @@ -1,5 +1,6 @@ package org.jeecg.modules.system.service.impl; +import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -17,6 +18,7 @@ import org.jeecg.modules.system.mapper.SysUserMapper; import org.jeecg.modules.system.service.ISysAnnouncementSendService; import org.jeecg.modules.system.service.ISysAnnouncementService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; @@ -143,7 +145,7 @@ public class SysAnnouncementServiceImpl extends ServiceImpl announcementIds = this.getNotSendedAnnouncementlist(userId); List sysAnnouncementSendList = new ArrayList<>(); @@ -193,7 +195,7 @@ public class SysAnnouncementServiceImpl extends ServiceImpl page = new Page(pageNo,pageSize); List list = baseMapper.queryAllMessageList(page, sysUser.getId(), fromUser, starFlag, beginDate, endDate); @@ -202,13 +204,13 @@ public class SysAnnouncementServiceImpl extends ServiceImpl annoceIdList) { - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; sysAnnouncementSendMapper.updateReaded(sysUser.getId(), annoceIdList); } @Override public void clearAllUnReadMessage() { - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; sysAnnouncementSendMapper.clearAllUnReadMessage(sysUser.getId()); } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysBaseApiImpl.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysBaseApiImpl.java index d04b2106d..3a94d1818 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysBaseApiImpl.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysBaseApiImpl.java @@ -54,6 +54,7 @@ import org.jeecg.modules.system.vo.lowapp.SysDictVo; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import org.springframework.ui.freemarker.FreeMarkerTemplateUtils; import org.springframework.util.AntPathMatcher; @@ -584,7 +585,7 @@ public class SysBaseApiImpl implements ISysBaseAPI { public void updateSysAnnounReadFlag(String busType, String busId) { SysAnnouncement announcement = sysAnnouncementMapper.selectOne(new QueryWrapper().eq("bus_type",busType).eq("bus_id",busId)); if(announcement != null){ - LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; String userId = sysUser.getId(); LambdaUpdateWrapper updateWrapper = new UpdateWrapper().lambda(); updateWrapper.set(SysAnnouncementSend::getReadFlag, CommonConstant.HAS_READ_FLAG); @@ -1469,6 +1470,27 @@ public class SysBaseApiImpl implements ISysBaseAPI { return sysDictService.queryTableDictTextByKeys(table, text, code, Arrays.asList(keys.split(","))); } + @Override + public Map> queryAllDictItems() { + return sysDictService.queryAllDictItems(); + } + + @Override + public List queryUserDeparts(String userId) { + List list = new ArrayList<>(); + for (SysDepart sysDepartService: sysDepartService.queryUserDeparts(userId)) { + SysDepartModel model = new SysDepartModel(); + BeanUtils.copyProperties(sysDepartService, model); + list.add(model); + } + return list; + } + + @Override + public void updateUserDepart(String username, String orgCode, Integer loginTenantId) { + sysUserService.updateUserDepart(username, orgCode,null); + } + //-------------------------------------流程节点发送模板消息----------------------------------------------- @Autowired private QywxSendMsgHandle qywxSendMsgHandle; diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysDepartServiceImpl.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysDepartServiceImpl.java index 247543b5c..da7706f24 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysDepartServiceImpl.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysDepartServiceImpl.java @@ -1,6 +1,7 @@ package org.jeecg.modules.system.service.impl; import cn.hutool.core.collection.CollectionUtil; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -31,6 +32,7 @@ import org.jeecg.modules.system.util.FindsDepartsChildrenUtil; import org.jeecg.modules.system.vo.lowapp.ExportDepartVo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -834,7 +836,7 @@ public class SysDepartServiceImpl extends ServiceImpl getMyDepartList() { - LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser user = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; String userId = user.getId(); //字典code集合 List list = new ArrayList<>(); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysTenantPackServiceImpl.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysTenantPackServiceImpl.java index 8401dbe0b..d7071d092 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysTenantPackServiceImpl.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysTenantPackServiceImpl.java @@ -1,5 +1,6 @@ package org.jeecg.modules.system.service.impl; +import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.apache.shiro.SecurityUtils; import org.jeecg.common.constant.SymbolConstant; @@ -19,6 +20,7 @@ import org.jeecg.modules.system.mapper.SysTenantPackUserMapper; import org.jeecg.modules.system.service.ISysTenantPackService; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -133,7 +135,7 @@ public class SysTenantPackServiceImpl extends ServiceImpl invitationUser(String phone, String departId) { Result result = new Result<>(); - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; //1、查询用户信息,判断用户是否存在 SysUser userByPhone = userService.getUserByPhone(phone); @@ -427,7 +429,7 @@ public class SysTenantServiceImpl extends ServiceImpl pageList = null; // 部门ID不存在 直接查询用户表即可 Page page = new Page<>(pageNo, pageSize); - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; if(oConvertUtils.isEmpty(departId)){ LambdaQueryWrapper query = new LambdaQueryWrapper<>(); query.eq(SysUser::getStatus,Integer.parseInt(CommonConstant.STATUS_1)); @@ -247,7 +249,7 @@ public class SysUserDepartServiceImpl extends ServiceImpl pageList = null; // 部门ID不存在 直接查询用户表即可 Page page = new Page<>(pageNo, pageSize); - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; if(oConvertUtils.isNotEmpty(departId)){ // 有部门ID 需要走自定义sql SysDepart sysDepart = sysDepartService.getById(departId); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java index 866a3541d..5db6072e1 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java @@ -2,6 +2,7 @@ package org.jeecg.modules.system.service.impl; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.RandomUtil; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -55,6 +56,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.context.annotation.Lazy; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; @@ -1478,7 +1480,7 @@ public class SysUserServiceImpl extends ServiceImpl impl //导出文件名称 mv.addObject(NormalExcelConstants.FILE_NAME, "用户列表"); mv.addObject(NormalExcelConstants.CLASS, AppExportUserVo.class); - LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser user = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; ExportParams exportParams = new ExportParams("导入规则:\n" + "1、存在用户编号时,数据会根据用户编号进行匹配,匹配成功后只会更新职位和工号;\n" + "2、不存在用户编号时,支持手机号、邮箱、姓名、部们、职位、工号导入,其中手机号必填;\n" + @@ -1786,7 +1788,7 @@ public class SysUserServiceImpl extends ServiceImpl impl userTenantMapper.insert(userTenant); //update-begin---author:wangshuai ---date:20230710 for:【QQYUN-5731】导入用户时,没有提醒------------ //发送系统消息通知 - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; MessageDTO messageDTO = new MessageDTO(); String title = sysUser.getRealname() + " 邀请您加入 " + tenantName + "。"; messageDTO.setTitle(title); diff --git a/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml b/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml index 52902e455..b6c5e6099 100644 --- a/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml +++ b/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml @@ -3,10 +3,10 @@ server: undertow: # 平替 tomcat server.tomcat.max-swallow-siz, undertow该值默认为-1 # max-http-post-size: 10MB - worker-threads: 16 # 4核CPU标准配置 - buffers: - websocket: 8192 # WebSocket缓冲 以字节为单位,这里设置为8 KB - io: 16384 # IO操作缓冲 以字节为单位,这里设置为16 KB + threads: + io: 16 # 4核CPU标准配置 + worker: 256 + buffer-size: 8192 # 以字节为单位,这里设置为8 KB error: include-exception: true include-stacktrace: ALWAYS diff --git a/jeecg-module-system/jeecg-system-start/src/main/resources/application-prod.yml b/jeecg-module-system/jeecg-system-start/src/main/resources/application-prod.yml index ea078924b..9d91fc234 100644 --- a/jeecg-module-system/jeecg-system-start/src/main/resources/application-prod.yml +++ b/jeecg-module-system/jeecg-system-start/src/main/resources/application-prod.yml @@ -3,10 +3,10 @@ server: undertow: # 平替 tomcat server.tomcat.max-swallow-siz, undertow该值默认为-1 # max-http-post-size: 10MB - worker-threads: 16 # 4核CPU标准配置 - buffers: - websocket: 8192 # WebSocket缓冲 以字节为单位,这里设置为8 KB - io: 16384 # IO操作缓冲 以字节为单位,这里设置为16 KB + threads: + io: 16 # 4核CPU标准配置 + worker: 256 + buffer-size: 8192 # 以字节为单位,这里设置为8 KB error: include-exception: true include-stacktrace: ALWAYS @@ -149,11 +149,12 @@ spring: #password: root #driver-class-name: com.mysql.cj.jdbc.Driver #redis 配置 - redis: - database: 0 - host: 127.0.0.1 - port: 6379 - password: '' + data: + redis: + database: 0 + host: 127.0.0.1 + port: 6379 + password: '' #mybatis plus 设置 mybatis-plus: mapper-locations: classpath*:org/jeecg/modules/**/xml/*Mapper.xml From 0faac01bb7c247e3b5a28c977f585d8f5b1449d1 Mon Sep 17 00:00:00 2001 From: EightMonth Date: Thu, 4 Jan 2024 11:15:15 +0800 Subject: [PATCH 2/3] =?UTF-8?q?sas=E5=8D=87=E7=BA=A7=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/增量SQL/sas升级脚本.sql | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 db/增量SQL/sas升级脚本.sql diff --git a/db/增量SQL/sas升级脚本.sql b/db/增量SQL/sas升级脚本.sql new file mode 100644 index 000000000..d0e295257 --- /dev/null +++ b/db/增量SQL/sas升级脚本.sql @@ -0,0 +1,45 @@ +CREATE TABLE `oauth2_registered_client` ( + `id` varchar(100) NOT NULL, + `client_id` varchar(100) NOT NULL, + `client_id_issued_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `client_secret` varchar(200) DEFAULT NULL, + `client_secret_expires_at` timestamp NULL DEFAULT NULL, + `client_name` varchar(200) NOT NULL, + `client_authentication_methods` varchar(1000) NOT NULL, + `authorization_grant_types` varchar(1000) NOT NULL, + `redirect_uris` varchar(1000) DEFAULT NULL, + `post_logout_redirect_uris` varchar(1000) DEFAULT NULL, + `scopes` varchar(1000) NOT NULL, + `client_settings` varchar(2000) NOT NULL, + `token_settings` varchar(2000) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +INSERT INTO `oauth2_registered_client` +(`id`, +`client_id`, +`client_id_issued_at`, +`client_secret`, +`client_secret_expires_at`, +`client_name`, +`client_authentication_methods`, +`authorization_grant_types`, +`redirect_uris`, +`post_logout_redirect_uris`, +`scopes`, +`client_settings`, +`token_settings`) +VALUES +('3eacac0e-0de9-4727-9a64-6bdd4be2ee1f', +'jeecg-client', +now(), +'secret', +null, +'3eacac0e-0de9-4727-9a64-6bdd4be2ee1f', +'client_secret_basic', +'refresh_token,authorization_code,password', +'http://127.0.0.1:8080/jeecg-', +'http://127.0.0.1:8080/', +'*', +'{"@class":"java.util.Collections$UnmodifiableMap","settings.client.require-proof-key":false,"settings.client.require-authorization-consent":true}', +'{"@class":"java.util.Collections$UnmodifiableMap","settings.token.reuse-refresh-tokens":true,"settings.token.id-token-signature-algorithm":["org.springframework.security.oauth2.jose.jws.SignatureAlgorithm","RS256"],"settings.token.access-token-time-to-live":["java.time.Duration",300000.000000000],"settings.token.access-token-format":{"@class":"org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat","value":"self-contained"},"settings.token.refresh-token-time-to-live":["java.time.Duration",3600.000000000],"settings.token.authorization-code-time-to-live":["java.time.Duration",300000.000000000],"settings.token.device-code-time-to-live":["java.time.Duration",300000.000000000]}'); From 3ac8ee304aa5b25a4d5b5c4615e0c7ed9db5c43a Mon Sep 17 00:00:00 2001 From: EightMonth Date: Fri, 12 Jan 2024 09:26:30 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E5=AE=8C=E5=85=A8=E6=9B=BF=E6=8D=A2shiro?= =?UTF-8?q?=E6=9D=83=E9=99=90=E6=B3=A8=E8=A7=A3=EF=BC=8C=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E6=89=8B=E6=9C=BA=E7=99=BB=E5=BD=95=E3=80=81APP=E7=99=BB?= =?UTF-8?q?=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 +- derby.log | 13 - .../java/org/jeecg/common/api/CommonAPI.java | 7 + .../jeecg/common/aspect/AutoLogAspect.java | 4 +- .../exception/JeecgBootExceptionHandler.java | 7 + .../base/controller/JeecgController.java | 5 +- .../org/jeecg/common/system/util/JwtUtil.java | 6 +- .../org/jeecg/common/system/vo/LoginUser.java | 46 +-- .../interceptor/LowCodeModeInterceptor.java | 3 - .../security/JeecgPermissionService.java | 53 ++++ .../org/jeecg/config/security/LoginType.java | 31 ++ .../jeecg/config/security/SecurityConfig.java | 41 +-- .../app/AppGrantAuthenticationConvert.java | 80 +++++ .../app/AppGrantAuthenticationProvider.java | 284 ++++++++++++++++++ .../app/AppGrantAuthenticationToken.java | 20 ++ .../PasswordGrantAuthenticationConvert.java | 5 +- .../PasswordGrantAuthenticationProvider.java | 28 +- .../PasswordGrantAuthenticationToken.java | 5 +- .../PhoneGrantAuthenticationConvert.java | 77 +++++ .../PhoneGrantAuthenticationProvider.java | 267 ++++++++++++++++ .../phone/PhoneGrantAuthenticationToken.java | 20 ++ .../config/security/utils/SecureUtil.java | 17 ++ .../org/jeecg/config/shiro/ShiroRealm.java | 1 - .../controller/JeecgOrderMainController.java | 3 +- .../service/impl/JeecgDemoServiceImpl.java | 3 +- .../api/fallback/SysBaseAPIFallback.java | 5 + .../modules/aop/TenantPackUserLogAspect.java | 4 +- .../oss/controller/OssFileController.java | 3 +- .../controller/QuartzJobController.java | 18 +- .../system/controller/LoginController.java | 37 ++- .../controller/SysAnnouncementController.java | 7 +- .../SysAnnouncementSendController.java | 7 +- .../controller/SysCategoryController.java | 3 +- .../controller/SysCommentController.java | 4 +- .../controller/SysDataSourceController.java | 3 +- .../controller/SysDepartController.java | 16 +- .../SysDepartPermissionController.java | 4 +- .../controller/SysDepartRoleController.java | 19 +- .../system/controller/SysDictController.java | 14 +- .../controller/SysDictItemController.java | 9 +- .../controller/SysGatewayRouteController.java | 3 +- .../controller/SysPermissionController.java | 27 +- .../controller/SysPositionController.java | 3 +- .../system/controller/SysRoleController.java | 20 +- .../controller/SysRoleIndexController.java | 5 +- .../SysTableWhiteListController.java | 14 +- .../controller/SysTenantController.java | 63 ++-- .../system/controller/SysUserController.java | 44 +-- .../system/controller/ThirdAppController.java | 5 +- .../modules/system/entity/SysDataLog.java | 3 +- .../impl/SysAnnouncementServiceImpl.java | 9 +- .../system/service/impl/SysBaseApiImpl.java | 17 +- .../service/impl/SysDepartServiceImpl.java | 3 +- .../impl/SysTenantPackServiceImpl.java | 3 +- .../service/impl/SysTenantServiceImpl.java | 15 +- .../impl/SysThirdAccountServiceImpl.java | 3 +- .../impl/SysUserDepartServiceImpl.java | 5 +- .../service/impl/SysUserServiceImpl.java | 5 +- .../controller/${entityName}Controller.javai | 12 +- .../controller/${entityName}Controller.javai | 12 +- .../controller/${entityName}Controller.javai | 12 +- .../controller/${entityName}Controller.javai | 12 +- .../controller/${entityName}Controller.javai | 12 +- .../controller/${entityName}Controller.javai | 12 +- .../controller/${entityName}Controller.javai | 12 +- .../src/main/resources/application.yml | 32 +- .../src/main/resources/application.yml | 2 +- .../src/main/resources/application.yml | 20 +- 68 files changed, 1228 insertions(+), 340 deletions(-) delete mode 100644 derby.log create mode 100644 jeecg-boot-base-core/src/main/java/org/jeecg/config/security/JeecgPermissionService.java create mode 100644 jeecg-boot-base-core/src/main/java/org/jeecg/config/security/LoginType.java create mode 100644 jeecg-boot-base-core/src/main/java/org/jeecg/config/security/app/AppGrantAuthenticationConvert.java create mode 100644 jeecg-boot-base-core/src/main/java/org/jeecg/config/security/app/AppGrantAuthenticationProvider.java create mode 100644 jeecg-boot-base-core/src/main/java/org/jeecg/config/security/app/AppGrantAuthenticationToken.java create mode 100644 jeecg-boot-base-core/src/main/java/org/jeecg/config/security/phone/PhoneGrantAuthenticationConvert.java create mode 100644 jeecg-boot-base-core/src/main/java/org/jeecg/config/security/phone/PhoneGrantAuthenticationProvider.java create mode 100644 jeecg-boot-base-core/src/main/java/org/jeecg/config/security/phone/PhoneGrantAuthenticationToken.java create mode 100644 jeecg-boot-base-core/src/main/java/org/jeecg/config/security/utils/SecureUtil.java diff --git a/.gitignore b/.gitignore index f7e65b4f5..5b3005449 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,6 @@ rebel.xml ## front **/*.lock -os_del.cmd \ No newline at end of file +os_del.cmd + +*.log \ No newline at end of file diff --git a/derby.log b/derby.log deleted file mode 100644 index fc66fb70f..000000000 --- a/derby.log +++ /dev/null @@ -1,13 +0,0 @@ ----------------------------------------------------------------- -Mon Nov 06 11:45:05 CST 2023: -Booting Derby version The Apache Software Foundation - Apache Derby - 10.14.2.0 - (1828579): instance a816c00e-018b-a2bb-db1d-000001f2c9e8 -on database directory memory:D:\dev\workspace_idea\jeecg\jeecg-boot\b8bc13ee-4d9a-4fe9-b521-8d23d69f4e24 with class loader jdk.internal.loader.ClassLoaders$AppClassLoader@63947c6b -Loaded from file:/D:/repository/org/apache/derby/derby/10.14.2.0/derby-10.14.2.0.jar -java.vendor=Oracle Corporation -java.runtime.version=17.0.9+11-LTS-201 -user.dir=D:\dev\workspace_idea\jeecg\jeecg-boot -os.name=Windows 11 -os.arch=amd64 -os.version=10.0 -derby.system.home=null -Database Class Loader started - derby.database.classpath='' diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/api/CommonAPI.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/api/CommonAPI.java index 0013f4ef4..79b60305e 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/common/api/CommonAPI.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/api/CommonAPI.java @@ -50,6 +50,13 @@ public interface CommonAPI { */ public LoginUser getUserByName(String username); + /** + * 5根据用户手机号查询用户信息 + * @param username + * @return + */ + public LoginUser getUserByPhone(String phone); + /** * 6字典表的 翻译 diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/AutoLogAspect.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/AutoLogAspect.java index 44443e0cb..42200a1c6 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/AutoLogAspect.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/AutoLogAspect.java @@ -3,7 +3,6 @@ package org.jeecg.common.aspect; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.serializer.PropertyFilter; -import org.apache.shiro.SecurityUtils; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; @@ -16,6 +15,7 @@ import org.jeecg.common.aspect.annotation.AutoLog; import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.enums.ModuleType; import org.jeecg.common.constant.enums.OperateTypeEnum; +import org.jeecg.config.security.utils.SecureUtil; import org.jeecg.modules.base.service.BaseCommonService; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.IpUtils; @@ -102,7 +102,7 @@ public class AutoLogAspect { //设置IP地址 dto.setIp(IpUtils.getIpAddr(request)); //获取登录用户信息 - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); if(sysUser!=null){ dto.setUserid(sysUser.getUsername()); dto.setUsername(sysUser.getRealname()); diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/exception/JeecgBootExceptionHandler.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/exception/JeecgBootExceptionHandler.java index 6e92c2c64..f69b8d049 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/common/exception/JeecgBootExceptionHandler.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/exception/JeecgBootExceptionHandler.java @@ -10,6 +10,7 @@ import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.DuplicateKeyException; import org.springframework.data.redis.connection.PoolException; import org.springframework.http.HttpStatus; +import org.springframework.security.access.AccessDeniedException; import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; @@ -92,6 +93,12 @@ public class JeecgBootExceptionHandler { return Result.noauth("没有权限,请联系管理员授权"); } + @ExceptionHandler(AccessDeniedException.class) + public Result handleAuthorizationException(AccessDeniedException e){ + log.error(e.getMessage(), e); + return Result.noauth("没有权限,请联系管理员授权"); + } + @ExceptionHandler(Exception.class) public Result handleException(Exception e){ log.error(e.getMessage(), e); diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/base/controller/JeecgController.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/base/controller/JeecgController.java index e9f577276..4f703754d 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/base/controller/JeecgController.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/base/controller/JeecgController.java @@ -13,6 +13,7 @@ import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.oConvertUtils; import org.jeecg.config.JeecgBaseConfig; +import org.jeecg.config.security.utils.SecureUtil; import org.jeecgframework.poi.excel.ExcelImportUtil; import org.jeecgframework.poi.excel.def.NormalExcelConstants; import org.jeecgframework.poi.excel.entity.ExportParams; @@ -53,7 +54,7 @@ public class JeecgController> { protected ModelAndView exportXls(HttpServletRequest request, T object, Class clazz, String title) { // Step.1 组装查询条件 QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(object, request.getParameterMap()); - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); // 过滤选中数据 String selections = request.getParameter("selections"); @@ -91,7 +92,7 @@ public class JeecgController> { protected ModelAndView exportXlsSheet(HttpServletRequest request, T object, Class clazz, String title,String exportFields,Integer pageNum) { // Step.1 组装查询条件 QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(object, request.getParameterMap()); - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); // Step.2 计算分页sheet数据 double total = service.count(); int count = (int)Math.ceil(total/pageNum); diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/util/JwtUtil.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/util/JwtUtil.java index a059f857d..da97d9573 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/util/JwtUtil.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/util/JwtUtil.java @@ -19,7 +19,6 @@ import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; import lombok.extern.slf4j.Slf4j; -import org.apache.shiro.SecurityUtils; import org.jeecg.common.api.vo.Result; import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.DataBaseConstant; @@ -31,6 +30,7 @@ import org.jeecg.common.system.vo.SysUserCacheInfo; import org.jeecg.common.util.DateUtils; import org.jeecg.common.util.SpringContextUtils; import org.jeecg.common.util.oConvertUtils; +import org.jeecg.config.security.utils.SecureUtil; import org.springframework.security.core.context.SecurityContextHolder; /** @@ -98,7 +98,7 @@ public class JwtUtil { public static String getUsername(String token) { try { DecodedJWT jwt = JWT.decode(token); - LoginUser loginUser = JSONObject.parseObject(jwt.getClaim("sub").asString(), LoginUser.class); + LoginUser loginUser = SecureUtil.currentUser(); return loginUser.getUsername(); } catch (JWTDecodeException e) { return null; @@ -181,7 +181,7 @@ public class JwtUtil { //2.通过shiro获取登录用户信息 LoginUser sysUser = null; try { - sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + sysUser = SecureUtil.currentUser(); } catch (Exception e) { log.warn("SecurityUtils.getSubject() 获取用户信息异常:" + e.getMessage()); } diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/vo/LoginUser.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/vo/LoginUser.java index c0a83364c..1c63fe232 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/vo/LoginUser.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/vo/LoginUser.java @@ -1,15 +1,18 @@ package org.jeecg.common.system.vo; +import com.alibaba.fastjson2.JSON; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; import org.jeecg.common.desensitization.annotation.SensitiveField; import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; import java.io.Serializable; -import java.text.SimpleDateFormat; import java.util.Date; +import java.util.Set; /** *

@@ -136,27 +139,24 @@ public class LoginUser implements Serializable { @Override public String toString() { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - return "{" + - "\"id\":\"" + id + '"' + - ", \"username\":\"" + username + '"' + - ", \"realname\":\"" + realname + '"' + - ", \"password\":\"'" + password + '"' + - ", \"orgCode\":\"" + orgCode + '"' + - ", \"avatar\":\"" + avatar + '"' + - ", \"sex\":" + sex + - ", \"email\":\"" + email + '"' + - ", \"phone\":\"" + phone + '"' + - ", \"status\":" + status + - ", \"delFlag\":" + delFlag + - ", \"activitiSync\":" + activitiSync + - ", \"userIdentity\":" + userIdentity + - ", \"departIds\":\"" + departIds + '"' + - ", \"post\":\"" + post + '"' + - ", \"telephone\":\"" + telephone + '"' + - ", \"relTenantIds\":\"" + relTenantIds + '"' + - ", \"clientId\":\"" + clientId + '"' + - ", \"salt\":\"" + salt + '"' + - '}'; + // 重新构建对象过滤一些敏感字段 + LoginUser loginUser = new LoginUser(); + loginUser.setId(id); + loginUser.setUsername(username); + loginUser.setRealname(realname); + loginUser.setOrgCode(orgCode); + loginUser.setSex(sex); + loginUser.setEmail(email); + loginUser.setPhone(phone); + loginUser.setDelFlag(delFlag); + loginUser.setStatus(status); + loginUser.setActivitiSync(activitiSync); + loginUser.setUserIdentity(userIdentity); + loginUser.setDepartIds(departIds); + loginUser.setPost(post); + loginUser.setTelephone(telephone); + loginUser.setRelTenantIds(relTenantIds); + loginUser.setClientId(clientId); + return JSON.toJSONString(loginUser); } } diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/config/firewall/interceptor/LowCodeModeInterceptor.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/firewall/interceptor/LowCodeModeInterceptor.java index 215351d29..071d14068 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/config/firewall/interceptor/LowCodeModeInterceptor.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/config/firewall/interceptor/LowCodeModeInterceptor.java @@ -6,15 +6,12 @@ import org.apache.shiro.SecurityUtils; import org.jeecg.common.api.CommonAPI; import org.jeecg.common.api.vo.Result; import org.jeecg.common.constant.CommonConstant; -import org.jeecg.common.exception.JeecgBootException; import org.jeecg.common.system.util.JwtUtil; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.CommonUtils; import org.jeecg.common.util.SpringContextUtils; import org.jeecg.config.JeecgBaseConfig; -import org.jeecg.config.firewall.interceptor.enums.LowCodeUrlsEnum; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.util.AntPathMatcher; import org.springframework.web.servlet.HandlerInterceptor; import jakarta.annotation.Resource; diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/JeecgPermissionService.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/JeecgPermissionService.java new file mode 100644 index 000000000..69e102530 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/JeecgPermissionService.java @@ -0,0 +1,53 @@ +package org.jeecg.config.security; + +import cn.hutool.core.util.ArrayUtil; +import lombok.AllArgsConstructor; +import org.jeecg.common.api.CommonAPI; +import org.jeecg.common.system.vo.LoginUser; +import org.jeecg.config.security.utils.SecureUtil; +import org.springframework.stereotype.Service; +import org.springframework.util.PatternMatchUtils; +import org.springframework.util.StringUtils; + +import java.util.Set; + +/** + * @author EightMonth + * @date 2024/1/10 17:00 + */ +@Service("jps") +@AllArgsConstructor +public class JeecgPermissionService { + + private final CommonAPI commonAPI; + + /** + * 判断接口是否有任意xxx,xxx权限 + * @param permissions 权限 + * @return {boolean} + */ + public boolean requiresPermissions(String... permissions) { + if (ArrayUtil.isEmpty(permissions)) { + return false; + } + LoginUser loginUser = SecureUtil.currentUser(); + Set permissionList = commonAPI.queryUserAuths(loginUser.getUsername()); + return permissionList.stream().filter(StringUtils::hasText) + .anyMatch(x -> PatternMatchUtils.simpleMatch(permissions, x)); + } + + /** + * 判断接口是否有任意xxx,xxx角色 + * @param roles 角色 + * @return {boolean} + */ + public boolean requiresRoles(String... roles) { + if (ArrayUtil.isEmpty(roles)) { + return false; + } + LoginUser loginUser = SecureUtil.currentUser(); + Set roleList = commonAPI.queryUserRoles(loginUser.getUsername()); + return roleList.stream().filter(StringUtils::hasText) + .anyMatch(x -> PatternMatchUtils.simpleMatch(roles, x)); + } +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/LoginType.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/LoginType.java new file mode 100644 index 000000000..06e59a8a3 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/LoginType.java @@ -0,0 +1,31 @@ +package org.jeecg.config.security; + +/** + * 登录模式 + * @author EightMonth + * @date 2024/1/10 17:43 + */ +public class LoginType { + + /** + * 密码模式 + */ + public static final String PASSWORD = "password"; + + + /** + * 手机号+验证码模式 + */ + public static final String PHONE = "phone"; + + + /** + * app登录 + */ + public static final String APP = "app"; + + /** + * 扫码登录 + */ + public static final String SCAN = "scan"; +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/SecurityConfig.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/SecurityConfig.java index cdec413f9..809cca92b 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/SecurityConfig.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/SecurityConfig.java @@ -6,36 +6,22 @@ import com.nimbusds.jose.jwk.source.ImmutableJWKSet; import com.nimbusds.jose.jwk.source.JWKSource; import com.nimbusds.jose.proc.SecurityContext; import lombok.AllArgsConstructor; -import org.jeecg.common.api.CommonAPI; -import org.jeecg.common.util.RedisUtil; -import org.jeecg.config.JeecgBaseConfig; import org.jeecg.config.security.password.PasswordGrantAuthenticationConvert; import org.jeecg.config.security.password.PasswordGrantAuthenticationProvider; -import org.jeecg.modules.base.service.BaseCommonService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.security.servlet.PathRequest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; -import org.springframework.data.redis.core.RedisTemplate; import org.springframework.http.MediaType; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.factory.PasswordEncoderFactories; import org.springframework.security.crypto.password.NoOpPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames; -import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames; -import org.springframework.security.oauth2.jwt.JwsHeader; -import org.springframework.security.oauth2.jwt.JwtClaimsSet; import org.springframework.security.oauth2.jwt.JwtDecoder; import org.springframework.security.oauth2.jwt.NimbusJwtEncoder; -import org.springframework.security.oauth2.server.authorization.*; +import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; @@ -52,9 +38,7 @@ import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; -import java.time.Instant; import java.util.Arrays; -import java.util.Date; import java.util.UUID; /** @@ -69,10 +53,6 @@ public class SecurityConfig { private JdbcTemplate jdbcTemplate; private OAuth2AuthorizationService authorizationService; - private final CommonAPI commonAPI; - private final RedisUtil redisUtil; - private final JeecgBaseConfig jeecgBaseConfig; - private final BaseCommonService baseCommonService; @Bean @Order(1) @@ -81,7 +61,7 @@ public class SecurityConfig { OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); http.getConfigurer(OAuth2AuthorizationServerConfigurer.class) .tokenEndpoint(tokenEndpoint -> tokenEndpoint.accessTokenRequestConverter(new PasswordGrantAuthenticationConvert()) - .authenticationProvider(new PasswordGrantAuthenticationProvider(jwtCustomizer(), authorizationService, tokenGenerator(), commonAPI, redisUtil, jeecgBaseConfig, baseCommonService))) + .authenticationProvider(new PasswordGrantAuthenticationProvider(authorizationService, tokenGenerator()))) //开启OpenID Connect 1.0(其中oidc为OpenID Connect的缩写)。 访问 /.well-known/openid-configuration即可获取认证信息 .oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0 http @@ -251,21 +231,4 @@ public class SecurityConfig { jwtGenerator, accessTokenGenerator, refreshTokenGenerator); } - @Bean - public OAuth2TokenCustomizer jwtCustomizer() { - return context -> { - JwsHeader.Builder headers = context.getJwsHeader(); - JwtClaimsSet.Builder claims = context.getClaims(); - if (context.getTokenType().equals(OAuth2TokenType.ACCESS_TOKEN)) { - // 自定义 access_token headers/claims - claims.claim("username", context.getPrincipal().getName()); - - } else if (context.getTokenType().getValue().equals(OidcParameterNames.ID_TOKEN)) { - // 自定义 id_token headers/claims for - claims.claim(IdTokenClaimNames.AUTH_TIME, Date.from(Instant.now())); - - } - }; - } - } diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/app/AppGrantAuthenticationConvert.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/app/AppGrantAuthenticationConvert.java new file mode 100644 index 000000000..588f8fd85 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/app/AppGrantAuthenticationConvert.java @@ -0,0 +1,80 @@ +package org.jeecg.config.security.app; + +import jakarta.servlet.http.HttpServletRequest; +import org.jeecg.config.security.LoginType; +import org.jeecg.config.security.password.PasswordGrantAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.core.OAuth2AuthenticationException; +import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; +import org.springframework.security.web.authentication.AuthenticationConverter; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.util.StringUtils; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author EightMonth + * @date 2024/1/1 + */ +public class AppGrantAuthenticationConvert implements AuthenticationConverter { + @Override + public Authentication convert(HttpServletRequest request) { + + String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE); + if (!LoginType.APP.equals(grantType)) { + return null; + } + + Authentication clientPrincipal = SecurityContextHolder.getContext().getAuthentication(); + + //从request中提取请求参数,然后存入MultiValueMap + MultiValueMap parameters = getParameters(request); + + // username (REQUIRED) + String username = parameters.getFirst(OAuth2ParameterNames.USERNAME); + if (!StringUtils.hasText(username) || + parameters.get(OAuth2ParameterNames.USERNAME).size() != 1) { + throw new OAuth2AuthenticationException("无效请求,用户名不能为空!"); + } + String password = parameters.getFirst(OAuth2ParameterNames.PASSWORD); + if (!StringUtils.hasText(password) || + parameters.get(OAuth2ParameterNames.PASSWORD).size() != 1) { + throw new OAuth2AuthenticationException("无效请求,密码不能为空!"); + } + + //收集要传入PasswordGrantAuthenticationToken构造方法的参数, + //该参数接下来在PasswordGrantAuthenticationProvider中使用 + Map additionalParameters = new HashMap<>(); + //遍历从request中提取的参数,排除掉grant_type、client_id、code等字段参数,其他参数收集到additionalParameters中 + parameters.forEach((key, value) -> { + if (!key.equals(OAuth2ParameterNames.GRANT_TYPE) && + !key.equals(OAuth2ParameterNames.CLIENT_ID) && + !key.equals(OAuth2ParameterNames.CODE)) { + additionalParameters.put(key, value.get(0)); + } + }); + + //返回自定义的PasswordGrantAuthenticationToken对象 + return new PasswordGrantAuthenticationToken(clientPrincipal, additionalParameters); + + } + + /** + *从request中提取请求参数,然后存入MultiValueMap + */ + private static MultiValueMap getParameters(HttpServletRequest request) { + Map parameterMap = request.getParameterMap(); + MultiValueMap parameters = new LinkedMultiValueMap<>(parameterMap.size()); + parameterMap.forEach((key, values) -> { + if (values.length > 0) { + for (String value : values) { + parameters.add(key, value); + } + } + }); + return parameters; + } +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/app/AppGrantAuthenticationProvider.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/app/AppGrantAuthenticationProvider.java new file mode 100644 index 000000000..29ef8b127 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/app/AppGrantAuthenticationProvider.java @@ -0,0 +1,284 @@ +package org.jeecg.config.security.app; + +import lombok.extern.slf4j.Slf4j; +import org.jeecg.common.api.CommonAPI; +import org.jeecg.common.constant.CommonConstant; +import org.jeecg.common.exception.JeecgBootException; +import org.jeecg.common.exception.JeecgCaptchaException; +import org.jeecg.common.system.vo.LoginUser; +import org.jeecg.common.system.vo.SysDepartModel; +import org.jeecg.common.util.Md5Util; +import org.jeecg.common.util.PasswordUtil; +import org.jeecg.common.util.RedisUtil; +import org.jeecg.common.util.oConvertUtils; +import org.jeecg.config.JeecgBaseConfig; +import org.jeecg.config.security.password.PasswordGrantAuthenticationToken; +import org.jeecg.modules.base.service.BaseCommonService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.oauth2.core.*; +import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; +import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; +import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; +import org.springframework.security.oauth2.server.authorization.OAuth2TokenType; +import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AccessTokenAuthenticationToken; +import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken; +import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; +import org.springframework.security.oauth2.server.authorization.context.AuthorizationServerContextHolder; +import org.springframework.security.oauth2.server.authorization.token.DefaultOAuth2TokenContext; +import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenContext; +import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator; +import org.springframework.util.Assert; + +import java.security.Principal; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @author EightMonth + * @date 2024/1/1 + */ +@Slf4j +public class AppGrantAuthenticationProvider implements AuthenticationProvider { + + private static final String ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc6749#section-5.2"; + + private final OAuth2AuthorizationService authorizationService; + private final OAuth2TokenGenerator tokenGenerator; + @Autowired + private CommonAPI commonAPI; + @Autowired + private RedisUtil redisUtil; + @Autowired + private JeecgBaseConfig jeecgBaseConfig; + @Autowired + private BaseCommonService baseCommonService; + + public AppGrantAuthenticationProvider(OAuth2AuthorizationService authorizationService, OAuth2TokenGenerator tokenGenerator) { + Assert.notNull(authorizationService, "authorizationService cannot be null"); + Assert.notNull(tokenGenerator, "tokenGenerator cannot be null"); + this.authorizationService = authorizationService; + this.tokenGenerator = tokenGenerator; + } + + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + PasswordGrantAuthenticationToken passwordGrantAuthenticationToken = (PasswordGrantAuthenticationToken) authentication; + Map additionalParameter = passwordGrantAuthenticationToken.getAdditionalParameters(); + + // 授权类型 + AuthorizationGrantType authorizationGrantType = passwordGrantAuthenticationToken.getGrantType(); + // 用户名 + String username = (String) additionalParameter.get(OAuth2ParameterNames.USERNAME); + // 密码 + String password = (String) additionalParameter.get(OAuth2ParameterNames.PASSWORD); + //请求参数权限范围 + String requestScopesStr = (String)additionalParameter.getOrDefault(OAuth2ParameterNames.SCOPE, "*"); + //请求参数权限范围专场集合 + Set requestScopeSet = Stream.of(requestScopesStr.split(" ")).collect(Collectors.toSet()); + // 验证码 + String captcha = (String) additionalParameter.get("captcha"); + String checkKey = (String) additionalParameter.get("checkKey"); + + + if(isLoginFailOvertimes(username)){ + throw new JeecgBootException("该用户登录失败次数过多,请于10分钟后再次登录!"); + } + + if(captcha==null){ + throw new JeecgBootException("验证码无效"); + } + String lowerCaseCaptcha = captcha.toLowerCase(); + // 加入密钥作为混淆,避免简单的拼接,被外部利用,用户自定义该密钥即可 + String origin = lowerCaseCaptcha+checkKey+jeecgBaseConfig.getSignatureSecret(); + String realKey = Md5Util.md5Encode(origin, "utf-8"); + Object checkCode = redisUtil.get(realKey); + //当进入登录页时,有一定几率出现验证码错误 #1714 + if(checkCode==null || !checkCode.toString().equals(lowerCaseCaptcha)) { + log.warn("验证码错误,key= {} , Ui checkCode= {}, Redis checkCode = {}", checkKey, lowerCaseCaptcha, checkCode); + // 改成特殊的code 便于前端判断 + throw new JeecgCaptchaException(HttpStatus.PRECONDITION_FAILED.value(), "验证码错误"); + } + + OAuth2ClientAuthenticationToken clientPrincipal = getAuthenticatedClientElseThrowInvalidClient(passwordGrantAuthenticationToken); + RegisteredClient registeredClient = clientPrincipal.getRegisteredClient(); + + if (!registeredClient.getAuthorizationGrantTypes().contains(authorizationGrantType)) { + throw new JeecgBootException("非法登录"); + } + + LoginUser loginUser = commonAPI.getUserByName(username); + // 检查用户可行性 + checkUserIsEffective(loginUser); + + // 不使用spring security passwordEncoder针对密码进行匹配,使用自有加密匹配,针对 spring security使用noop传输 + password = PasswordUtil.encrypt(username, password, loginUser.getSalt()); + if (!password.equals(loginUser.getPassword())) { + addLoginFailOvertimes(username); + throw new JeecgBootException("用户名或密码不正确"); + } + + //由于在上面已验证过用户名、密码,现在构建一个已认证的对象UsernamePasswordAuthenticationToken + UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = UsernamePasswordAuthenticationToken.authenticated(loginUser,clientPrincipal,new ArrayList<>()); + + DefaultOAuth2TokenContext.Builder tokenContextBuilder = DefaultOAuth2TokenContext.builder() + .registeredClient(registeredClient) + .principal(usernamePasswordAuthenticationToken) + .authorizationServerContext(AuthorizationServerContextHolder.getContext()) + .authorizationGrantType(authorizationGrantType) + .authorizedScopes(requestScopeSet) + .authorizationGrant(passwordGrantAuthenticationToken); + + OAuth2Authorization.Builder authorizationBuilder = OAuth2Authorization.withRegisteredClient(registeredClient) + .principalName(clientPrincipal.getName()) + .authorizedScopes(requestScopeSet) + .attribute(Principal.class.getName(), username) + .authorizationGrantType(authorizationGrantType); + + + // ----- Access token ----- + OAuth2TokenContext tokenContext = tokenContextBuilder.tokenType(OAuth2TokenType.ACCESS_TOKEN).build(); + OAuth2Token generatedAccessToken = this.tokenGenerator.generate(tokenContext); + if (generatedAccessToken == null) { + OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.SERVER_ERROR, + "无法生成访问token,请联系管理系。", ERROR_URI); + throw new OAuth2AuthenticationException(error); + } + OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, + generatedAccessToken.getTokenValue(), generatedAccessToken.getIssuedAt(), + generatedAccessToken.getExpiresAt(), tokenContext.getAuthorizedScopes()); + if (generatedAccessToken instanceof ClaimAccessor) { + authorizationBuilder.token(accessToken, (metadata) -> { + metadata.put(OAuth2Authorization.Token.CLAIMS_METADATA_NAME, ((ClaimAccessor) generatedAccessToken).getClaims()); + }); + } else { + authorizationBuilder.accessToken(accessToken); + } + + // ----- Refresh token ----- + OAuth2RefreshToken refreshToken = null; + if (registeredClient.getAuthorizationGrantTypes().contains(AuthorizationGrantType.REFRESH_TOKEN) && + // 不向公共客户端颁发刷新令牌 + !clientPrincipal.getClientAuthenticationMethod().equals(ClientAuthenticationMethod.NONE)) { + + tokenContext = tokenContextBuilder.tokenType(OAuth2TokenType.REFRESH_TOKEN).build(); + OAuth2Token generatedRefreshToken = this.tokenGenerator.generate(tokenContext); + if (!(generatedRefreshToken instanceof OAuth2RefreshToken)) { + OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.SERVER_ERROR, + "无法生成刷新token,请联系管理员。", ERROR_URI); + throw new OAuth2AuthenticationException(error); + } + + refreshToken = (OAuth2RefreshToken) generatedRefreshToken; + authorizationBuilder.refreshToken(refreshToken); + } + + OAuth2Authorization authorization = authorizationBuilder.build(); + + authorizationService.save(authorization); + + // 登录成功,删除redis中的验证码 + redisUtil.del(realKey); + redisUtil.del(CommonConstant.LOGIN_FAIL + username); + baseCommonService.addLog("用户名: " + username + ",登录成功!", CommonConstant.LOG_TYPE_1, null,loginUser); + + Map addition = new HashMap<>(); + // 设置登录用户信息 + addition.put("userInfo", loginUser); + addition.put("sysAllDictItems", commonAPI.queryAllDictItems()); + + List departs = commonAPI.queryUserDeparts(loginUser.getId()); + addition.put("departs", departs); + if (departs == null || departs.size() == 0) { + addition.put("multi_depart", 0); + } else if (departs.size() == 1) { + commonAPI.updateUserDepart(username, departs.get(0).getOrgCode(),null); + addition.put("multi_depart", 1); + } else { + //查询当前是否有登录部门 + if(oConvertUtils.isEmpty(loginUser.getOrgCode())){ + commonAPI.updateUserDepart(username, departs.get(0).getOrgCode(),null); + } + addition.put("multi_depart", 2); + } + + return new OAuth2AccessTokenAuthenticationToken(registeredClient, clientPrincipal, accessToken, refreshToken, addition); + } + + @Override + public boolean supports(Class authentication) { + return PasswordGrantAuthenticationToken.class.isAssignableFrom(authentication); + } + + private static OAuth2ClientAuthenticationToken getAuthenticatedClientElseThrowInvalidClient(Authentication authentication) { + OAuth2ClientAuthenticationToken clientPrincipal = null; + if (OAuth2ClientAuthenticationToken.class.isAssignableFrom(authentication.getPrincipal().getClass())) { + clientPrincipal = (OAuth2ClientAuthenticationToken) authentication.getPrincipal(); + } + if (clientPrincipal != null && clientPrincipal.isAuthenticated()) { + return clientPrincipal; + } + throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_CLIENT); + } + + /** + * 登录失败超出次数5 返回true + * @param username + * @return + */ + private boolean isLoginFailOvertimes(String username){ + String key = CommonConstant.LOGIN_FAIL + username; + Object failTime = redisUtil.get(key); + if(failTime!=null){ + Integer val = Integer.parseInt(failTime.toString()); + if(val>5){ + return true; + } + } + return false; + } + + /** + * 记录登录失败次数 + * @param username + */ + private void addLoginFailOvertimes(String username){ + String key = CommonConstant.LOGIN_FAIL + username; + Object failTime = redisUtil.get(key); + Integer val = 0; + if(failTime!=null){ + val = Integer.parseInt(failTime.toString()); + } + // 10分钟 + redisUtil.set(key, ++val, 10); + } + + /** + * 校验用户是否有效 + */ + private void checkUserIsEffective(LoginUser loginUser) { + //情况1:根据用户信息查询,该用户不存在 + if (Objects.isNull(loginUser)) { + baseCommonService.addLog("用户登录失败,用户不存在!", CommonConstant.LOG_TYPE_1, null); + throw new JeecgBootException("该用户不存在,请注册"); + } + //情况2:根据用户信息查询,该用户已注销 + //update-begin---author:王帅 Date:20200601 for:if条件永远为falsebug------------ + if (CommonConstant.DEL_FLAG_1.equals(loginUser.getDelFlag())) { + //update-end---author:王帅 Date:20200601 for:if条件永远为falsebug------------ + baseCommonService.addLog("用户登录失败,用户名:" + loginUser.getUsername() + "已注销!", CommonConstant.LOG_TYPE_1, null); + throw new JeecgBootException("该用户已注销"); + } + //情况3:根据用户信息查询,该用户已冻结 + if (CommonConstant.USER_FREEZE.equals(loginUser.getStatus())) { + baseCommonService.addLog("用户登录失败,用户名:" + loginUser.getUsername() + "已冻结!", CommonConstant.LOG_TYPE_1, null); + throw new JeecgBootException("该用户已冻结"); + } + } + +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/app/AppGrantAuthenticationToken.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/app/AppGrantAuthenticationToken.java new file mode 100644 index 000000000..619f028c7 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/app/AppGrantAuthenticationToken.java @@ -0,0 +1,20 @@ +package org.jeecg.config.security.app; + +import org.jeecg.config.security.LoginType; +import org.springframework.security.core.Authentication; +import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationGrantAuthenticationToken; + +import java.util.Map; + +/** + * @author EightMonth + * @date 2024/1/1 + */ +public class AppGrantAuthenticationToken extends OAuth2AuthorizationGrantAuthenticationToken { + + public AppGrantAuthenticationToken(Authentication clientPrincipal, Map additionalParameters) { + super(new AuthorizationGrantType(LoginType.APP), clientPrincipal, additionalParameters); + } + +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/password/PasswordGrantAuthenticationConvert.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/password/PasswordGrantAuthenticationConvert.java index b90d9cca0..9d0d5c440 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/password/PasswordGrantAuthenticationConvert.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/password/PasswordGrantAuthenticationConvert.java @@ -2,6 +2,7 @@ package org.jeecg.config.security.password; import jakarta.servlet.http.HttpServletRequest; import org.jeecg.common.constant.CommonConstant; +import org.jeecg.config.security.LoginType; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.oauth2.core.AuthorizationGrantType; @@ -16,7 +17,7 @@ import java.util.HashMap; import java.util.Map; /** - * @author kezhijie@co-mall.com + * @author EightMonth * @date 2024/1/1 */ public class PasswordGrantAuthenticationConvert implements AuthenticationConverter { @@ -24,7 +25,7 @@ public class PasswordGrantAuthenticationConvert implements AuthenticationConvert public Authentication convert(HttpServletRequest request) { String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE); - if (!AuthorizationGrantType.PASSWORD.getValue().equals(grantType)) { + if (!LoginType.PASSWORD.equals(grantType)) { return null; } diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/password/PasswordGrantAuthenticationProvider.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/password/PasswordGrantAuthenticationProvider.java index c99b6d5c2..c04a774ae 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/password/PasswordGrantAuthenticationProvider.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/password/PasswordGrantAuthenticationProvider.java @@ -13,11 +13,14 @@ import org.jeecg.common.util.RedisUtil; import org.jeecg.common.util.oConvertUtils; import org.jeecg.config.JeecgBaseConfig; import org.jeecg.modules.base.service.BaseCommonService; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.oauth2.core.*; import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; @@ -27,7 +30,9 @@ import org.springframework.security.oauth2.server.authorization.authentication.O import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken; import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.context.AuthorizationServerContextHolder; -import org.springframework.security.oauth2.server.authorization.token.*; +import org.springframework.security.oauth2.server.authorization.token.DefaultOAuth2TokenContext; +import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenContext; +import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator; import org.springframework.util.Assert; import java.security.Principal; @@ -46,22 +51,20 @@ public class PasswordGrantAuthenticationProvider implements AuthenticationProvid private final OAuth2AuthorizationService authorizationService; private final OAuth2TokenGenerator tokenGenerator; - private final CommonAPI commonAPI; - private final RedisUtil redisUtil; - private final JeecgBaseConfig jeecgBaseConfig; - private final BaseCommonService baseCommonService; - private final OAuth2TokenCustomizer oAuth2TokenCustomizer; + @Autowired + private CommonAPI commonAPI; + @Autowired + private RedisUtil redisUtil; + @Autowired + private JeecgBaseConfig jeecgBaseConfig; + @Autowired + private BaseCommonService baseCommonService; - public PasswordGrantAuthenticationProvider(OAuth2TokenCustomizer oAuth2TokenCustomizer, OAuth2AuthorizationService authorizationService, OAuth2TokenGenerator tokenGenerator, CommonAPI commonAPI, RedisUtil redisUtil, JeecgBaseConfig jeecgBaseConfig, BaseCommonService baseCommonService) { + public PasswordGrantAuthenticationProvider(OAuth2AuthorizationService authorizationService, OAuth2TokenGenerator tokenGenerator) { Assert.notNull(authorizationService, "authorizationService cannot be null"); Assert.notNull(tokenGenerator, "tokenGenerator cannot be null"); this.authorizationService = authorizationService; this.tokenGenerator = tokenGenerator; - this.commonAPI = commonAPI; - this.redisUtil = redisUtil; - this.jeecgBaseConfig = jeecgBaseConfig; - this.baseCommonService = baseCommonService; - this.oAuth2TokenCustomizer = oAuth2TokenCustomizer; } @Override @@ -125,7 +128,6 @@ public class PasswordGrantAuthenticationProvider implements AuthenticationProvid UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = UsernamePasswordAuthenticationToken.authenticated(loginUser,clientPrincipal,new ArrayList<>()); DefaultOAuth2TokenContext.Builder tokenContextBuilder = DefaultOAuth2TokenContext.builder() - .put("username", username) .registeredClient(registeredClient) .principal(usernamePasswordAuthenticationToken) .authorizationServerContext(AuthorizationServerContextHolder.getContext()) diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/password/PasswordGrantAuthenticationToken.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/password/PasswordGrantAuthenticationToken.java index 9b81873f3..0528167dc 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/password/PasswordGrantAuthenticationToken.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/password/PasswordGrantAuthenticationToken.java @@ -1,5 +1,6 @@ package org.jeecg.config.security.password; +import org.jeecg.config.security.LoginType; import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.core.AuthorizationGrantType; import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationGrantAuthenticationToken; @@ -7,13 +8,13 @@ import org.springframework.security.oauth2.server.authorization.authentication.O import java.util.Map; /** - * @author kezhijie@co-mall.com + * @author EightMonth * @date 2024/1/1 */ public class PasswordGrantAuthenticationToken extends OAuth2AuthorizationGrantAuthenticationToken { public PasswordGrantAuthenticationToken(Authentication clientPrincipal, Map additionalParameters) { - super(new AuthorizationGrantType(AuthorizationGrantType.PASSWORD.getValue()), clientPrincipal, additionalParameters); + super(new AuthorizationGrantType(LoginType.PASSWORD), clientPrincipal, additionalParameters); } } diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/phone/PhoneGrantAuthenticationConvert.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/phone/PhoneGrantAuthenticationConvert.java new file mode 100644 index 000000000..85f4b14f3 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/phone/PhoneGrantAuthenticationConvert.java @@ -0,0 +1,77 @@ +package org.jeecg.config.security.phone; + +import jakarta.servlet.http.HttpServletRequest; +import lombok.AllArgsConstructor; +import org.jeecg.config.security.LoginType; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.core.OAuth2AuthenticationException; +import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; +import org.springframework.security.web.authentication.AuthenticationConverter; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.util.StringUtils; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author EightMonth + * @date 2024/1/1 + */ +@AllArgsConstructor +public class PhoneGrantAuthenticationConvert implements AuthenticationConverter { + @Override + public Authentication convert(HttpServletRequest request) { + + String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE); + if (!LoginType.PHONE.equals(grantType)) { + return null; + } + + Authentication clientPrincipal = SecurityContextHolder.getContext().getAuthentication(); + + //从request中提取请求参数,然后存入MultiValueMap + MultiValueMap parameters = getParameters(request); + + // 验证码 + String captcha = parameters.getFirst("captcha"); + if (!StringUtils.hasText(captcha) || + parameters.get(OAuth2ParameterNames.USERNAME).size() != 1) { + throw new OAuth2AuthenticationException("无效请求,验证码不能为空!"); + } + + //收集要传入PhoneGrantAuthenticationToken构造方法的参数, + //该参数接下来在PhoneGrantAuthenticationProvider中使用 + Map additionalParameters = new HashMap<>(); + //遍历从request中提取的参数,排除掉grant_type、client_id、code等字段参数,其他参数收集到additionalParameters中 + parameters.forEach((key, value) -> { + if (!key.equals(OAuth2ParameterNames.GRANT_TYPE) && + !key.equals(OAuth2ParameterNames.CLIENT_ID) && + !key.equals(OAuth2ParameterNames.CODE)) { + additionalParameters.put(key, value.get(0)); + } + }); + + //返回自定义的PhoneGrantAuthenticationToken对象 + return new PhoneGrantAuthenticationToken(clientPrincipal, additionalParameters); + + } + + /** + *从request中提取请求参数,然后存入MultiValueMap + */ + private static MultiValueMap getParameters(HttpServletRequest request) { + Map parameterMap = request.getParameterMap(); + MultiValueMap parameters = new LinkedMultiValueMap<>(parameterMap.size()); + parameterMap.forEach((key, values) -> { + if (values.length > 0) { + for (String value : values) { + parameters.add(key, value); + } + } + }); + return parameters; + } + +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/phone/PhoneGrantAuthenticationProvider.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/phone/PhoneGrantAuthenticationProvider.java new file mode 100644 index 000000000..e2ed2355c --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/phone/PhoneGrantAuthenticationProvider.java @@ -0,0 +1,267 @@ +package org.jeecg.config.security.phone; + +import lombok.extern.slf4j.Slf4j; +import org.jeecg.common.api.CommonAPI; +import org.jeecg.common.constant.CommonConstant; +import org.jeecg.common.exception.JeecgBootException; +import org.jeecg.common.exception.JeecgCaptchaException; +import org.jeecg.common.system.vo.LoginUser; +import org.jeecg.common.system.vo.SysDepartModel; +import org.jeecg.common.util.Md5Util; +import org.jeecg.common.util.PasswordUtil; +import org.jeecg.common.util.RedisUtil; +import org.jeecg.common.util.oConvertUtils; +import org.jeecg.config.JeecgBaseConfig; +import org.jeecg.config.security.password.PasswordGrantAuthenticationToken; +import org.jeecg.modules.base.service.BaseCommonService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.oauth2.core.*; +import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; +import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; +import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; +import org.springframework.security.oauth2.server.authorization.OAuth2TokenType; +import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AccessTokenAuthenticationToken; +import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken; +import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; +import org.springframework.security.oauth2.server.authorization.context.AuthorizationServerContextHolder; +import org.springframework.security.oauth2.server.authorization.token.DefaultOAuth2TokenContext; +import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenContext; +import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator; +import org.springframework.util.Assert; + +import java.security.Principal; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @author EightMonth + * @date 2024/1/1 + */ +@Slf4j +public class PhoneGrantAuthenticationProvider implements AuthenticationProvider { + + private static final String ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc6749#section-5.2"; + + private final OAuth2AuthorizationService authorizationService; + private final OAuth2TokenGenerator tokenGenerator; + @Autowired + private CommonAPI commonAPI; + @Autowired + private RedisUtil redisUtil; + @Autowired + private JeecgBaseConfig jeecgBaseConfig; + @Autowired + private BaseCommonService baseCommonService; + + public PhoneGrantAuthenticationProvider(OAuth2AuthorizationService authorizationService, OAuth2TokenGenerator tokenGenerator) { + Assert.notNull(authorizationService, "authorizationService cannot be null"); + Assert.notNull(tokenGenerator, "tokenGenerator cannot be null"); + this.authorizationService = authorizationService; + this.tokenGenerator = tokenGenerator; + } + + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + PasswordGrantAuthenticationToken passwordGrantAuthenticationToken = (PasswordGrantAuthenticationToken) authentication; + Map additionalParameter = passwordGrantAuthenticationToken.getAdditionalParameters(); + + // 授权类型 + AuthorizationGrantType authorizationGrantType = passwordGrantAuthenticationToken.getGrantType(); + // 手机号 + String phone = (String) additionalParameter.get("mobile"); + + if(isLoginFailOvertimes(phone)){ + throw new JeecgBootException("该用户登录失败次数过多,请于10分钟后再次登录!"); + } + + //请求参数权限范围 + String requestScopesStr = (String)additionalParameter.getOrDefault(OAuth2ParameterNames.SCOPE, "*"); + //请求参数权限范围专场集合 + Set requestScopeSet = Stream.of(requestScopesStr.split(" ")).collect(Collectors.toSet()); + // 验证码 + String captcha = (String) additionalParameter.get("captcha"); + + LoginUser loginUser = commonAPI.getUserByPhone(phone); + // 检查用户可行性 + checkUserIsEffective(loginUser); + + + String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE+phone; + Object code = redisUtil.get(redisKey); + + if (!captcha.equals(code)) { + //update-begin-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户 + addLoginFailOvertimes(phone); + //update-end-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户 + throw new JeecgBootException("手机验证码错误"); + } + + OAuth2ClientAuthenticationToken clientPrincipal = getAuthenticatedClientElseThrowInvalidClient(passwordGrantAuthenticationToken); + RegisteredClient registeredClient = clientPrincipal.getRegisteredClient(); + + if (!registeredClient.getAuthorizationGrantTypes().contains(authorizationGrantType)) { + throw new JeecgBootException("非法登录"); + } + + //由于在上面已验证过用户名、密码,现在构建一个已认证的对象UsernamePasswordAuthenticationToken + UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = UsernamePasswordAuthenticationToken.authenticated(loginUser,clientPrincipal,new ArrayList<>()); + + DefaultOAuth2TokenContext.Builder tokenContextBuilder = DefaultOAuth2TokenContext.builder() + .registeredClient(registeredClient) + .principal(usernamePasswordAuthenticationToken) + .authorizationServerContext(AuthorizationServerContextHolder.getContext()) + .authorizationGrantType(authorizationGrantType) + .authorizedScopes(requestScopeSet) + .authorizationGrant(passwordGrantAuthenticationToken); + + OAuth2Authorization.Builder authorizationBuilder = OAuth2Authorization.withRegisteredClient(registeredClient) + .principalName(clientPrincipal.getName()) + .authorizedScopes(requestScopeSet) + .attribute(Principal.class.getName(), loginUser.getUsername()) + .authorizationGrantType(authorizationGrantType); + + + // ----- Access token ----- + OAuth2TokenContext tokenContext = tokenContextBuilder.tokenType(OAuth2TokenType.ACCESS_TOKEN).build(); + OAuth2Token generatedAccessToken = this.tokenGenerator.generate(tokenContext); + if (generatedAccessToken == null) { + OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.SERVER_ERROR, + "无法生成访问token,请联系管理系。", ERROR_URI); + throw new OAuth2AuthenticationException(error); + } + OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, + generatedAccessToken.getTokenValue(), generatedAccessToken.getIssuedAt(), + generatedAccessToken.getExpiresAt(), tokenContext.getAuthorizedScopes()); + if (generatedAccessToken instanceof ClaimAccessor) { + authorizationBuilder.token(accessToken, (metadata) -> { + metadata.put(OAuth2Authorization.Token.CLAIMS_METADATA_NAME, ((ClaimAccessor) generatedAccessToken).getClaims()); + }); + } else { + authorizationBuilder.accessToken(accessToken); + } + + // ----- Refresh token ----- + OAuth2RefreshToken refreshToken = null; + if (registeredClient.getAuthorizationGrantTypes().contains(AuthorizationGrantType.REFRESH_TOKEN) && + // 不向公共客户端颁发刷新令牌 + !clientPrincipal.getClientAuthenticationMethod().equals(ClientAuthenticationMethod.NONE)) { + + tokenContext = tokenContextBuilder.tokenType(OAuth2TokenType.REFRESH_TOKEN).build(); + OAuth2Token generatedRefreshToken = this.tokenGenerator.generate(tokenContext); + if (!(generatedRefreshToken instanceof OAuth2RefreshToken)) { + OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.SERVER_ERROR, + "无法生成刷新token,请联系管理员。", ERROR_URI); + throw new OAuth2AuthenticationException(error); + } + + refreshToken = (OAuth2RefreshToken) generatedRefreshToken; + authorizationBuilder.refreshToken(refreshToken); + } + + OAuth2Authorization authorization = authorizationBuilder.build(); + + authorizationService.save(authorization); + + baseCommonService.addLog("用户名: " + loginUser.getUsername() + ",登录成功!", CommonConstant.LOG_TYPE_1, null,loginUser); + + Map addition = new HashMap<>(); + // 设置登录用户信息 + addition.put("userInfo", loginUser); + addition.put("sysAllDictItems", commonAPI.queryAllDictItems()); + + List departs = commonAPI.queryUserDeparts(loginUser.getId()); + addition.put("departs", departs); + if (departs == null || departs.size() == 0) { + addition.put("multi_depart", 0); + } else if (departs.size() == 1) { + commonAPI.updateUserDepart(loginUser.getUsername(), departs.get(0).getOrgCode(),null); + addition.put("multi_depart", 1); + } else { + //查询当前是否有登录部门 + if(oConvertUtils.isEmpty(loginUser.getOrgCode())){ + commonAPI.updateUserDepart(loginUser.getUsername(), departs.get(0).getOrgCode(),null); + } + addition.put("multi_depart", 2); + } + + return new OAuth2AccessTokenAuthenticationToken(registeredClient, clientPrincipal, accessToken, refreshToken, addition); + } + + @Override + public boolean supports(Class authentication) { + return PasswordGrantAuthenticationToken.class.isAssignableFrom(authentication); + } + + private static OAuth2ClientAuthenticationToken getAuthenticatedClientElseThrowInvalidClient(Authentication authentication) { + OAuth2ClientAuthenticationToken clientPrincipal = null; + if (OAuth2ClientAuthenticationToken.class.isAssignableFrom(authentication.getPrincipal().getClass())) { + clientPrincipal = (OAuth2ClientAuthenticationToken) authentication.getPrincipal(); + } + if (clientPrincipal != null && clientPrincipal.isAuthenticated()) { + return clientPrincipal; + } + throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_CLIENT); + } + + /** + * 登录失败超出次数5 返回true + * @param username + * @return + */ + private boolean isLoginFailOvertimes(String username){ + String key = CommonConstant.LOGIN_FAIL + username; + Object failTime = redisUtil.get(key); + if(failTime!=null){ + Integer val = Integer.parseInt(failTime.toString()); + if(val>5){ + return true; + } + } + return false; + } + + /** + * 记录登录失败次数 + * @param username + */ + private void addLoginFailOvertimes(String username){ + String key = CommonConstant.LOGIN_FAIL + username; + Object failTime = redisUtil.get(key); + Integer val = 0; + if(failTime!=null){ + val = Integer.parseInt(failTime.toString()); + } + // 10分钟 + redisUtil.set(key, ++val, 10); + } + + /** + * 校验用户是否有效 + */ + private void checkUserIsEffective(LoginUser loginUser) { + //情况1:根据用户信息查询,该用户不存在 + if (Objects.isNull(loginUser)) { + baseCommonService.addLog("用户登录失败,用户不存在!", CommonConstant.LOG_TYPE_1, null); + throw new JeecgBootException("该用户不存在,请注册"); + } + //情况2:根据用户信息查询,该用户已注销 + //update-begin---author:王帅 Date:20200601 for:if条件永远为falsebug------------ + if (CommonConstant.DEL_FLAG_1.equals(loginUser.getDelFlag())) { + //update-end---author:王帅 Date:20200601 for:if条件永远为falsebug------------ + baseCommonService.addLog("用户登录失败,用户名:" + loginUser.getUsername() + "已注销!", CommonConstant.LOG_TYPE_1, null); + throw new JeecgBootException("该用户已注销"); + } + //情况3:根据用户信息查询,该用户已冻结 + if (CommonConstant.USER_FREEZE.equals(loginUser.getStatus())) { + baseCommonService.addLog("用户登录失败,用户名:" + loginUser.getUsername() + "已冻结!", CommonConstant.LOG_TYPE_1, null); + throw new JeecgBootException("该用户已冻结"); + } + } + +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/phone/PhoneGrantAuthenticationToken.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/phone/PhoneGrantAuthenticationToken.java new file mode 100644 index 000000000..68110cf6b --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/phone/PhoneGrantAuthenticationToken.java @@ -0,0 +1,20 @@ +package org.jeecg.config.security.phone; + +import org.jeecg.config.security.LoginType; +import org.springframework.security.core.Authentication; +import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationGrantAuthenticationToken; + +import java.util.Map; + +/** + * @author EightMonth + * @date 2024/1/1 + */ +public class PhoneGrantAuthenticationToken extends OAuth2AuthorizationGrantAuthenticationToken { + + public PhoneGrantAuthenticationToken(Authentication clientPrincipal, Map additionalParameters) { + super(new AuthorizationGrantType(LoginType.PHONE), clientPrincipal, additionalParameters); + } + +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/utils/SecureUtil.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/utils/SecureUtil.java new file mode 100644 index 000000000..f9a416b75 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/config/security/utils/SecureUtil.java @@ -0,0 +1,17 @@ +package org.jeecg.config.security.utils; + +import com.alibaba.fastjson2.JSONObject; +import org.jeecg.common.system.vo.LoginUser; +import org.springframework.security.core.context.SecurityContextHolder; + +/** + * @author EightMonth + * @date 2024/1/10 17:03 + */ +public class SecureUtil { + + public static LoginUser currentUser() { + String name = SecurityContextHolder.getContext().getAuthentication().getName(); + return JSONObject.parseObject(name, LoginUser.class); + } +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroRealm.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroRealm.java index 1d1b59f61..3f1ee9cbf 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroRealm.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroRealm.java @@ -20,7 +20,6 @@ import org.jeecg.common.util.SpringContextUtils; import org.jeecg.common.util.TokenUtils; import org.jeecg.common.util.oConvertUtils; import org.springframework.context.annotation.Lazy; -import org.springframework.stereotype.Component; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletRequest; diff --git a/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/controller/JeecgOrderMainController.java b/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/controller/JeecgOrderMainController.java index fa74020e6..79597706d 100644 --- a/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/controller/JeecgOrderMainController.java +++ b/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/controller/JeecgOrderMainController.java @@ -15,6 +15,7 @@ import org.jeecg.common.system.base.controller.JeecgController; import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.oConvertUtils; +import org.jeecg.config.security.utils.SecureUtil; import org.jeecg.modules.demo.test.entity.JeecgDemo; import org.jeecg.modules.demo.test.entity.JeecgOrderCustomer; import org.jeecg.modules.demo.test.entity.JeecgOrderMain; @@ -186,7 +187,7 @@ public class JeecgOrderMainController extends JeecgController pageList = new ArrayList(); diff --git a/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/service/impl/JeecgDemoServiceImpl.java b/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/service/impl/JeecgDemoServiceImpl.java index 6b5f87cfc..5a202c51e 100644 --- a/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/service/impl/JeecgDemoServiceImpl.java +++ b/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/service/impl/JeecgDemoServiceImpl.java @@ -8,6 +8,7 @@ import org.apache.shiro.SecurityUtils; import org.jeecg.common.constant.CacheConstant; import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.system.vo.LoginUser; +import org.jeecg.config.security.utils.SecureUtil; import org.jeecg.modules.demo.test.entity.JeecgDemo; import org.jeecg.modules.demo.test.mapper.JeecgDemoMapper; import org.jeecg.modules.demo.test.service.IJeecgDemoService; @@ -83,7 +84,7 @@ public class JeecgDemoServiceImpl extends ServiceImpl noAuthList = new ArrayList<>(); diff --git a/jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/fallback/SysBaseAPIFallback.java b/jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/fallback/SysBaseAPIFallback.java index e47caef74..55a331ea0 100644 --- a/jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/fallback/SysBaseAPIFallback.java +++ b/jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/fallback/SysBaseAPIFallback.java @@ -447,4 +447,9 @@ public class SysBaseAPIFallback implements ISysBaseAPI { public void updateUserDepart(String username, String orgCode, Integer loginTenantId) { } + + @Override + public LoginUser getUserByPhone(String phone) { + return null; + } } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/aop/TenantPackUserLogAspect.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/aop/TenantPackUserLogAspect.java index 4014cec9c..63112b67b 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/aop/TenantPackUserLogAspect.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/aop/TenantPackUserLogAspect.java @@ -1,7 +1,6 @@ package org.jeecg.modules.aop; import com.alibaba.fastjson.JSON; -import org.apache.shiro.SecurityUtils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; @@ -10,6 +9,7 @@ import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.jeecg.common.api.dto.LogDTO; import org.jeecg.common.system.vo.LoginUser; +import org.jeecg.config.security.utils.SecureUtil; import org.jeecg.modules.base.service.BaseCommonService; import org.jeecg.modules.system.entity.SysTenantPack; import org.jeecg.modules.system.entity.SysTenantPackUser; @@ -80,7 +80,7 @@ public class TenantPackUserLogAspect { dto.setOperateType(opType); dto.setTenantId(tenantId); //获取登录用户信息 - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); if(sysUser!=null){ dto.setUserid(sysUser.getUsername()); dto.setUsername(sysUser.getRealname()); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/oss/controller/OssFileController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/oss/controller/OssFileController.java index 21eeb3ee0..6f40f0167 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/oss/controller/OssFileController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/oss/controller/OssFileController.java @@ -9,6 +9,7 @@ import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.modules.oss.entity.OssFile; import org.jeecg.modules.oss.service.IOssFileService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -48,7 +49,7 @@ public class OssFileController { @ResponseBody @PostMapping("/upload") //@RequiresRoles("admin") - @RequiresPermissions("system:ossFile:upload") + @PreAuthorize("@jps.requiresPermissions('system:ossFile:upload')") public Result upload(@RequestParam("file") MultipartFile multipartFile) { Result result = new Result(); try { diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/quartz/controller/QuartzJobController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/quartz/controller/QuartzJobController.java index 71dbcb393..905cae48f 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/quartz/controller/QuartzJobController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/quartz/controller/QuartzJobController.java @@ -16,6 +16,7 @@ import org.jeecg.common.constant.SymbolConstant; import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.ImportExcelUtil; +import org.jeecg.config.security.utils.SecureUtil; import org.jeecg.modules.quartz.entity.QuartzJob; import org.jeecg.modules.quartz.service.IQuartzJobService; import org.jeecgframework.poi.excel.ExcelImportUtil; @@ -26,6 +27,7 @@ import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -82,7 +84,7 @@ public class QuartzJobController { * @return */ //@RequiresRoles("admin") - @RequiresPermissions("system:quartzJob:add") + @PreAuthorize("@jps.requiresPermissions('system:quartzJob:add')") @RequestMapping(value = "/add", method = RequestMethod.POST) public Result add(@RequestBody QuartzJob quartzJob) { quartzJobService.saveAndScheduleJob(quartzJob); @@ -96,7 +98,7 @@ public class QuartzJobController { * @return */ //@RequiresRoles("admin") - @RequiresPermissions("system:quartzJob:edit") + @PreAuthorize("@jps.requiresPermissions('system:quartzJob:edit')") @RequestMapping(value = "/edit", method ={RequestMethod.PUT, RequestMethod.POST}) public Result eidt(@RequestBody QuartzJob quartzJob) { try { @@ -115,7 +117,7 @@ public class QuartzJobController { * @return */ //@RequiresRoles("admin") - @RequiresPermissions("system:quartzJob:delete") + @PreAuthorize("@jps.requiresPermissions('system:quartzJob:delete')") @RequestMapping(value = "/delete", method = RequestMethod.DELETE) public Result delete(@RequestParam(name = "id", required = true) String id) { QuartzJob quartzJob = quartzJobService.getById(id); @@ -134,7 +136,7 @@ public class QuartzJobController { * @return */ //@RequiresRoles("admin") - @RequiresPermissions("system:quartzJob:deleteBatch") + @PreAuthorize("@jps.requiresPermissions('system:quartzJob:deleteBatch')") @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE) public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) { if (ids == null || "".equals(ids.trim())) { @@ -154,7 +156,7 @@ public class QuartzJobController { * @return */ //@RequiresRoles("admin") - @RequiresPermissions("system:quartzJob:pause") + @PreAuthorize("@jps.requiresPermissions('system:quartzJob:pause')") @GetMapping(value = "/pause") @Operation(summary = "停止定时任务") public Result pauseJob(@RequestParam(name = "id") String id) { @@ -173,7 +175,7 @@ public class QuartzJobController { * @return */ //@RequiresRoles("admin") - @RequiresPermissions("system:quartzJob:resume") + @PreAuthorize("@jps.requiresPermissions('system:quartzJob:resume')") @GetMapping(value = "/resume") @Operation(summary = "启动定时任务") public Result resumeJob(@RequestParam(name = "id") String id) { @@ -216,7 +218,7 @@ public class QuartzJobController { mv.addObject(NormalExcelConstants.CLASS, QuartzJob.class); //获取当前登录用户 //update-begin---author:wangshuai ---date:20211227 for:[JTC-116]导出人写死了------------ - LoginUser user = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser user = SecureUtil.currentUser(); mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("定时任务列表数据", "导出人:"+user.getRealname(), "导出信息")); //update-end---author:wangshuai ---date:20211227 for:[JTC-116]导出人写死了------------ mv.addObject(NormalExcelConstants.DATA_LIST, pageList); @@ -274,7 +276,7 @@ public class QuartzJobController { * @return */ //@RequiresRoles("admin") - @RequiresPermissions("system:quartzJob:execute") + @PreAuthorize("@jps.requiresPermissions('system:quartzJob:execute')") @GetMapping("/execute") public Result execute(@RequestParam(name = "id", required = true) String id) { QuartzJob quartzJob = quartzJobService.getById(id); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/LoginController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/LoginController.java index 97942517d..96651be12 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/LoginController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/LoginController.java @@ -1,6 +1,7 @@ package org.jeecg.modules.system.controller; import cn.hutool.core.util.RandomUtil; +import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.aliyuncs.exceptions.ClientException; @@ -21,10 +22,10 @@ import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.*; import org.jeecg.common.util.encryption.EncryptedString; import org.jeecg.config.JeecgBaseConfig; +import org.jeecg.config.security.utils.SecureUtil; import org.jeecg.modules.base.service.BaseCommonService; import org.jeecg.modules.system.entity.SysDepart; import org.jeecg.modules.system.entity.SysRoleIndex; -import org.jeecg.modules.system.entity.SysTenant; import org.jeecg.modules.system.entity.SysUser; import org.jeecg.modules.system.model.SysLoginModel; import org.jeecg.modules.system.service.*; @@ -32,15 +33,23 @@ import org.jeecg.modules.system.service.impl.SysBaseApiImpl; import org.jeecg.modules.system.util.RandImageUtil; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.CacheManager; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.authentication.event.LogoutSuccessEvent; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.core.OAuth2AccessToken; +import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; +import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; +import org.springframework.security.oauth2.server.authorization.OAuth2TokenType; +import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; import org.springframework.web.bind.annotation.*; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.util.*; -import java.util.stream.Collectors; /** * @Author scott @@ -69,9 +78,19 @@ public class LoginController { private BaseCommonService baseCommonService; @Autowired private JeecgBaseConfig jeecgBaseConfig; + @Autowired + private OAuth2AuthorizationService authorizationService; + @Autowired + private CacheManager cacheManager; private final String BASE_CHECK_CODES = "qwertyuiplkjhgfdsazxcvbnmQWERTYUPLKJHGFDSAZXCVBNM1234567890"; + /** + * 使用spring authorization server提供的各类登录接口 + * @param sysLoginModel + * @return + */ + @Deprecated @Operation(summary = "登录接口") @RequestMapping(value = "/login", method = RequestMethod.POST) public Result login(@RequestBody SysLoginModel sysLoginModel){ @@ -209,7 +228,15 @@ public class LoginController { //清空用户的缓存信息(包括部门信息),例如sys:cache:user:: redisUtil.del(String.format("%s::%s", CacheConstant.SYS_USERS_CACHE, sysUser.getUsername())); //调用shiro的logout - SecurityUtils.getSubject().logout(); +// SecurityUtils.getSubject().logout(); + + OAuth2Authorization authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN); + + // 清空用户信息 + cacheManager.getCache("user_details").evict(authorization.getPrincipalName()); + // 清空access token + authorizationService.remove(authorization); + return Result.ok("退出登录成功!"); }else { return Result.error("Token无效!"); @@ -279,7 +306,7 @@ public class LoginController { Result result = new Result(); String username = user.getUsername(); if(oConvertUtils.isEmpty(username)) { - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); username = sysUser.getUsername(); } @@ -542,7 +569,7 @@ public class LoginController { /** * 切换菜单表为vue3的表 */ - @RequiresRoles({"admin"}) + @PreAuthorize("@jps.requiresRoles('admin')") @GetMapping(value = "/switchVue3Menu") public Result switchVue3Menu(HttpServletResponse response) { Result res = new Result(); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementController.java index 288a0998c..3280d9708 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementController.java @@ -24,6 +24,7 @@ import org.jeecg.common.util.RedisUtil; import org.jeecg.common.util.TokenUtils; import org.jeecg.common.util.oConvertUtils; import org.jeecg.config.mybatis.MybatisPlusSaasConfig; +import org.jeecg.config.security.utils.SecureUtil; import org.jeecg.modules.message.enums.RangeDateEnum; import org.jeecg.modules.message.websocket.WebSocket; import org.jeecg.modules.system.entity.SysAnnouncement; @@ -337,7 +338,7 @@ public class SysAnnouncementController { public Result> listByUser(@RequestParam(required = false, defaultValue = "5") Integer pageSize) { Result> result = new Result>(); Map sysMsgMap = new HashMap(5); - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); String userId = sysUser.getId(); // //补推送数据(用户和通知的关系表) @@ -380,7 +381,7 @@ public class SysAnnouncementController { //导出文件名称 mv.addObject(NormalExcelConstants.FILE_NAME, "系统通告列表"); mv.addObject(NormalExcelConstants.CLASS, SysAnnouncement.class); - LoginUser user = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser user = SecureUtil.currentUser(); mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("系统通告列表数据", "导出人:"+user.getRealname(), "导出信息")); mv.addObject(NormalExcelConstants.DATA_LIST, pageList); return mv; @@ -548,7 +549,7 @@ public class SysAnnouncementController { JSONObject obj = new JSONObject(); obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER); - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); webSocket.sendMessage(sysUser.getId(), obj.toJSONString()); // 4、性能统计耗时 diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementSendController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementSendController.java index 659d2ec35..d935a26cf 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementSendController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementSendController.java @@ -14,6 +14,7 @@ import org.jeecg.common.constant.WebsocketConst; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.SqlInjectionUtil; import org.jeecg.common.util.oConvertUtils; +import org.jeecg.config.security.utils.SecureUtil; import org.jeecg.modules.message.websocket.WebSocket; import org.jeecg.modules.system.entity.SysAnnouncementSend; import org.jeecg.modules.system.model.AnnouncementSendModel; @@ -196,7 +197,7 @@ public class SysAnnouncementSendController { public Result editById(@RequestBody JSONObject json) { Result result = new Result(); String anntId = json.getString("anntId"); - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); String userId = sysUser.getId(); LambdaUpdateWrapper updateWrapper = new UpdateWrapper().lambda(); updateWrapper.set(SysAnnouncementSend::getReadFlag, CommonConstant.HAS_READ_FLAG); @@ -221,7 +222,7 @@ public class SysAnnouncementSendController { @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, @RequestParam(name="pageSize", defaultValue="10") Integer pageSize) { Result> result = new Result>(); - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); String userId = sysUser.getId(); announcementSendModel.setUserId(userId); announcementSendModel.setPageNo((pageNo-1)*pageSize); @@ -240,7 +241,7 @@ public class SysAnnouncementSendController { @PutMapping(value = "/readAll") public Result readAll() { Result result = new Result(); - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); String userId = sysUser.getId(); LambdaUpdateWrapper updateWrapper = new UpdateWrapper().lambda(); updateWrapper.set(SysAnnouncementSend::getReadFlag, CommonConstant.HAS_READ_FLAG); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysCategoryController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysCategoryController.java index 773f9116d..76c48c479 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysCategoryController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysCategoryController.java @@ -18,6 +18,7 @@ import org.jeecg.common.util.ImportExcelUtil; import org.jeecg.common.util.ReflectHelper; import org.jeecg.common.util.oConvertUtils; import org.jeecg.config.mybatis.MybatisPlusSaasConfig; +import org.jeecg.config.security.utils.SecureUtil; import org.jeecg.modules.system.entity.SysCategory; import org.jeecg.modules.system.model.TreeSelectModel; import org.jeecg.modules.system.service.ISysCategoryService; @@ -238,7 +239,7 @@ public class SysCategoryController { //导出文件名称 mv.addObject(NormalExcelConstants.FILE_NAME, "分类字典列表"); mv.addObject(NormalExcelConstants.CLASS, SysCategory.class); - LoginUser user = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser user = SecureUtil.currentUser(); mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("分类字典列表数据", "导出人:"+user.getRealname(), "导出信息")); return mv; } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysCommentController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysCommentController.java index f3169d9a6..1880bc484 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysCommentController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysCommentController.java @@ -7,7 +7,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; -import org.apache.shiro.SecurityUtils; import org.jeecg.common.api.dto.DataLogDTO; import org.jeecg.common.api.vo.Result; import org.jeecg.common.constant.CommonConstant; @@ -15,6 +14,7 @@ import org.jeecg.common.system.api.ISysBaseAPI; import org.jeecg.common.system.base.controller.JeecgController; import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.system.vo.LoginUser; +import org.jeecg.config.security.utils.SecureUtil; import org.jeecg.modules.system.entity.SysComment; import org.jeecg.modules.system.service.ISysCommentService; import org.jeecg.modules.system.vo.SysCommentFileVo; @@ -128,7 +128,7 @@ public class SysCommentController extends JeecgController queryPageList( SysDataSource sysDataSource, diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDepartController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDepartController.java index 55182a339..9a293e1c1 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDepartController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDepartController.java @@ -19,6 +19,7 @@ import org.jeecg.common.util.ImportExcelUtil; import org.jeecg.common.util.YouBianCodeUtil; import org.jeecg.common.util.oConvertUtils; import org.jeecg.config.mybatis.MybatisPlusSaasConfig; +import org.jeecg.config.security.utils.SecureUtil; import org.jeecg.modules.system.entity.SysDepart; import org.jeecg.modules.system.entity.SysUser; import org.jeecg.modules.system.model.DepartIdModel; @@ -35,6 +36,7 @@ import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -74,7 +76,7 @@ public class SysDepartController { @RequestMapping(value = "/queryMyDeptTreeList", method = RequestMethod.GET) public Result> queryMyDeptTreeList() { Result> result = new Result<>(); - LoginUser user = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser user = SecureUtil.currentUser(); try { if(oConvertUtils.isNotEmpty(user.getUserIdentity()) && user.getUserIdentity().equals( CommonConstant.USER_IDENTITY_2 )){ //update-begin--Author:liusq Date:20210624 for:部门查询ids为空后的前端显示问题 issues/I3UD06 @@ -178,7 +180,7 @@ public class SysDepartController { * @param sysDepart * @return */ - @RequiresPermissions("system:depart:add") + @PreAuthorize("@jps.requiresPermissions('system:depart:add')") @RequestMapping(value = "/add", method = RequestMethod.POST) @CacheEvict(value= {CacheConstant.SYS_DEPARTS_CACHE,CacheConstant.SYS_DEPART_IDS_CACHE}, allEntries=true) public Result add(@RequestBody SysDepart sysDepart, HttpServletRequest request) { @@ -204,7 +206,7 @@ public class SysDepartController { * @param sysDepart * @return */ - @RequiresPermissions("system:depart:edit") + @PreAuthorize("@jps.requiresPermissions('system:depart:edit')") @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) @CacheEvict(value= {CacheConstant.SYS_DEPARTS_CACHE,CacheConstant.SYS_DEPART_IDS_CACHE}, allEntries=true) public Result edit(@RequestBody SysDepart sysDepart, HttpServletRequest request) { @@ -232,7 +234,7 @@ public class SysDepartController { * @param id * @return */ - @RequiresPermissions("system:depart:delete") + @PreAuthorize("@jps.requiresPermissions('system:depart:delete')") @RequestMapping(value = "/delete", method = RequestMethod.DELETE) @CacheEvict(value= {CacheConstant.SYS_DEPARTS_CACHE,CacheConstant.SYS_DEPART_IDS_CACHE}, allEntries=true) public Result delete(@RequestParam(name="id",required=true) String id) { @@ -258,7 +260,7 @@ public class SysDepartController { * @param ids * @return */ - @RequiresPermissions("system:depart:deleteBatch") + @PreAuthorize("@jps.requiresPermissions('system:depart:deleteBatch')") @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE) @CacheEvict(value= {CacheConstant.SYS_DEPARTS_CACHE,CacheConstant.SYS_DEPART_IDS_CACHE}, allEntries=true) public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) { @@ -322,7 +324,7 @@ public class SysDepartController { public Result> searchBy(@RequestParam(name = "keyWord", required = true) String keyWord,@RequestParam(name = "myDeptSearch", required = false) String myDeptSearch) { Result> result = new Result>(); //部门查询,myDeptSearch为1时为我的部门查询,登录用户为上级时查只查负责部门下数据 - LoginUser user = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser user = SecureUtil.currentUser(); String departIds = null; if(oConvertUtils.isNotEmpty(user.getUserIdentity()) && user.getUserIdentity().equals( CommonConstant.USER_IDENTITY_2 )){ departIds = user.getDepartIds(); @@ -382,7 +384,7 @@ public class SysDepartController { * @param response * @return */ - @RequiresPermissions("system:depart:importExcel") + @PreAuthorize("@jps.requiresPermissions('system:depart:importExcel')") @RequestMapping(value = "/importExcel", method = RequestMethod.POST) @CacheEvict(value= {CacheConstant.SYS_DEPARTS_CACHE,CacheConstant.SYS_DEPART_IDS_CACHE}, allEntries=true) public Result importExcel(HttpServletRequest request, HttpServletResponse response) { diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDepartPermissionController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDepartPermissionController.java index 8042220b0..9dbe427fe 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDepartPermissionController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDepartPermissionController.java @@ -11,13 +11,13 @@ import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; -import org.apache.shiro.SecurityUtils; import org.jeecg.common.api.vo.Result; import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.system.base.controller.JeecgController; import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.oConvertUtils; +import org.jeecg.config.security.utils.SecureUtil; import org.jeecg.modules.base.service.BaseCommonService; import org.jeecg.modules.system.entity.SysDepartPermission; import org.jeecg.modules.system.entity.SysDepartRolePermission; @@ -260,7 +260,7 @@ public class SysDepartPermissionController extends JeecgController queryWrapper = QueryGenerator.initQueryWrapper(sysDepartRole, req.getParameterMap()); Page page = new Page(pageNo, pageSize); - LoginUser user = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser user = SecureUtil.currentUser(); List deptIds = null; // if(oConvertUtils.isEmpty(deptId)){ // if(oConvertUtils.isNotEmpty(user.getUserIdentity()) && user.getUserIdentity().equals(CommonConstant.USER_IDENTITY_2) ){ @@ -107,7 +106,7 @@ public class SysDepartRoleController extends JeecgController add(@RequestBody SysDepartRole sysDepartRole) { @@ -122,7 +121,7 @@ public class SysDepartRoleController extends JeecgController edit(@RequestBody SysDepartRole sysDepartRole) { sysDepartRoleService.updateById(sysDepartRole); @@ -137,7 +136,7 @@ public class SysDepartRoleController extends JeecgController delete(@RequestParam(name="id",required=true) String id) { sysDepartRoleService.removeById(id); @@ -152,7 +151,7 @@ public class SysDepartRoleController extends JeecgController deleteBatch(@RequestParam(name="ids",required=true) String ids) { this.sysDepartRoleService.removeByIds(Arrays.asList(ids.split(","))); @@ -192,7 +191,7 @@ public class SysDepartRoleController extends JeecgController deptRoleAdd(@RequestBody JSONObject json) { String newRoleId = json.getString("newRoleId"); @@ -200,7 +199,7 @@ public class SysDepartRoleController extends JeecgController add(@RequestBody SysDict sysDict) { Result result = new Result(); @@ -386,7 +388,7 @@ public class SysDictController { * @param sysDict * @return */ - @RequiresPermissions("system:dict:edit") + @PreAuthorize("@jps.requiresPermissions('system:dict:edit')") @RequestMapping(value = "/edit", method = { RequestMethod.PUT,RequestMethod.POST }) public Result edit(@RequestBody SysDict sysDict) { Result result = new Result(); @@ -408,7 +410,7 @@ public class SysDictController { * @param id * @return */ - @RequiresPermissions("system:dict:delete") + @PreAuthorize("@jps.requiresPermissions('system:dict:delete')") @RequestMapping(value = "/delete", method = RequestMethod.DELETE) @CacheEvict(value={CacheConstant.SYS_DICT_CACHE, CacheConstant.SYS_ENABLE_DICT_CACHE}, allEntries=true) public Result delete(@RequestParam(name="id",required=true) String id) { @@ -427,7 +429,7 @@ public class SysDictController { * @param ids * @return */ - @RequiresPermissions("system:dict:deleteBatch") + @PreAuthorize("@jps.requiresPermissions('system:dict:deleteBatch')") @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE) @CacheEvict(value= {CacheConstant.SYS_DICT_CACHE, CacheConstant.SYS_ENABLE_DICT_CACHE}, allEntries=true) public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { @@ -514,7 +516,7 @@ public class SysDictController { // 注解对象Class mv.addObject(NormalExcelConstants.CLASS, SysDictPage.class); // 自定义表格参数 - LoginUser user = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser user = SecureUtil.currentUser(); mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("数据字典列表", "导出人:"+user.getRealname(), "数据字典")); // 导出数据列表 mv.addObject(NormalExcelConstants.DATA_LIST, pageList); @@ -528,7 +530,7 @@ public class SysDictController { * @param * @return */ - @RequiresPermissions("system:dict:importExcel") + @PreAuthorize("@jps.requiresPermissions('system:dict:importExcel')") @RequestMapping(value = "/importExcel", method = RequestMethod.POST) public Result importExcel(HttpServletRequest request, HttpServletResponse response) { MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDictItemController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDictItemController.java index a7cb0ff6a..d3d33ead1 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDictItemController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDictItemController.java @@ -20,6 +20,7 @@ import org.jeecg.modules.system.entity.SysDictItem; import org.jeecg.modules.system.service.ISysDictItemService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -74,7 +75,7 @@ public class SysDictItemController { * @功能:新增 * @return */ - @RequiresPermissions("system:dict:item:add") + @PreAuthorize("@jps.requiresPermissions('system:dict:item:add')") @RequestMapping(value = "/add", method = RequestMethod.POST) @CacheEvict(value= {CacheConstant.SYS_DICT_CACHE, CacheConstant.SYS_ENABLE_DICT_CACHE}, allEntries=true) public Result add(@RequestBody SysDictItem sysDictItem) { @@ -95,7 +96,7 @@ public class SysDictItemController { * @param sysDictItem * @return */ - @RequiresPermissions("system:dict:item:edit") + @PreAuthorize("@jps.requiresPermissions('system:dict:item:edit')") @RequestMapping(value = "/edit", method = { RequestMethod.PUT,RequestMethod.POST }) @CacheEvict(value={CacheConstant.SYS_DICT_CACHE, CacheConstant.SYS_ENABLE_DICT_CACHE}, allEntries=true) public Result edit(@RequestBody SysDictItem sysDictItem) { @@ -119,7 +120,7 @@ public class SysDictItemController { * @param id * @return */ - @RequiresPermissions("system:dict:item:delete") + @PreAuthorize("@jps.requiresPermissions('system:dict:item:delete')") @RequestMapping(value = "/delete", method = RequestMethod.DELETE) @CacheEvict(value={CacheConstant.SYS_DICT_CACHE, CacheConstant.SYS_ENABLE_DICT_CACHE}, allEntries=true) public Result delete(@RequestParam(name="id",required=true) String id) { @@ -141,7 +142,7 @@ public class SysDictItemController { * @param ids * @return */ - @RequiresPermissions("system:dict:item:deleteBatch") + @PreAuthorize("@jps.requiresPermissions('system:dict:item:deleteBatch')") @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE) @CacheEvict(value={CacheConstant.SYS_DICT_CACHE, CacheConstant.SYS_ENABLE_DICT_CACHE}, allEntries=true) public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysGatewayRouteController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysGatewayRouteController.java index 945b09c8c..be7ce33cc 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysGatewayRouteController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysGatewayRouteController.java @@ -12,6 +12,7 @@ import org.jeecg.common.util.oConvertUtils; import org.jeecg.modules.system.entity.SysGatewayRoute; import org.jeecg.modules.system.service.ISysGatewayRouteService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import java.util.List; @@ -67,7 +68,7 @@ public class SysGatewayRouteController extends JeecgController delete(@RequestParam(name = "id", required = true) String id) { sysGatewayRouteService.deleteById(id); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysPermissionController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysPermissionController.java index 44a0df4e3..2c39345c6 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysPermissionController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysPermissionController.java @@ -7,7 +7,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; -import org.apache.shiro.SecurityUtils; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.jeecg.common.api.vo.Result; import org.jeecg.common.constant.CommonConstant; @@ -17,6 +16,7 @@ import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.Md5Util; import org.jeecg.common.util.oConvertUtils; import org.jeecg.config.JeecgBaseConfig; +import org.jeecg.config.security.utils.SecureUtil; import org.jeecg.modules.base.service.BaseCommonService; import org.jeecg.modules.system.entity.*; import org.jeecg.modules.system.model.SysPermissionTree; @@ -24,6 +24,7 @@ import org.jeecg.modules.system.model.TreeModel; import org.jeecg.modules.system.service.*; import org.jeecg.modules.system.util.PermissionDataUtil; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; @@ -241,7 +242,7 @@ public class SysPermissionController { Result result = new Result(); try { //直接获取当前用户不适用前端token - LoginUser loginUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class); + LoginUser loginUser = SecureUtil.currentUser(); if (oConvertUtils.isEmpty(loginUser)) { return Result.error("请登录系统!"); } @@ -319,7 +320,7 @@ public class SysPermissionController { public Result getPermCode() { try { // 直接获取当前用户 - LoginUser loginUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser loginUser = SecureUtil.currentUser(); if (oConvertUtils.isEmpty(loginUser)) { return Result.error("请登录系统!"); } @@ -360,7 +361,7 @@ public class SysPermissionController { * @param permission * @return */ - @RequiresPermissions("system:permission:add") + @PreAuthorize("@jps.requiresPermissions('system:permission:add')") @RequestMapping(value = "/add", method = RequestMethod.POST) public Result add(@RequestBody SysPermission permission) { Result result = new Result(); @@ -380,7 +381,7 @@ public class SysPermissionController { * @param permission * @return */ - @RequiresPermissions("system:permission:edit") + @PreAuthorize("@jps.requiresPermissions('system:permission:edit')") @RequestMapping(value = "/edit", method = { RequestMethod.PUT, RequestMethod.POST }) public Result edit(@RequestBody SysPermission permission) { Result result = new Result<>(); @@ -422,7 +423,7 @@ public class SysPermissionController { * @param id * @return */ - @RequiresPermissions("system:permission:delete") + @PreAuthorize("@jps.requiresPermissions('system:permission:delete')") @RequestMapping(value = "/delete", method = RequestMethod.DELETE) public Result delete(@RequestParam(name = "id", required = true) String id) { Result result = new Result<>(); @@ -441,7 +442,7 @@ public class SysPermissionController { * @param ids * @return */ - @RequiresPermissions("system:permission:deleteBatch") + @PreAuthorize("@jps.requiresPermissions('system:permission:deleteBatch')") @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE) public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) { Result result = new Result<>(); @@ -549,7 +550,7 @@ public class SysPermissionController { * @return */ @RequestMapping(value = "/saveRolePermission", method = RequestMethod.POST) - @RequiresPermissions("system:permission:saveRole") + @PreAuthorize("@jps.requiresPermissions('system:permission:saveRole')") public Result saveRolePermission(@RequestBody JSONObject json) { long start = System.currentTimeMillis(); Result result = new Result<>(); @@ -559,7 +560,7 @@ public class SysPermissionController { String lastPermissionIds = json.getString("lastpermissionIds"); this.sysRolePermissionService.saveRolePermission(roleId, permissionIds, lastPermissionIds); //update-begin---author:wangshuai ---date:20220316 for:[VUEN-234]用户管理角色授权添加敏感日志------------ - LoginUser loginUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser loginUser = SecureUtil.currentUser(); baseCommonService.addLog("修改角色ID: "+roleId+" 的权限配置,操作人: " +loginUser.getUsername() ,CommonConstant.LOG_TYPE_2, 2); //update-end---author:wangshuai ---date:20220316 for:[VUEN-234]用户管理角色授权添加敏感日志------------ result.success("保存成功!"); @@ -877,7 +878,7 @@ public class SysPermissionController { * @param sysPermissionDataRule * @return */ - @RequiresPermissions("system:permission:addRule") + @PreAuthorize("@jps.requiresPermissions('system:permission:addRule')") @RequestMapping(value = "/addPermissionRule", method = RequestMethod.POST) public Result addPermissionRule(@RequestBody SysPermissionDataRule sysPermissionDataRule) { Result result = new Result(); @@ -892,7 +893,7 @@ public class SysPermissionController { return result; } - @RequiresPermissions("system:permission:editRule") + @PreAuthorize("@jps.requiresPermissions('system:permission:editRule')") @RequestMapping(value = "/editPermissionRule", method = { RequestMethod.PUT, RequestMethod.POST }) public Result editPermissionRule(@RequestBody SysPermissionDataRule sysPermissionDataRule) { Result result = new Result(); @@ -912,7 +913,7 @@ public class SysPermissionController { * @param id * @return */ - @RequiresPermissions("system:permission:deleteRule") + @PreAuthorize("@jps.requiresPermissions('system:permission:deleteRule')") @RequestMapping(value = "/deletePermissionRule", method = RequestMethod.DELETE) public Result deletePermissionRule(@RequestParam(name = "id", required = true) String id) { Result result = new Result(); @@ -969,7 +970,7 @@ public class SysPermissionController { * @return */ @RequestMapping(value = "/saveDepartPermission", method = RequestMethod.POST) - @RequiresPermissions("system:permission:saveDepart") + @PreAuthorize("@jps.requiresPermissions('system:permission:saveDepart')") public Result saveDepartPermission(@RequestBody JSONObject json) { long start = System.currentTimeMillis(); Result result = new Result<>(); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysPositionController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysPositionController.java index 8364fdcfb..e75ce6832 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysPositionController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysPositionController.java @@ -18,6 +18,7 @@ import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.ImportExcelUtil; import org.jeecg.common.util.oConvertUtils; import org.jeecg.config.mybatis.MybatisPlusSaasConfig; +import org.jeecg.config.security.utils.SecureUtil; import org.jeecg.modules.system.entity.SysPosition; import org.jeecg.modules.system.entity.SysUser; import org.jeecg.modules.system.service.ISysPositionService; @@ -243,7 +244,7 @@ public class SysPositionController { //Step.2 AutoPoi 导出Excel ModelAndView mv = new ModelAndView(new JeecgEntityExcelView()); List pageList = sysPositionService.list(queryWrapper); - LoginUser user = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser user = SecureUtil.currentUser(); //导出文件名称 mv.addObject(NormalExcelConstants.FILE_NAME, "职务表列表"); mv.addObject(NormalExcelConstants.CLASS, SysPosition.class); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysRoleController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysRoleController.java index dcd373c9a..25baeb5c1 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysRoleController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysRoleController.java @@ -1,10 +1,8 @@ package org.jeecg.modules.system.controller; -import java.io.File; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -24,6 +22,7 @@ import org.jeecg.common.constant.SymbolConstant; import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.util.oConvertUtils; import org.jeecg.config.mybatis.MybatisPlusSaasConfig; +import org.jeecg.config.security.utils.SecureUtil; import org.jeecg.modules.base.service.BaseCommonService; import org.jeecg.modules.system.entity.*; import org.jeecg.modules.system.model.TreeModel; @@ -35,6 +34,7 @@ import org.jeecgframework.poi.excel.entity.ImportParams; import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -94,7 +94,7 @@ public class SysRoleController { * @param req * @return */ - @RequiresPermissions("system:role:list") + @PreAuthorize("@jps.requiresPermissions('system:role:list')") @RequestMapping(value = "/list", method = RequestMethod.GET) public Result> queryPageList(SysRole role, @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, @@ -143,7 +143,7 @@ public class SysRoleController { * @return */ @RequestMapping(value = "/add", method = RequestMethod.POST) - @RequiresPermissions("system:role:add") + @PreAuthorize("@jps.requiresPermissions('system:role:add')") public Result add(@RequestBody SysRole role) { Result result = new Result(); try { @@ -166,7 +166,7 @@ public class SysRoleController { * @param role * @return */ - @RequiresPermissions("system:role:edit") + @PreAuthorize("@jps.requiresPermissions('system:role:edit')") @RequestMapping(value = "/edit",method = {RequestMethod.PUT,RequestMethod.POST}) public Result edit(@RequestBody SysRole role) { Result result = new Result(); @@ -180,7 +180,7 @@ public class SysRoleController { //如果是saas隔离的情况下,判断当前租户id是否是当前租户下的 if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) { //获取当前用户 - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); Integer tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0); String username = "admin"; if (!tenantId.equals(role.getTenantId()) && !username.equals(sysUser.getUsername())) { @@ -203,13 +203,13 @@ public class SysRoleController { * @param id * @return */ - @RequiresPermissions("system:role:delete") + @PreAuthorize("@jps.requiresPermissions('system:role:delete')") @RequestMapping(value = "/delete", method = RequestMethod.DELETE) public Result delete(@RequestParam(name="id",required=true) String id) { //如果是saas隔离的情况下,判断当前租户id是否是当前租户下的 if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){ //获取当前用户 - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); int tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0); Long getRoleCount = sysRoleService.getRoleCountByTenantId(id, tenantId); String username = "admin"; @@ -227,7 +227,7 @@ public class SysRoleController { * @param ids * @return */ - @RequiresPermissions("system:role:deleteBatch") + @PreAuthorize("@jps.requiresPermissions('system:role:deleteBatch')") @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE) public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { baseCommonService.addLog("删除角色操作,角色ids:" + ids, CommonConstant.LOG_TYPE_2, CommonConstant.OPERATE_TYPE_4); @@ -304,7 +304,7 @@ public class SysRoleController { * * @return */ - @RequiresPermissions("system:role:queryallNoByTenant") + @PreAuthorize("@jps.requiresPermissions('system:role:queryallNoByTenant')") @RequestMapping(value = "/queryallNoByTenant", method = RequestMethod.GET) public Result> queryallNoByTenant() { Result> result = new Result<>(); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysRoleIndexController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysRoleIndexController.java index ef3e89ffa..23b2568e5 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysRoleIndexController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysRoleIndexController.java @@ -23,6 +23,7 @@ import lombok.extern.slf4j.Slf4j; import org.jeecg.common.system.base.controller.JeecgController; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; @@ -68,7 +69,7 @@ public class SysRoleIndexController extends JeecgController queryPageList( SysTableWhiteList sysTableWhiteList, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @@ -62,7 +64,7 @@ public class SysTableWhiteListController extends JeecgController add(@RequestBody SysTableWhiteList sysTableWhiteList) { if (sysTableWhiteListService.add(sysTableWhiteList)) { @@ -80,7 +82,7 @@ public class SysTableWhiteListController extends JeecgController edit(@RequestBody SysTableWhiteList sysTableWhiteList) { if (sysTableWhiteListService.edit(sysTableWhiteList)) { @@ -98,7 +100,7 @@ public class SysTableWhiteListController extends JeecgController delete(@RequestParam(name = "id") String id) { if (sysTableWhiteListService.deleteByIds(id)) { @@ -116,7 +118,7 @@ public class SysTableWhiteListController extends JeecgController deleteBatch(@RequestParam(name = "ids") String ids) { if (sysTableWhiteListService.deleteByIds(ids)) { @@ -134,7 +136,7 @@ public class SysTableWhiteListController extends JeecgController queryById(@RequestParam(name = "id", required = true) String id) { SysTableWhiteList sysTableWhiteList = sysTableWhiteListService.getById(id); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysTenantController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysTenantController.java index 4246d0399..7c177241e 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysTenantController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysTenantController.java @@ -8,7 +8,6 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.extern.slf4j.Slf4j; -import org.apache.shiro.SecurityUtils; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.jeecg.common.api.vo.Result; import org.jeecg.common.aspect.annotation.PermissionData; @@ -21,6 +20,7 @@ import org.jeecg.common.util.PasswordUtil; import org.jeecg.common.util.TokenUtils; import org.jeecg.common.util.oConvertUtils; import org.jeecg.config.mybatis.MybatisPlusSaasConfig; +import org.jeecg.config.security.utils.SecureUtil; import org.jeecg.modules.base.service.BaseCommonService; import org.jeecg.modules.system.entity.*; import org.jeecg.modules.system.service.ISysTenantPackService; @@ -34,6 +34,7 @@ import org.jeecg.modules.system.vo.tenant.TenantPackModel; import org.jeecg.modules.system.vo.tenant.TenantPackUser; import org.jeecg.modules.system.vo.tenant.TenantPackUserCount; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; @@ -75,7 +76,7 @@ public class SysTenantController { * @param req * @return */ - @RequiresPermissions("system:tenant:list") + @PreAuthorize("@jps.requiresPermissions('system:tenant:list')") @PermissionData(pageComponent = "system/TenantList") @RequestMapping(value = "/list", method = RequestMethod.GET) public Result> queryPageList(SysTenant sysTenant,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo, @@ -114,7 +115,7 @@ public class SysTenantController { * @return */ @GetMapping("/recycleBinPageList") - @RequiresPermissions("system:tenant:recycleBinPageList") + @PreAuthorize("@jps.requiresPermissions('system:tenant:recycleBinPageList')") public Result> recycleBinPageList(SysTenant sysTenant,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo, @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,HttpServletRequest req){ Result> result = new Result>(); @@ -130,7 +131,7 @@ public class SysTenantController { * @param * @return */ - @RequiresPermissions("system:tenant:add") + @PreAuthorize("@jps.requiresPermissions('system:tenant:add')") @RequestMapping(value = "/add", method = RequestMethod.POST) public Result add(@RequestBody SysTenant sysTenant) { Result result = new Result(); @@ -154,7 +155,7 @@ public class SysTenantController { * @param * @return */ - @RequiresPermissions("system:tenant:edit") + @PreAuthorize("@jps.requiresPermissions('system:tenant:edit')") @RequestMapping(value = "/edit", method ={RequestMethod.PUT, RequestMethod.POST}) public Result edit(@RequestBody SysTenant tenant) { Result result = new Result(); @@ -177,14 +178,14 @@ public class SysTenantController { * @param id * @return */ - @RequiresPermissions("system:tenant:delete") + @PreAuthorize("@jps.requiresPermissions('system:tenant:delete')") @RequestMapping(value = "/delete", method ={RequestMethod.DELETE, RequestMethod.POST}) public Result delete(@RequestParam(name="id",required=true) String id) { //------------------------------------------------------------------ //如果是saas隔离的情况下,判断当前租户id是否是当前租户下的 if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) { //获取当前用户 - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser();; SysTenant sysTenant = sysTenantService.getById(id); String username = "admin"; @@ -205,7 +206,7 @@ public class SysTenantController { * @param ids * @return */ - @RequiresPermissions("system:tenant:deleteBatch") + @PreAuthorize("@jps.requiresPermissions('system:tenant:deleteBatch')") @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE) public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { Result result = new Result<>(); @@ -220,7 +221,7 @@ public class SysTenantController { //如果是saas隔离的情况下,判断当前租户id是否是当前租户下的 if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) { //获取当前用户 - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); SysTenant sysTenant = sysTenantService.getById(id); String username = "admin"; @@ -255,7 +256,7 @@ public class SysTenantController { } //------------------------------------------------------------------------------------------------ //获取登录用户信息 - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); //是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】, admin给特权可以管理所有租户 if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL && !"admin".equals(sysUser.getUsername())){ Integer loginSessionTenant = oConvertUtils.getInt(TenantContext.getTenant()); @@ -280,7 +281,7 @@ public class SysTenantController { * 查询有效的 租户数据 * @return */ - @RequiresPermissions("system:tenant:queryList") + @PreAuthorize("@jps.requiresPermissions('system:tenant:queryList')") @RequestMapping(value = "/queryList", method = RequestMethod.GET) public Result> queryList(@RequestParam(name="ids",required=false) String ids) { Result> result = new Result>(); @@ -306,7 +307,7 @@ public class SysTenantController { * @return */ @GetMapping(value = "/packList") - @RequiresPermissions("system:tenant:packList") + @PreAuthorize("@jps.requiresPermissions('system:tenant:packList')") public Result> queryPackPageList(SysTenantPack sysTenantPack, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, @@ -328,7 +329,7 @@ public class SysTenantController { * @return */ @PostMapping(value = "/addPackPermission") - @RequiresPermissions("system:tenant:add:pack") + @PreAuthorize("@jps.requiresPermissions('system:tenant:add:pack')") public Result addPackPermission(@RequestBody SysTenantPack sysTenantPack) { sysTenantPackService.addPackPermission(sysTenantPack); return Result.ok("创建租户产品包成功"); @@ -341,7 +342,7 @@ public class SysTenantController { * @return */ @PutMapping(value = "/editPackPermission") - @RequiresPermissions("system:tenant:edit:pack") + @PreAuthorize("@jps.requiresPermissions('system:tenant:edit:pack')") public Result editPackPermission(@RequestBody SysTenantPack sysTenantPack) { sysTenantPackService.editPackPermission(sysTenantPack); return Result.ok("修改租户产品包成功"); @@ -354,7 +355,7 @@ public class SysTenantController { * @return */ @DeleteMapping("/deletePackPermissions") - @RequiresPermissions("system:tenant:delete:pack") + @PreAuthorize("@jps.requiresPermissions('system:tenant:delete:pack')") public Result deletePackPermissions(@RequestParam(value = "ids") String ids) { sysTenantPackService.deletePackPermissions(ids); return Result.ok("删除租户产品包成功"); @@ -371,7 +372,7 @@ public class SysTenantController { public Result> getCurrentUserTenant() { Result> result = new Result>(); try { - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); //update-begin---author:wangshuai ---date:20221223 for:[QQYUN-3371]租户逻辑改造,改成关系表------------ List tenantIdList = relationService.getTenantIdsByUserId(sysUser.getId()); Map map = new HashMap(5); @@ -397,7 +398,7 @@ public class SysTenantController { * @return */ @PutMapping("/invitationUserJoin") - @RequiresPermissions("system:tenant:invitation:user") + @PreAuthorize("@jps.requiresPermissions('system:tenant:invitation:user')") public Result invitationUserJoin(@RequestParam("ids") String ids,@RequestParam("phone") String phone){ sysTenantService.invitationUserJoin(ids,phone); return Result.ok("邀请用户成功"); @@ -412,7 +413,7 @@ public class SysTenantController { * @return */ @RequestMapping(value = "/getTenantUserList", method = RequestMethod.GET) - @RequiresPermissions("system:tenant:user:list") + @PreAuthorize("@jps.requiresPermissions('system:tenant:user:list')") public Result> getTenantUserList(SysUser user, @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, @@ -433,12 +434,12 @@ public class SysTenantController { * @return */ @PutMapping("/leaveTenant") - @RequiresPermissions("system:tenant:leave") + @PreAuthorize("@jps.requiresPermissions('system:tenant:leave')") public Result leaveTenant(@RequestParam("userIds") String userIds, @RequestParam("tenantId") String tenantId){ Result result = new Result<>(); //是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】 - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL && !"admin".equals(sysUser.getUsername())){ Integer loginSessionTenant = oConvertUtils.getInt(TenantContext.getTenant()); if(loginSessionTenant!=null && !loginSessionTenant.equals(Integer.valueOf(tenantId))){ @@ -484,7 +485,7 @@ public class SysTenantController { @PostMapping("/saveTenantJoinUser") public Result saveTenantJoinUser(@RequestBody SysTenant sysTenant){ Result result = new Result<>(); - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); Integer tenantId = sysTenantService.saveTenantJoinUser(sysTenant, sysUser.getId()); result.setSuccess(true); result.setMessage("创建成功"); @@ -498,7 +499,7 @@ public class SysTenantController { */ @PostMapping("/joinTenantByHouseNumber") public Result joinTenantByHouseNumber(@RequestBody SysTenant sysTenant){ - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); Integer tenantId = sysTenantService.joinTenantByHouseNumber(sysTenant, sysUser.getId()); Result result = new Result<>(); if(tenantId != 0){ @@ -533,7 +534,7 @@ public class SysTenantController { SysUser user, HttpServletRequest req) { Page page = new Page(pageNo, pageSize); - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); String tenantId = oConvertUtils.getString(TenantContext.getTenant(), "0"); IPage list = relationService.getUserTenantPageList(page, Arrays.asList(userTenantStatus.split(SymbolConstant.COMMA)), user, Integer.valueOf(tenantId)); return Result.ok(list); @@ -548,7 +549,7 @@ public class SysTenantController { @GetMapping("/getTenantListByUserId") //@RequiresPermissions("system:tenant:getTenantListByUserId") public Result> getTenantListByUserId(@RequestParam(name = "userTenantStatus", required = false) String userTenantStatus) { - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); List list = null; if (oConvertUtils.isNotEmpty(userTenantStatus)) { list = Arrays.asList(userTenantStatus.split(SymbolConstant.COMMA)); @@ -581,7 +582,7 @@ public class SysTenantController { @PutMapping("/cancelTenant") //@RequiresPermissions("system:tenant:cancelTenant") public Result cancelTenant(@RequestBody SysTenant sysTenant,HttpServletRequest request) { - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); SysTenant tenant = sysTenantService.getById(sysTenant.getId()); if (null == tenant) { return Result.error("未找到当前租户信息"); @@ -624,7 +625,7 @@ public class SysTenantController { */ @PutMapping("/cancelApplyTenant") public Result cancelApplyTenant(@RequestParam("tenantId") String tenantId){ - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); sysTenantService.leaveTenant(sysUser.getId(),tenantId); return Result.ok("取消申请成功"); } @@ -637,7 +638,7 @@ public class SysTenantController { * @return */ @DeleteMapping("/deleteLogicDeleted") - @RequiresPermissions("system:tenant:deleteTenantLogic") + @PreAuthorize("@jps.requiresPermissions('system:tenant:deleteTenantLogic')") public Result deleteTenantLogic(@RequestParam("ids") String ids){ sysTenantService.deleteTenantLogic(ids); return Result.ok("彻底删除成功"); @@ -649,7 +650,7 @@ public class SysTenantController { * @return */ @PutMapping("/revertTenantLogic") - @RequiresPermissions("system:tenant:revertTenantLogic") + @PreAuthorize("@jps.requiresPermissions('system:tenant:revertTenantLogic')") public Result revertTenantLogic(@RequestParam("ids") String ids){ sysTenantService.revertTenantLogic(ids); return Result.ok("还原成功"); @@ -663,7 +664,7 @@ public class SysTenantController { */ @DeleteMapping("/exitUserTenant") public Result exitUserTenant(@RequestBody SysTenant sysTenant,HttpServletRequest request){ - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); //验证用户是否已存在 Integer count = relationService.userTenantIzExist(sysUser.getId(),sysTenant.getId()); if (count == 0) { @@ -885,7 +886,7 @@ public class SysTenantController { public Result> getTenantPageListByUserId(SysUserTenantVo sysUserTenantVo, @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, @RequestParam(name="pageSize", defaultValue="10") Integer pageSize) { - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); List list = null; String userTenantStatus = sysUserTenantVo.getUserTenantStatus(); if (oConvertUtils.isNotEmpty(userTenantStatus)) { @@ -903,7 +904,7 @@ public class SysTenantController { public Result agreeOrRefuseJoinTenant(@RequestParam("tenantId") Integer tenantId, @RequestParam("status") String status){ //是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】 - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); String userId = sysUser.getId(); SysTenant tenant = sysTenantService.getById(tenantId); if(null == tenant){ diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUserController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUserController.java index bfe6783d4..a0fce83ab 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUserController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUserController.java @@ -7,7 +7,6 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.extern.slf4j.Slf4j; @@ -41,6 +40,7 @@ import org.jeecgframework.poi.excel.entity.ImportParams; import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; @@ -138,7 +138,7 @@ public class SysUserController { * @param req * @return */ - @RequiresPermissions("system:user:listAll") + @PreAuthorize("@jps.requiresPermissions('system:user:listAll')") @RequestMapping(value = "/listAll", method = RequestMethod.GET) public Result> queryAllPageList(SysUser user, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) { @@ -146,7 +146,7 @@ public class SysUserController { return sysUserService.queryPageList(req, queryWrapper, pageSize, pageNo); } - @RequiresPermissions("system:user:add") + @PreAuthorize("@jps.requiresPermissions('system:user:add')") @RequestMapping(value = "/add", method = RequestMethod.POST) public Result add(@RequestBody JSONObject jsonObject) { Result result = new Result(); @@ -176,7 +176,7 @@ public class SysUserController { return result; } - @RequiresPermissions("system:user:edit") + @PreAuthorize("@jps.requiresPermissions('system:user:edit')") @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) public Result edit(@RequestBody JSONObject jsonObject) { Result result = new Result(); @@ -214,7 +214,7 @@ public class SysUserController { /** * 删除用户 */ - @RequiresPermissions("system:user:delete") + @PreAuthorize("@jps.requiresPermissions('system:user:delete')") @RequestMapping(value = "/delete", method = RequestMethod.DELETE) public Result delete(@RequestParam(name="id",required=true) String id) { baseCommonService.addLog("删除用户,id: " +id ,CommonConstant.LOG_TYPE_2, 3); @@ -225,7 +225,7 @@ public class SysUserController { /** * 批量删除用户 */ - @RequiresPermissions("system:user:deleteBatch") + @PreAuthorize("@jps.requiresPermissions('system:user:deleteBatch')") @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE) public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { baseCommonService.addLog("批量删除用户, ids: " +ids ,CommonConstant.LOG_TYPE_2, 3); @@ -238,7 +238,7 @@ public class SysUserController { * @param jsonObject * @return */ - @RequiresPermissions("system:user:frozenBatch") + @PreAuthorize("@jps.requiresPermissions('system:user:frozenBatch')") @RequestMapping(value = "/frozenBatch", method = RequestMethod.PUT) public Result frozenBatch(@RequestBody JSONObject jsonObject) { Result result = new Result(); @@ -262,7 +262,7 @@ public class SysUserController { } - @RequiresPermissions("system:user:queryById") + @PreAuthorize("@jps.requiresPermissions('system:user:queryById')") @RequestMapping(value = "/queryById", method = RequestMethod.GET) public Result queryById(@RequestParam(name = "id", required = true) String id) { Result result = new Result(); @@ -276,7 +276,7 @@ public class SysUserController { return result; } - @RequiresPermissions("system:user:queryUserRole") + @PreAuthorize("@jps.requiresPermissions('system:user:queryUserRole')") @RequestMapping(value = "/queryUserRole", method = RequestMethod.GET) public Result> queryUserRole(@RequestParam(name = "userid", required = true) String userid) { Result> result = new Result<>(); @@ -329,7 +329,7 @@ public class SysUserController { /** * 修改密码 */ - @RequiresPermissions("system:user:changepwd") + @PreAuthorize("@jps.requiresPermissions('system:user:changepwd')") @RequestMapping(value = "/changePassword", method = RequestMethod.PUT) public Result changePassword(@RequestBody SysUser sysUser) { SysUser u = this.sysUserService.getOne(new LambdaQueryWrapper().eq(SysUser::getUsername, sysUser.getUsername())); @@ -452,7 +452,7 @@ public class SysUserController { * @param request * @param sysUser */ - @RequiresPermissions("system:user:export") + @PreAuthorize("@jps.requiresPermissions('system:user:export')") @RequestMapping(value = "/exportXls") public ModelAndView exportXls(SysUser sysUser,HttpServletRequest request) { // Step.1 组装查询条件 @@ -485,7 +485,7 @@ public class SysUserController { * @param response * @return */ - @RequiresPermissions("system:user:import") + @PreAuthorize("@jps.requiresPermissions('system:user:import')") @RequestMapping(value = "/importExcel", method = RequestMethod.POST) public Result importExcel(HttpServletRequest request, HttpServletResponse response)throws IOException { MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; @@ -599,7 +599,7 @@ public class SysUserController { /** * 首页用户重置密码 */ - @RequiresPermissions("system:user:updatepwd") + @PreAuthorize("@jps.requiresPermissions('system:user:updatepwd')") @RequestMapping(value = "/updatePassword", method = RequestMethod.PUT) public Result updatePassword(@RequestBody JSONObject json) { String username = json.getString("username"); @@ -640,7 +640,7 @@ public class SysUserController { * @param * @return */ - @RequiresPermissions("system:user:addUserRole") + @PreAuthorize("@jps.requiresPermissions('system:user:addUserRole')") @RequestMapping(value = "/addSysUserRole", method = RequestMethod.POST) public Result addSysUserRole(@RequestBody SysUserRoleVO sysUserRoleVO) { Result result = new Result(); @@ -672,7 +672,7 @@ public class SysUserController { * @param * @return */ - @RequiresPermissions("system:user:deleteRole") + @PreAuthorize("@jps.requiresPermissions('system:user:deleteRole')") @RequestMapping(value = "/deleteUserRole", method = RequestMethod.DELETE) public Result deleteUserRole(@RequestParam(name="roleId") String roleId, @RequestParam(name="userId",required=true) String userId @@ -696,7 +696,7 @@ public class SysUserController { * @param * @return */ - @RequiresPermissions("system:user:deleteRoleBatch") + @PreAuthorize("@jps.requiresPermissions('system:user:deleteRoleBatch')") @RequestMapping(value = "/deleteUserRoleBatch", method = RequestMethod.DELETE) public Result deleteUserRoleBatch( @RequestParam(name="roleId") String roleId, @@ -827,7 +827,7 @@ public class SysUserController { /** * 给指定部门添加对应的用户 */ - @RequiresPermissions("system:user:editDepartWithUser") + @PreAuthorize("@jps.requiresPermissions('system:user:editDepartWithUser')") @RequestMapping(value = "/editSysDepartWithUser", method = RequestMethod.POST) public Result editSysDepartWithUser(@RequestBody SysDepartUsersVO sysDepartUsersVO) { Result result = new Result(); @@ -856,7 +856,7 @@ public class SysUserController { /** * 删除指定机构的用户关系 */ - @RequiresPermissions("system:user:deleteUserInDepart") + @PreAuthorize("@jps.requiresPermissions('system:user:deleteUserInDepart')") @RequestMapping(value = "/deleteUserInDepart", method = RequestMethod.DELETE) public Result deleteUserInDepart(@RequestParam(name="depId") String depId, @RequestParam(name="userId",required=true) String userId @@ -888,7 +888,7 @@ public class SysUserController { /** * 批量删除指定机构的用户关系 */ - @RequiresPermissions("system:user:deleteUserInDepartBatch") + @PreAuthorize("@jps.requiresPermissions('system:user:deleteUserInDepartBatch')") @RequestMapping(value = "/deleteUserInDepartBatch", method = RequestMethod.DELETE) public Result deleteUserInDepartBatch( @RequestParam(name="depId") String depId, @@ -1263,7 +1263,7 @@ public class SysUserController { * @param userIds 被删除的用户ID,多个id用半角逗号分割 * @return */ - @RequiresPermissions("system:user:deleteRecycleBin") + @PreAuthorize("@jps.requiresPermissions('system:user:deleteRecycleBin')") @RequestMapping(value = "/deleteRecycleBin", method = RequestMethod.DELETE) public Result deleteRecycleBin(@RequestParam("userIds") String userIds) { if (StringUtils.isNotBlank(userIds)) { @@ -1278,7 +1278,7 @@ public class SysUserController { * @param jsonObject * @return */ - @RequiresRoles({"admin"}) + @PreAuthorize("@jps.requiresRoles('admin')") @RequestMapping(value = "/appEdit", method = {RequestMethod.PUT,RequestMethod.POST}) public Result appEdit(HttpServletRequest request,@RequestBody JSONObject jsonObject) { Result result = new Result(); @@ -1668,7 +1668,7 @@ public class SysUserController { * @return */ @PostMapping("/login/setting/userEdit") - @RequiresPermissions("system:user:setting:edit") + @PreAuthorize("@jps.requiresPermissions('system:user:setting:edit')") public Result userEdit(@RequestBody SysUser sysUser, HttpServletRequest request) { String username = JwtUtil.getUserNameByToken(request); SysUser user = sysUserService.getById(sysUser.getId()); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/ThirdAppController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/ThirdAppController.java index 27633fe4c..d7148658e 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/ThirdAppController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/ThirdAppController.java @@ -17,6 +17,7 @@ import org.jeecg.common.system.util.JwtUtil; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.oConvertUtils; import org.jeecg.config.mybatis.MybatisPlusSaasConfig; +import org.jeecg.config.security.utils.SecureUtil; import org.jeecg.modules.system.entity.SysThirdAccount; import org.jeecg.modules.system.entity.SysThirdAppConfig; import org.jeecg.modules.system.service.ISysThirdAccountService; @@ -479,7 +480,7 @@ public class ThirdAppController { */ @GetMapping("/getThirdAccountByUserId") public Result> getThirdAccountByUserId(@RequestParam(name="thirdType") String thirdType){ - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); LambdaQueryWrapper query = new LambdaQueryWrapper<>(); //根据id查询 query.eq(SysThirdAccount::getSysUserId,sysUser.getId()); @@ -510,7 +511,7 @@ public class ThirdAppController { */ @DeleteMapping("/deleteThirdAccount") public Result deleteThirdAccountById(@RequestBody SysThirdAccount sysThirdAccount){ - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); if(!sysUser.getId().equals(sysThirdAccount.getSysUserId())){ return Result.error("无权修改他人信息"); } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysDataLog.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysDataLog.java index 844fbe790..a98658fd3 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysDataLog.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysDataLog.java @@ -10,6 +10,7 @@ import lombok.experimental.Accessors; import lombok.extern.slf4j.Slf4j; import org.apache.shiro.SecurityUtils; import org.jeecg.common.system.vo.LoginUser; +import org.jeecg.config.security.utils.SecureUtil; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.security.core.context.SecurityContextHolder; @@ -95,7 +96,7 @@ public class SysDataLog implements Serializable { */ public void autoSetCreateName() { try { - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); this.setCreateName(sysUser.getRealname()); } catch (Exception e) { log.warn("SecurityUtils.getSubject() 获取用户信息异常:" + e.getMessage()); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysAnnouncementServiceImpl.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysAnnouncementServiceImpl.java index ca1805274..9f9d03cda 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysAnnouncementServiceImpl.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysAnnouncementServiceImpl.java @@ -10,6 +10,7 @@ import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.oConvertUtils; import org.jeecg.config.mybatis.MybatisPlusSaasConfig; +import org.jeecg.config.security.utils.SecureUtil; import org.jeecg.modules.system.entity.SysAnnouncement; import org.jeecg.modules.system.entity.SysAnnouncementSend; import org.jeecg.modules.system.mapper.SysAnnouncementMapper; @@ -145,7 +146,7 @@ public class SysAnnouncementServiceImpl extends ServiceImpl announcementIds = this.getNotSendedAnnouncementlist(userId); List sysAnnouncementSendList = new ArrayList<>(); @@ -195,7 +196,7 @@ public class SysAnnouncementServiceImpl extends ServiceImpl page = new Page(pageNo,pageSize); List list = baseMapper.queryAllMessageList(page, sysUser.getId(), fromUser, starFlag, beginDate, endDate); @@ -204,13 +205,13 @@ public class SysAnnouncementServiceImpl extends ServiceImpl annoceIdList) { - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); sysAnnouncementSendMapper.updateReaded(sysUser.getId(), annoceIdList); } @Override public void clearAllUnReadMessage() { - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); sysAnnouncementSendMapper.clearAllUnReadMessage(sysUser.getId()); } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysBaseApiImpl.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysBaseApiImpl.java index 3a94d1818..d45c7efbd 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysBaseApiImpl.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysBaseApiImpl.java @@ -17,7 +17,6 @@ import freemarker.template.TemplateException; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang3.ObjectUtils; -import org.apache.shiro.SecurityUtils; import org.jeecg.common.api.dto.DataLogDTO; import org.jeecg.common.api.dto.OnlineAuthDTO; import org.jeecg.common.api.dto.message.*; @@ -39,6 +38,7 @@ import org.jeecg.common.util.dynamic.db.FreemarkerParseFactory; import org.jeecg.common.util.oConvertUtils; import org.jeecg.config.firewall.SqlInjection.IDictTableWhiteListHandler; import org.jeecg.config.mybatis.MybatisPlusSaasConfig; +import org.jeecg.config.security.utils.SecureUtil; import org.jeecg.modules.message.entity.SysMessageTemplate; import org.jeecg.modules.message.handle.impl.DdSendMsgHandle; import org.jeecg.modules.message.handle.impl.EmailSendMsgHandle; @@ -159,6 +159,19 @@ public class SysBaseApiImpl implements ISysBaseAPI { return user; } + @Override + public LoginUser getUserByPhone(String phone) { + if (oConvertUtils.isEmpty(phone)) { + return null; + } + + LoginUser loginUser = new LoginUser(); + SysUser sysUser = sysUserService.getUserByPhone(phone); + + BeanUtils.copyProperties(sysUser, loginUser); + return loginUser; + } + @Override public String translateDictFromTable(String table, String text, String code, String key) { return sysDictService.queryTableDictTextByKey(table, text, code, key); @@ -585,7 +598,7 @@ public class SysBaseApiImpl implements ISysBaseAPI { public void updateSysAnnounReadFlag(String busType, String busId) { SysAnnouncement announcement = sysAnnouncementMapper.selectOne(new QueryWrapper().eq("bus_type",busType).eq("bus_id",busId)); if(announcement != null){ - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); String userId = sysUser.getId(); LambdaUpdateWrapper updateWrapper = new UpdateWrapper().lambda(); updateWrapper.set(SysAnnouncementSend::getReadFlag, CommonConstant.HAS_READ_FLAG); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysDepartServiceImpl.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysDepartServiceImpl.java index da7706f24..4edb70546 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysDepartServiceImpl.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysDepartServiceImpl.java @@ -23,6 +23,7 @@ import org.jeecg.common.util.ImportExcelUtil; import org.jeecg.common.util.YouBianCodeUtil; import org.jeecg.common.util.oConvertUtils; import org.jeecg.config.mybatis.MybatisPlusSaasConfig; +import org.jeecg.config.security.utils.SecureUtil; import org.jeecg.modules.system.entity.*; import org.jeecg.modules.system.mapper.*; import org.jeecg.modules.system.model.DepartIdModel; @@ -836,7 +837,7 @@ public class SysDepartServiceImpl extends ServiceImpl getMyDepartList() { - LoginUser user = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser user = SecureUtil.currentUser(); String userId = user.getId(); //字典code集合 List list = new ArrayList<>(); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysTenantPackServiceImpl.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysTenantPackServiceImpl.java index d7071d092..34c75c178 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysTenantPackServiceImpl.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysTenantPackServiceImpl.java @@ -8,6 +8,7 @@ import org.jeecg.common.constant.TenantConstant; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.SpringContextUtils; import org.jeecg.common.util.oConvertUtils; +import org.jeecg.config.security.utils.SecureUtil; import org.jeecg.modules.aop.TenantLog; import org.jeecg.modules.system.entity.SysPackPermission; import org.jeecg.modules.system.entity.SysTenant; @@ -135,7 +136,7 @@ public class SysTenantPackServiceImpl extends ServiceImpl invitationUser(String phone, String departId) { Result result = new Result<>(); - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); //1、查询用户信息,判断用户是否存在 SysUser userByPhone = userService.getUserByPhone(phone); @@ -429,7 +426,7 @@ public class SysTenantServiceImpl extends ServiceImpl pageList = null; // 部门ID不存在 直接查询用户表即可 Page page = new Page<>(pageNo, pageSize); - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); if(oConvertUtils.isEmpty(departId)){ LambdaQueryWrapper query = new LambdaQueryWrapper<>(); query.eq(SysUser::getStatus,Integer.parseInt(CommonConstant.STATUS_1)); @@ -249,7 +250,7 @@ public class SysUserDepartServiceImpl extends ServiceImpl pageList = null; // 部门ID不存在 直接查询用户表即可 Page page = new Page<>(pageNo, pageSize); - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); if(oConvertUtils.isNotEmpty(departId)){ // 有部门ID 需要走自定义sql SysDepart sysDepart = sysDepartService.getById(departId); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java index 5db6072e1..83d5644f0 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java @@ -31,6 +31,7 @@ import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.system.vo.SysUserCacheInfo; import org.jeecg.common.util.*; import org.jeecg.config.mybatis.MybatisPlusSaasConfig; +import org.jeecg.config.security.utils.SecureUtil; import org.jeecg.modules.base.service.BaseCommonService; import org.jeecg.modules.message.handle.impl.SystemSendMsgHandle; import org.jeecg.modules.system.entity.*; @@ -1480,7 +1481,7 @@ public class SysUserServiceImpl extends ServiceImpl impl //导出文件名称 mv.addObject(NormalExcelConstants.FILE_NAME, "用户列表"); mv.addObject(NormalExcelConstants.CLASS, AppExportUserVo.class); - LoginUser user = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser user = SecureUtil.currentUser();; ExportParams exportParams = new ExportParams("导入规则:\n" + "1、存在用户编号时,数据会根据用户编号进行匹配,匹配成功后只会更新职位和工号;\n" + "2、不存在用户编号时,支持手机号、邮箱、姓名、部们、职位、工号导入,其中手机号必填;\n" + @@ -1788,7 +1789,7 @@ public class SysUserServiceImpl extends ServiceImpl impl userTenantMapper.insert(userTenant); //update-begin---author:wangshuai ---date:20230710 for:【QQYUN-5731】导入用户时,没有提醒------------ //发送系统消息通知 - LoginUser sysUser = JSON.parseObject(SecurityContextHolder.getContext().getAuthentication().getName(), LoginUser.class);; + LoginUser sysUser = SecureUtil.currentUser(); MessageDTO messageDTO = new MessageDTO(); String title = sysUser.getRealname() + " 邀请您加入 " + tenantName + "。"; messageDTO.setTitle(title); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai b/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai index 637f4d739..f43ff7026 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai +++ b/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai @@ -87,7 +87,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e */ @AutoLog(value = "${tableVo.ftlDescription}-添加") @Operation(summary="${tableVo.ftlDescription}-添加") - @RequiresPermissions("${entityPackage}:${tableName}:add") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:add')") @PostMapping(value = "/add") public Result add(@RequestBody ${entityName} ${entityName?uncap_first}) { <#if bpm_flag> @@ -105,7 +105,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e */ @AutoLog(value = "${tableVo.ftlDescription}-编辑") @Operation(summary="${tableVo.ftlDescription}-编辑") - @RequiresPermissions("${entityPackage}:${tableName}:edit") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:edit')") @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) public Result edit(@RequestBody ${entityName} ${entityName?uncap_first}) { ${entityName?uncap_first}Service.updateById(${entityName?uncap_first}); @@ -120,7 +120,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e */ @AutoLog(value = "${tableVo.ftlDescription}-通过id删除") @Operation(summary="${tableVo.ftlDescription}-通过id删除") - @RequiresPermissions("${entityPackage}:${tableName}:delete") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:delete')") @DeleteMapping(value = "/delete") public Result delete(@RequestParam(name="id",required=true) String id) { ${entityName?uncap_first}Service.removeById(id); @@ -135,7 +135,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e */ @AutoLog(value = "${tableVo.ftlDescription}-批量删除") @Operation(summary="${tableVo.ftlDescription}-批量删除") - @RequiresPermissions("${entityPackage}:${tableName}:deleteBatch") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:deleteBatch')") @DeleteMapping(value = "/deleteBatch") public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { this.${entityName?uncap_first}Service.removeByIds(Arrays.asList(ids.split(","))); @@ -165,7 +165,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e * @param request * @param ${entityName?uncap_first} */ - @RequiresPermissions("${entityPackage}:${tableName}:exportXls") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:exportXls')") @RequestMapping(value = "/exportXls") public ModelAndView exportXls(HttpServletRequest request, ${entityName} ${entityName?uncap_first}) { return super.exportXls(request, ${entityName?uncap_first}, ${entityName}.class, "${tableVo.ftlDescription}"); @@ -178,7 +178,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e * @param response * @return */ - @RequiresPermissions("${entityPackage}:${tableName}:importExcel") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:importExcel')") @RequestMapping(value = "/importExcel", method = RequestMethod.POST) public Result importExcel(HttpServletRequest request, HttpServletResponse response) { return super.importExcel(request, response, ${entityName}.class); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai b/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai index bae5ee53b..97b0bf343 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai +++ b/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai @@ -101,7 +101,7 @@ public class ${entityName}Controller { */ @AutoLog(value = "${tableVo.ftlDescription}-添加") @Operation(summary="${tableVo.ftlDescription}-添加") - @RequiresPermissions("${entityPackage}:${tableName}:add") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:add')") @PostMapping(value = "/add") public Result add(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) { ${entityName} ${entityName?uncap_first} = new ${entityName}(); @@ -121,7 +121,7 @@ public class ${entityName}Controller { */ @AutoLog(value = "${tableVo.ftlDescription}-编辑") @Operation(summary="${tableVo.ftlDescription}-编辑") - @RequiresPermissions("${entityPackage}:${tableName}:edit") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:edit')") @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) public Result edit(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) { ${entityName} ${entityName?uncap_first} = new ${entityName}(); @@ -142,7 +142,7 @@ public class ${entityName}Controller { */ @AutoLog(value = "${tableVo.ftlDescription}-通过id删除") @Operation(summary="${tableVo.ftlDescription}-通过id删除") - @RequiresPermissions("${entityPackage}:${tableName}:delete") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:delete')") @DeleteMapping(value = "/delete") public Result delete(@RequestParam(name="id",required=true) String id) { ${entityName?uncap_first}Service.delMain(id); @@ -157,7 +157,7 @@ public class ${entityName}Controller { */ @AutoLog(value = "${tableVo.ftlDescription}-批量删除") @Operation(summary="${tableVo.ftlDescription}-批量删除") - @RequiresPermissions("${entityPackage}:${tableName}:deleteBatch") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:deleteBatch')") @DeleteMapping(value = "/deleteBatch") public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { this.${entityName?uncap_first}Service.delBatchMain(Arrays.asList(ids.split(","))); @@ -204,7 +204,7 @@ public class ${entityName}Controller { * @param request * @param ${entityName?uncap_first} */ - @RequiresPermissions("${entityPackage}:${tableName}:exportXls") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:exportXls')") @RequestMapping(value = "/exportXls") public ModelAndView exportXls(HttpServletRequest request, ${entityName} ${entityName?uncap_first}) { // Step.1 组装查询条件查询数据 @@ -248,7 +248,7 @@ public class ${entityName}Controller { * @param response * @return */ - @RequiresPermissions("${entityPackage}:${tableName}:importExcel") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:importExcel')") @RequestMapping(value = "/importExcel", method = RequestMethod.POST) public Result importExcel(HttpServletRequest request, HttpServletResponse response) { MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; diff --git a/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai b/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai index 391f39acd..9bf46b0db 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai +++ b/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai @@ -207,7 +207,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e */ @AutoLog(value = "${tableVo.ftlDescription}-添加") @Operation(summary="${tableVo.ftlDescription}-添加") - @RequiresPermissions("${entityPackage}:${tableName}:add") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:add')") @PostMapping(value = "/add") public Result add(@RequestBody ${entityName} ${entityName?uncap_first}) { ${entityName?uncap_first}Service.add${entityName}(${entityName?uncap_first}); @@ -222,7 +222,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e */ @AutoLog(value = "${tableVo.ftlDescription}-编辑") @Operation(summary="${tableVo.ftlDescription}-编辑") - @RequiresPermissions("${entityPackage}:${tableName}:edit") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:edit')") @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) public Result edit(@RequestBody ${entityName} ${entityName?uncap_first}) { ${entityName?uncap_first}Service.update${entityName}(${entityName?uncap_first}); @@ -237,7 +237,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e */ @AutoLog(value = "${tableVo.ftlDescription}-通过id删除") @Operation(summary="${tableVo.ftlDescription}-通过id删除") - @RequiresPermissions("${entityPackage}:${tableName}:delete") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:delete')") @DeleteMapping(value = "/delete") public Result delete(@RequestParam(name="id",required=true) String id) { ${entityName?uncap_first}Service.delete${entityName}(id); @@ -252,7 +252,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e */ @AutoLog(value = "${tableVo.ftlDescription}-批量删除") @Operation(summary="${tableVo.ftlDescription}-批量删除") - @RequiresPermissions("${entityPackage}:${tableName}:deleteBatch") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:deleteBatch')") @DeleteMapping(value = "/deleteBatch") public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { this.${entityName?uncap_first}Service.removeByIds(Arrays.asList(ids.split(","))); @@ -282,7 +282,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e * @param request * @param ${entityName?uncap_first} */ - @RequiresPermissions("${entityPackage}:${tableName}:exportXls") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:exportXls')") @RequestMapping(value = "/exportXls") public ModelAndView exportXls(HttpServletRequest request, ${entityName} ${entityName?uncap_first}) { return super.exportXls(request, ${entityName?uncap_first}, ${entityName}.class, "${tableVo.ftlDescription}"); @@ -295,7 +295,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e * @param response * @return */ - @RequiresPermissions("${entityPackage}:${tableName}:importExcel") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:importExcel')") @RequestMapping(value = "/importExcel", method = RequestMethod.POST) public Result importExcel(HttpServletRequest request, HttpServletResponse response) { return super.importExcel(request, response, ${entityName}.class); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai b/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai index a9b014d8c..aa42756eb 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai +++ b/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai @@ -91,7 +91,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e */ @AutoLog(value = "${tableVo.ftlDescription}-添加") @Operation(summary="${tableVo.ftlDescription}-添加") - @RequiresPermissions("${entityPackage}:${tableName}:add") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:add')") @PostMapping(value = "/add") public Result add(@RequestBody ${entityName} ${entityName?uncap_first}) { ${entityName?uncap_first}Service.save(${entityName?uncap_first}); @@ -105,7 +105,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e */ @AutoLog(value = "${tableVo.ftlDescription}-编辑") @Operation(summary="${tableVo.ftlDescription}-编辑") - @RequiresPermissions("${entityPackage}:${tableName}:edit") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:edit')") @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) public Result edit(@RequestBody ${entityName} ${entityName?uncap_first}) { ${entityName?uncap_first}Service.updateById(${entityName?uncap_first}); @@ -119,7 +119,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e */ @AutoLog(value = "${tableVo.ftlDescription}-通过id删除") @Operation(summary="${tableVo.ftlDescription}-通过id删除") - @RequiresPermissions("${entityPackage}:${tableName}:delete") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:delete')") @DeleteMapping(value = "/delete") public Result delete(@RequestParam(name="id",required=true) String id) { ${entityName?uncap_first}Service.delMain(id); @@ -133,7 +133,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e */ @AutoLog(value = "${tableVo.ftlDescription}-批量删除") @Operation(summary="${tableVo.ftlDescription}-批量删除") - @RequiresPermissions("${entityPackage}:${tableName}:deleteBatch") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:deleteBatch')") @DeleteMapping(value = "/deleteBatch") public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { this.${entityName?uncap_first}Service.delBatchMain(Arrays.asList(ids.split(","))); @@ -144,7 +144,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e * 导出 * @return */ - @RequiresPermissions("${entityPackage}:${tableName}:exportXls") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:exportXls')") @RequestMapping(value = "/exportXls") public ModelAndView exportXls(HttpServletRequest request, ${entityName} ${entityName?uncap_first}) { return super.exportXls(request, ${entityName?uncap_first}, ${entityName}.class, "${tableVo.ftlDescription}"); @@ -154,7 +154,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e * 导入 * @return */ - @RequiresPermissions("${entityPackage}:${tableName}:importExcel") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:importExcel')") @RequestMapping(value = "/importExcel", method = RequestMethod.POST) public Result importExcel(HttpServletRequest request, HttpServletResponse response) { return super.importExcel(request, response, ${entityName}.class); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai b/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai index 0bf86658c..00a7ddc1a 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai +++ b/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai @@ -95,7 +95,7 @@ public class ${entityName}Controller { */ @AutoLog(value = "${tableVo.ftlDescription}-添加") @Operation(summary="${tableVo.ftlDescription}-添加") - @RequiresPermissions("${entityPackage}:${tableName}:add") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:add')") @PostMapping(value = "/add") public Result add(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) { ${entityName} ${entityName?uncap_first} = new ${entityName}(); @@ -112,7 +112,7 @@ public class ${entityName}Controller { */ @AutoLog(value = "${tableVo.ftlDescription}-编辑") @Operation(summary="${tableVo.ftlDescription}-编辑") - @RequiresPermissions("${entityPackage}:${tableName}:edit") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:edit')") @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) public Result edit(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) { ${entityName} ${entityName?uncap_first} = new ${entityName}(); @@ -133,7 +133,7 @@ public class ${entityName}Controller { */ @AutoLog(value = "${tableVo.ftlDescription}-通过id删除") @Operation(summary="${tableVo.ftlDescription}-通过id删除") - @RequiresPermissions("${entityPackage}:${tableName}:delete") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:delete')") @DeleteMapping(value = "/delete") public Result delete(@RequestParam(name="id",required=true) String id) { ${entityName?uncap_first}Service.delMain(id); @@ -148,7 +148,7 @@ public class ${entityName}Controller { */ @AutoLog(value = "${tableVo.ftlDescription}-批量删除") @Operation(summary="${tableVo.ftlDescription}-批量删除") - @RequiresPermissions("${entityPackage}:${tableName}:deleteBatch") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:deleteBatch')") @DeleteMapping(value = "/deleteBatch") public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { this.${entityName?uncap_first}Service.delBatchMain(Arrays.asList(ids.split(","))); @@ -199,7 +199,7 @@ public class ${entityName}Controller { * @param request * @param ${entityName?uncap_first} */ - @RequiresPermissions("${entityPackage}:${tableName}:exportXls") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:exportXls')") @RequestMapping(value = "/exportXls") public ModelAndView exportXls(HttpServletRequest request, ${entityName} ${entityName?uncap_first}) { // Step.1 组装查询条件查询数据 @@ -243,7 +243,7 @@ public class ${entityName}Controller { * @param response * @return */ - @RequiresPermissions("${entityPackage}:${tableName}:importExcel") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:importExcel')") @RequestMapping(value = "/importExcel", method = RequestMethod.POST) public Result importExcel(HttpServletRequest request, HttpServletResponse response) { MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; diff --git a/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai b/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai index 45d25c3c1..9d7b47781 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai +++ b/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai @@ -102,7 +102,7 @@ public class ${entityName}Controller { */ @AutoLog(value = "${tableVo.ftlDescription}-添加") @Operation(summary="${tableVo.ftlDescription}-添加") - @RequiresPermissions("${entityPackage}:${tableName}:add") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:add')") @PostMapping(value = "/add") public Result add(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) { ${entityName} ${entityName?uncap_first} = new ${entityName}(); @@ -122,7 +122,7 @@ public class ${entityName}Controller { */ @AutoLog(value = "${tableVo.ftlDescription}-编辑") @Operation(summary="${tableVo.ftlDescription}-编辑") - @RequiresPermissions("${entityPackage}:${tableName}:edit") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:edit')") @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) public Result edit(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) { ${entityName} ${entityName?uncap_first} = new ${entityName}(); @@ -143,7 +143,7 @@ public class ${entityName}Controller { */ @AutoLog(value = "${tableVo.ftlDescription}-通过id删除") @Operation(summary="${tableVo.ftlDescription}-通过id删除") - @RequiresPermissions("${entityPackage}:${tableName}:delete") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:delete')") @DeleteMapping(value = "/delete") public Result delete(@RequestParam(name="id",required=true) String id) { ${entityName?uncap_first}Service.delMain(id); @@ -158,7 +158,7 @@ public class ${entityName}Controller { */ @AutoLog(value = "${tableVo.ftlDescription}-批量删除") @Operation(summary="${tableVo.ftlDescription}-批量删除") - @RequiresPermissions("${entityPackage}:${tableName}:deleteBatch") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:deleteBatch')") @DeleteMapping(value = "/deleteBatch") public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { this.${entityName?uncap_first}Service.delBatchMain(Arrays.asList(ids.split(","))); @@ -205,7 +205,7 @@ public class ${entityName}Controller { * @param request * @param ${entityName?uncap_first} */ - @RequiresPermissions("${entityPackage}:${tableName}:exportXls") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:exportXls')") @RequestMapping(value = "/exportXls") public ModelAndView exportXls(HttpServletRequest request, ${entityName} ${entityName?uncap_first}) { // Step.1 组装查询条件查询数据 @@ -249,7 +249,7 @@ public class ${entityName}Controller { * @param response * @return */ - @RequiresPermissions("${entityPackage}:${tableName}:importExcel") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:importExcel')") @RequestMapping(value = "/importExcel", method = RequestMethod.POST) public Result importExcel(HttpServletRequest request, HttpServletResponse response) { MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; diff --git a/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai b/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai index 0871c63ea..75db72634 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai +++ b/jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai @@ -95,7 +95,7 @@ public class ${entityName}Controller { */ @AutoLog(value = "${tableVo.ftlDescription}-添加") @Operation(summary="${tableVo.ftlDescription}-添加") - @RequiresPermissions("${entityPackage}:${tableName}:add") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:add')") @PostMapping(value = "/add") public Result add(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) { ${entityName} ${entityName?uncap_first} = new ${entityName}(); @@ -112,7 +112,7 @@ public class ${entityName}Controller { */ @AutoLog(value = "${tableVo.ftlDescription}-编辑") @Operation(summary="${tableVo.ftlDescription}-编辑") - @RequiresPermissions("${entityPackage}:${tableName}:edit") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:edit')") @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) public Result edit(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) { ${entityName} ${entityName?uncap_first} = new ${entityName}(); @@ -133,7 +133,7 @@ public class ${entityName}Controller { */ @AutoLog(value = "${tableVo.ftlDescription}-通过id删除") @Operation(summary="${tableVo.ftlDescription}-通过id删除") - @RequiresPermissions("${entityPackage}:${tableName}:delete") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:delete')") @DeleteMapping(value = "/delete") public Result delete(@RequestParam(name="id",required=true) String id) { ${entityName?uncap_first}Service.delMain(id); @@ -148,7 +148,7 @@ public class ${entityName}Controller { */ @AutoLog(value = "${tableVo.ftlDescription}-批量删除") @Operation(summary="${tableVo.ftlDescription}-批量删除") - @RequiresPermissions("${entityPackage}:${tableName}:deleteBatch") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:deleteBatch')") @DeleteMapping(value = "/deleteBatch") public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { this.${entityName?uncap_first}Service.delBatchMain(Arrays.asList(ids.split(","))); @@ -195,7 +195,7 @@ public class ${entityName}Controller { * @param request * @param ${entityName?uncap_first} */ - @RequiresPermissions("${entityPackage}:${tableName}:exportXls") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:exportXls')") @RequestMapping(value = "/exportXls") public ModelAndView exportXls(HttpServletRequest request, ${entityName} ${entityName?uncap_first}) { // Step.1 组装查询条件查询数据 @@ -239,7 +239,7 @@ public class ${entityName}Controller { * @param response * @return */ - @RequiresPermissions("${entityPackage}:${tableName}:importExcel") + @PreAuthorize("@jps.requiresPermissions('${entityPackage}:${tableName}:importExcel')") @RequestMapping(value = "/importExcel", method = RequestMethod.POST) public Result importExcel(HttpServletRequest request, HttpServletResponse response) { MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; diff --git a/jeecg-server-cloud/jeecg-cloud-gateway/src/main/resources/application.yml b/jeecg-server-cloud/jeecg-cloud-gateway/src/main/resources/application.yml index 2c1c006eb..c77b87f49 100644 --- a/jeecg-server-cloud/jeecg-cloud-gateway/src/main/resources/application.yml +++ b/jeecg-server-cloud/jeecg-cloud-gateway/src/main/resources/application.yml @@ -16,19 +16,21 @@ spring: allow-circular-references: true config: import: - - optional:nacos:jeecg-gateway-dev.yaml + - optional:nacos:${spring.application.name}-@profile.name@.yaml cloud: nacos: config: - server-addr: localhost:8848 - namespace: public - # username: @config.username@ - # password: @config.password@ + server-addr: @config.server-addr@ + group: @config.group@ + namespace: @config.namespace@ + username: @config.username@ + password: @config.password@ discovery: server-addr: ${spring.cloud.nacos.config.server-addr} - namespace: public - # username: @config.username@ - # password: @config.password@ + group: @config.group@ + namespace: @config.namespace@ + username: @config.username@ + password: @config.password@ gateway: discovery: locator: @@ -56,7 +58,7 @@ spring: flow: # 指定数据源名称 # 指定nacos数据源 nacos: - server-addr: ${spring.cloud.nacos.config.server-addr} + server-addr: @config.server-addr@ # 指定配置文件 dataId: ${spring.application.name}-flow-rules # 指定分组 @@ -68,7 +70,7 @@ spring: #降级规则 degrade: nacos: - server-addr: ${spring.cloud.nacos.config.server-addr} + server-addr: @config.server-addr@ dataId: ${spring.application.name}-degrade-rules groupId: SENTINEL_GROUP rule-type: degrade @@ -76,7 +78,7 @@ spring: #系统规则 system: nacos: - server-addr: ${spring.cloud.nacos.config.server-addr} + server-addr: @config.server-addr@ dataId: ${spring.application.name}-system-rules groupId: SENTINEL_GROUP rule-type: system @@ -84,7 +86,7 @@ spring: #授权规则 authority: nacos: - server-addr: ${spring.cloud.nacos.config.server-addr} + server-addr: @config.server-addr@ dataId: ${spring.application.name}-authority-rules groupId: SENTINEL_GROUP rule-type: authority @@ -92,7 +94,7 @@ spring: #热点参数 param-flow: nacos: - server-addr: ${spring.cloud.nacos.config.server-addr} + server-addr: @config.server-addr@ dataId: ${spring.application.name}-param-rules groupId: SENTINEL_GROUP rule-type: param-flow @@ -100,7 +102,7 @@ spring: #网关流控规则 gw-flow: nacos: - server-addr: ${spring.cloud.nacos.config.server-addr} + server-addr: @config.server-addr@ dataId: ${spring.application.name}-flow-rules groupId: SENTINEL_GROUP rule-type: gw-flow @@ -108,7 +110,7 @@ spring: #API流控规则 gw-api-group: nacos: - server-addr: ${spring.cloud.nacos.config.server-addr} + server-addr: @config.server-addr@ dataId: ${spring.application.name}-api-rules groupId: SENTINEL_GROUP rule-type: gw-api-group diff --git a/jeecg-server-cloud/jeecg-cloud-nacos/src/main/resources/application.yml b/jeecg-server-cloud/jeecg-cloud-nacos/src/main/resources/application.yml index b7eeddfd9..823093015 100644 --- a/jeecg-server-cloud/jeecg-cloud-nacos/src/main/resources/application.yml +++ b/jeecg-server-cloud/jeecg-cloud-nacos/src/main/resources/application.yml @@ -12,7 +12,7 @@ spring: db: num: 1 password: - '0': ${MYSQL-PWD:root} + '0': ${MYSQL-PWD:root@2023} url: '0': jdbc:mysql://${MYSQL-HOST:jeecg-boot-mysql}:${MYSQL-PORT:3306}/${MYSQL-DB:nacos}?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true user: diff --git a/jeecg-server-cloud/jeecg-system-cloud-start/src/main/resources/application.yml b/jeecg-server-cloud/jeecg-system-cloud-start/src/main/resources/application.yml index 53f5eed66..c3a55860c 100644 --- a/jeecg-server-cloud/jeecg-system-cloud-start/src/main/resources/application.yml +++ b/jeecg-server-cloud/jeecg-system-cloud-start/src/main/resources/application.yml @@ -7,18 +7,18 @@ spring: cloud: nacos: config: - server-addr: @config.server-addr@ - group: @config.group@ - namespace: @config.namespace@ - username: @config.username@ - password: @config.password@ + server-addr: localhost:8848 +# group: @config.group@ +# namespace: @config.namespace@ +# username: @config.username@ +# password: @config.password@ discovery: server-addr: ${spring.cloud.nacos.config.server-addr} - group: @config.group@ - namespace: @config.namespace@ - username: @config.username@ - password: @config.password@ +# group: @config.group@ +# namespace: @config.namespace@ +# username: @config.username@ +# password: @config.password@ config: import: - optional:nacos:jeecg.yaml - - optional:nacos:jeecg-@profile.name@.yaml \ No newline at end of file + - optional:nacos:jeecg-dev.yaml \ No newline at end of file