From c57e1e98f53fb57b8b9e4d29823ac7a8e7faf827 Mon Sep 17 00:00:00 2001 From: Bunny <1319900154@qq.com> Date: Thu, 10 Oct 2024 23:20:06 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E4=BF=AE=E6=94=B9):=20=E4=BF=AE=E6=94=B9s?= =?UTF-8?q?p6=E9=85=8D=E7=BD=AE=E5=BE=85=E7=A1=AE=E8=AE=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../generator/generator/WebGeneratorCode.java | 12 +- service/pom.xml | 10 ++ .../cn/bunny/services/ServiceApplication.java | 2 + .../controller/EmailTemplateController.java | 2 +- .../services/controller/IndexController.java | 10 +- .../bunny/services/factory/UserFactory.java | 13 +- .../services/mapper/EmailTemplateMapper.java | 2 +- .../security/config/WebSecurityConfig.java | 20 +-- .../security/custom/CustomCheckIsAdmin.java | 37 ++++++ .../services/security/custom/CustomUser.java | 2 +- .../filter/TokenAuthenticationFilter.java | 1 - ...CustomAuthorizationManagerServiceImpl.java | 72 ---------- ...CustomAuthorizationManagerServiceImpl.java | 125 ++++++++++++++++++ .../CustomUserDetailsServiceImpl.java | 27 ++-- .../service/EmailTemplateService.java | 2 +- .../impl/EmailTemplateServiceImpl.java | 2 +- .../service/impl/RouterServiceImpl.java | 4 +- service/src/main/resources/application.yml | 11 +- .../resources/mapper/EmailTemplateMapper.xml | 37 +++++- 19 files changed, 268 insertions(+), 123 deletions(-) create mode 100644 service/src/main/java/cn/bunny/services/security/custom/CustomCheckIsAdmin.java delete mode 100644 service/src/main/java/cn/bunny/services/security/service/iml/CustomAuthorizationManagerServiceImpl.java create mode 100644 service/src/main/java/cn/bunny/services/security/service/impl/CustomAuthorizationManagerServiceImpl.java rename service/src/main/java/cn/bunny/services/security/service/{iml => impl}/CustomUserDetailsServiceImpl.java (78%) diff --git a/common/common-generator/src/main/java/cn/bunny/common/generator/generator/WebGeneratorCode.java b/common/common-generator/src/main/java/cn/bunny/common/generator/generator/WebGeneratorCode.java index cf50470..74c632a 100644 --- a/common/common-generator/src/main/java/cn/bunny/common/generator/generator/WebGeneratorCode.java +++ b/common/common-generator/src/main/java/cn/bunny/common/generator/generator/WebGeneratorCode.java @@ -36,7 +36,7 @@ import java.util.stream.Stream; @Service public class WebGeneratorCode { // 公共路径 - public static String commonPath = "D:\\MyFolder\\auth-admin\\auth-web\\src"; + public static String commonPath = "D:\\Project\\web\\PC\\auth\\auth-web\\src"; // 生成API请求路径 public static String apiPath = commonPath + "\\api\\v1\\"; // 生成vue路径 @@ -44,11 +44,11 @@ public class WebGeneratorCode { // 生成仓库路径 public static String storePath = commonPath + "\\store\\system\\"; // 后端controller - public static String controllerPath = "D:\\MyFolder\\auth-admin\\auth-server-java\\service\\src\\main\\java\\cn\\bunny\\services\\controller\\"; - public static String servicePath = "D:\\MyFolder\\auth-admin\\auth-server-java\\service\\src\\main\\java\\cn\\bunny\\services\\service\\"; - public static String serviceImplPath = "D:\\MyFolder\\auth-admin\\auth-server-java\\service\\src\\main\\java\\cn\\bunny\\services\\service\\impl\\"; - public static String mapperPath = "D:\\MyFolder\\auth-admin\\auth-server-java\\service\\src\\main\\java\\cn\\bunny\\services\\mapper\\"; - public static String resourceMapperPath = "D:\\MyFolder\\auth-admin\\auth-server-java\\service\\src\\main\\resources\\mapper\\"; + public static String controllerPath = "D:\\Project\\web\\PC\\auth\\auth-server-java\\service\\src\\main\\java\\cn\\bunny\\services\\controller\\"; + public static String servicePath = "D:\\Project\\web\\PC\\auth\\auth-server-java\\service\\src\\main\\java\\cn\\bunny\\services\\service\\"; + public static String serviceImplPath = "D:\\Project\\web\\PC\\auth\\auth-server-java\\service\\src\\main\\java\\cn\\bunny\\services\\service\\impl\\"; + public static String mapperPath = "D:\\Project\\web\\PC\\auth\\auth-server-java\\service\\src\\main\\java\\cn\\bunny\\services\\mapper\\"; + public static String resourceMapperPath = "D:\\Project\\web\\PC\\auth\\auth-server-java\\service\\src\\main\\resources\\mapper\\"; public static void main(String[] args) throws Exception { Class originalClass = EmailTemplate.class; diff --git a/service/pom.xml b/service/pom.xml index ec262d1..928daa5 100644 --- a/service/pom.xml +++ b/service/pom.xml @@ -46,6 +46,16 @@ spring-boot-starter-actuator 3.2.3 + + de.codecentric + spring-boot-admin-starter-server + 3.2.3 + + + de.codecentric + spring-boot-admin-starter-client + 3.2.3 + junit diff --git a/service/src/main/java/cn/bunny/services/ServiceApplication.java b/service/src/main/java/cn/bunny/services/ServiceApplication.java index 32c058e..d27ff1a 100644 --- a/service/src/main/java/cn/bunny/services/ServiceApplication.java +++ b/service/src/main/java/cn/bunny/services/ServiceApplication.java @@ -1,5 +1,6 @@ package cn.bunny.services; +import de.codecentric.boot.admin.server.config.EnableAdminServer; import lombok.extern.slf4j.Slf4j; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; @@ -12,6 +13,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; @MapperScan("cn.bunny.services.mapper") @ComponentScan("cn.bunny") @EnableScheduling +@EnableAdminServer @EnableCaching @EnableTransactionManagement @Slf4j diff --git a/service/src/main/java/cn/bunny/services/controller/EmailTemplateController.java b/service/src/main/java/cn/bunny/services/controller/EmailTemplateController.java index 843dd68..74dc914 100644 --- a/service/src/main/java/cn/bunny/services/controller/EmailTemplateController.java +++ b/service/src/main/java/cn/bunny/services/controller/EmailTemplateController.java @@ -26,7 +26,7 @@ import java.util.List; *

* * @author Bunny - * @since 2024-10-10 16:28:29 + * @since 2024-10-10 21:24:08 */ @Tag(name = "邮件模板表", description = "邮件模板表相关接口") @RestController diff --git a/service/src/main/java/cn/bunny/services/controller/IndexController.java b/service/src/main/java/cn/bunny/services/controller/IndexController.java index 08c7e3d..d4dd48e 100644 --- a/service/src/main/java/cn/bunny/services/controller/IndexController.java +++ b/service/src/main/java/cn/bunny/services/controller/IndexController.java @@ -17,11 +17,11 @@ import org.springframework.web.bind.annotation.RestController; @RequestMapping("/") public class IndexController { - @Operation(summary = "访问首页", description = "访问首页") - @GetMapping("") - public String index() { - return "欢迎访问 Bunny Java Template,欢迎去Gitee:https://gitee.com/BunnyBoss/java_single.git"; - } + // @Operation(summary = "访问首页", description = "访问首页") + // @GetMapping("") + // public String index() { + // return "欢迎访问 Bunny Java Template,欢迎去Gitee:https://gitee.com/BunnyBoss/java_single.git"; + // } @Operation(summary = "生成验证码", description = "生成验证码") @GetMapping("noAuth/checkCode") diff --git a/service/src/main/java/cn/bunny/services/factory/UserFactory.java b/service/src/main/java/cn/bunny/services/factory/UserFactory.java index 77534f3..ad74946 100644 --- a/service/src/main/java/cn/bunny/services/factory/UserFactory.java +++ b/service/src/main/java/cn/bunny/services/factory/UserFactory.java @@ -12,6 +12,7 @@ import cn.bunny.dao.pojo.constant.UserConstant; import cn.bunny.dao.vo.system.user.LoginVo; import cn.bunny.services.mapper.PowerMapper; import cn.bunny.services.mapper.RoleMapper; +import cn.bunny.services.security.custom.CustomCheckIsAdmin; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; @@ -62,16 +63,14 @@ public class UserFactory { String expires = plusDay.format(dateTimeFormatter); // 查找用户橘色 - List roles = roleMapper.selectListByUserId(userId).stream().map(Role::getRoleCode).toList(); + List roles = new ArrayList<>(roleMapper.selectListByUserId(userId).stream().map(Role::getRoleCode).toList()); List permissions = new ArrayList<>(); // 判断是否是 admin 如果是admin 赋予所有权限 - boolean isAdmin = roles.stream().anyMatch(role -> role.equals("admin")); - if (isAdmin) { - permissions.add("*"); - permissions.add("*::*"); - permissions.add("*::*::*"); - } else permissions = powerMapper.selectListByUserId(userId).stream().map(Power::getPowerCode).toList(); + boolean isAdmin = CustomCheckIsAdmin.checkAdmin(roles, permissions, user); + if (!isAdmin) { + permissions = powerMapper.selectListByUserId(userId).stream().map(Power::getPowerCode).toList(); + } // 构建返回对象,设置用户需要内容 LoginVo loginVo = new LoginVo(); diff --git a/service/src/main/java/cn/bunny/services/mapper/EmailTemplateMapper.java b/service/src/main/java/cn/bunny/services/mapper/EmailTemplateMapper.java index bb6f7a2..1543395 100644 --- a/service/src/main/java/cn/bunny/services/mapper/EmailTemplateMapper.java +++ b/service/src/main/java/cn/bunny/services/mapper/EmailTemplateMapper.java @@ -16,7 +16,7 @@ import java.util.List; *

* * @author Bunny - * @since 2024-10-10 16:28:29 + * @since 2024-10-10 21:24:08 */ @Mapper public interface EmailTemplateMapper extends BaseMapper { diff --git a/service/src/main/java/cn/bunny/services/security/config/WebSecurityConfig.java b/service/src/main/java/cn/bunny/services/security/config/WebSecurityConfig.java index 65f573f..94b0f26 100644 --- a/service/src/main/java/cn/bunny/services/security/config/WebSecurityConfig.java +++ b/service/src/main/java/cn/bunny/services/security/config/WebSecurityConfig.java @@ -1,13 +1,11 @@ package cn.bunny.services.security.config; import cn.bunny.services.security.custom.CustomPasswordEncoder; -import cn.bunny.services.security.filter.NoTokenAuthenticationFilter; -import cn.bunny.services.security.filter.TokenAuthenticationFilter; import cn.bunny.services.security.filter.TokenLoginFilterService; import cn.bunny.services.security.handelr.SecurityAccessDeniedHandler; import cn.bunny.services.security.handelr.SecurityAuthenticationEntryPoint; import cn.bunny.services.security.service.CustomUserDetailsService; -import cn.bunny.services.security.service.iml.CustomAuthorizationManagerServiceImpl; +import cn.bunny.services.security.service.impl.CustomAuthorizationManagerServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -30,7 +28,7 @@ import org.springframework.security.web.util.matcher.RegexRequestMatcher; public class WebSecurityConfig { @Autowired private RedisTemplate redisTemplate; - + @Autowired private CustomUserDetailsService customUserDetailsService; @@ -49,7 +47,7 @@ public class WebSecurityConfig { // 前端段分离不需要---禁用明文验证 .httpBasic(AbstractHttpConfigurer::disable) // 前端段分离不需要---禁用默认登录页 - // .formLogin(AbstractHttpConfigurer::disable) + .formLogin(AbstractHttpConfigurer::disable) // 前端段分离不需要---禁用退出页 .logout(AbstractHttpConfigurer::disable) // 前端段分离不需要---csrf攻击 @@ -61,6 +59,8 @@ public class WebSecurityConfig { // 前后端分离不需要---记住我,e -> e.rememberMeParameter("rememberBunny").rememberMeCookieName("rememberBunny").key("BunnyKey") .rememberMe(AbstractHttpConfigurer::disable) .authorizeHttpRequests(authorize -> { + // 有样式文件,不需要访问权限 + authorize.requestMatchers(RegexRequestMatcher.regexMatcher(".*\\.(css|js)$")).permitAll(); // 上面都不是需要鉴权访问 authorize.anyRequest().access(customAuthorizationManagerService); }) @@ -73,8 +73,8 @@ public class WebSecurityConfig { // 登录验证过滤器 .addFilterBefore(new TokenLoginFilterService(authenticationConfiguration, redisTemplate, customUserDetailsService), UsernamePasswordAuthenticationFilter.class) // 其它权限鉴权过滤器 - .addFilterAt(new NoTokenAuthenticationFilter(redisTemplate), UsernamePasswordAuthenticationFilter.class) - .addFilterAt(new TokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) + // .addFilterAt(new NoTokenAuthenticationFilter(redisTemplate), UsernamePasswordAuthenticationFilter.class) + // .addFilterAt(new TokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) // 自定义密码加密器和用户登录 .passwordManagement(customPasswordEncoder).userDetailsService(customUserDetailsService); @@ -92,10 +92,10 @@ public class WebSecurityConfig { String[] annotations = { "/", "/ws/**", "/*/*/noAuth/**", "/*/noAuth/**", "/noAuth/**", - "/media.ico", "/favicon.ico", "*.html", "/webjars/**", "/error", "/*/api-docs/*", + "/media.ico", "/favicon.ico", "*.html", "/webjars/**", "/error", "/*/i18n/getI18n", }; - return web -> web.ignoring().requestMatchers(annotations) - .requestMatchers(RegexRequestMatcher.regexMatcher(".*\\.(css|js)$")); + return web -> web.ignoring().requestMatchers(annotations); + // .requestMatchers(RegexRequestMatcher.regexMatcher(".*\\.(css|js)$")); } } diff --git a/service/src/main/java/cn/bunny/services/security/custom/CustomCheckIsAdmin.java b/service/src/main/java/cn/bunny/services/security/custom/CustomCheckIsAdmin.java new file mode 100644 index 0000000..87123e6 --- /dev/null +++ b/service/src/main/java/cn/bunny/services/security/custom/CustomCheckIsAdmin.java @@ -0,0 +1,37 @@ +package cn.bunny.services.security.custom; + +import cn.bunny.dao.entity.system.AdminUser; +import cn.bunny.dao.vo.system.user.LoginVo; + +import java.util.List; + +/** + * 检查是否是管理员 + */ +public class CustomCheckIsAdmin { + + public static boolean checkAdmin(List roleList, LoginVo loginVo) { + // 判断是否是超级管理员 + if (loginVo.getId().equals(1L)) return true; + + // 判断是否是 admin + return roleList.stream().anyMatch(role -> role.equals("admin")); + } + + public static boolean checkAdmin(List roleList, List permissions, AdminUser adminUser) { + // 判断是否是超级管理员 + boolean isIdAdmin = adminUser.getId().equals(1L); + boolean isAdmin = roleList.stream().anyMatch(role -> role.equals("admin")); + + // 判断是否是 admin + if (!isIdAdmin || !isAdmin) { + roleList.add("admin"); + permissions.add("*"); + permissions.add("*::*"); + permissions.add("*::*::*"); + return true; + } + + return false; + } +} diff --git a/service/src/main/java/cn/bunny/services/security/custom/CustomUser.java b/service/src/main/java/cn/bunny/services/security/custom/CustomUser.java index 1c31e0e..5ac7e96 100644 --- a/service/src/main/java/cn/bunny/services/security/custom/CustomUser.java +++ b/service/src/main/java/cn/bunny/services/security/custom/CustomUser.java @@ -17,7 +17,7 @@ public class CustomUser extends User { private AdminUser user; public CustomUser(AdminUser user, Collection authorities) { - super(user.getEmail(), user.getPassword(), authorities); + super(user.getUsername(), user.getPassword(), authorities); this.user = user; } } \ No newline at end of file diff --git a/service/src/main/java/cn/bunny/services/security/filter/TokenAuthenticationFilter.java b/service/src/main/java/cn/bunny/services/security/filter/TokenAuthenticationFilter.java index 9116a7b..66cc65b 100644 --- a/service/src/main/java/cn/bunny/services/security/filter/TokenAuthenticationFilter.java +++ b/service/src/main/java/cn/bunny/services/security/filter/TokenAuthenticationFilter.java @@ -24,7 +24,6 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter { // 自定义实现内容 UsernamePasswordAuthenticationToken authentication = getAuthentication(); SecurityContextHolder.getContext().setAuthentication(authentication); - chain.doFilter(request, response); } diff --git a/service/src/main/java/cn/bunny/services/security/service/iml/CustomAuthorizationManagerServiceImpl.java b/service/src/main/java/cn/bunny/services/security/service/iml/CustomAuthorizationManagerServiceImpl.java deleted file mode 100644 index d690b9f..0000000 --- a/service/src/main/java/cn/bunny/services/security/service/iml/CustomAuthorizationManagerServiceImpl.java +++ /dev/null @@ -1,72 +0,0 @@ -package cn.bunny.services.security.service.iml; - -import cn.bunny.common.service.context.BaseContext; -import cn.bunny.dao.entity.system.Power; -import cn.bunny.services.mapper.PowerMapper; -import jakarta.servlet.http.HttpServletRequest; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.security.authorization.AuthorizationDecision; -import org.springframework.security.authorization.AuthorizationManager; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.web.access.intercept.RequestAuthorizationContext; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; -import org.springframework.stereotype.Component; - -import java.util.List; -import java.util.function.Supplier; - - -/** - * 自定义权限判断 - * 判断用户有哪些权限 - */ -@Component -@Slf4j -public class CustomAuthorizationManagerServiceImpl implements AuthorizationManager { - @Autowired - private RedisTemplate redisTemplate; - @Autowired - private PowerMapper powerMapper; - - - @SneakyThrows - @Override - public AuthorizationDecision check(Supplier authentication, RequestAuthorizationContext context) { - // 用户的token和用户id、请求Url - HttpServletRequest request = context.getRequest(); - - // 角色代码列表 - List roleCodeList = authentication.get().getAuthorities().stream().map(GrantedAuthority::getAuthority).toList(); - - // 校验权限 - return new AuthorizationDecision(hasAuth(request)); - } - - /** - * 查询用户所属的角色信息 - * - * @param request 请求url地址 - */ - private Boolean hasAuth(HttpServletRequest request) { - // 角色代码列表 - List roleCodeList = BaseContext.getLoginVo().getRoles(); - - // 判断是否是 admin - boolean isAdmin = roleCodeList.stream().anyMatch(role -> role.equals("admin")); - if (isAdmin) return true; - - // 不是 admin,查询角色权限关系表 - List powerCodes = BaseContext.getLoginVo().getPermissions(); - - // 根据权限码查询可以访问URL - List powerList = powerMapper.selectListByPowerCodes(powerCodes); - - // 判断是否与请求路径匹配 - return powerList.stream().anyMatch(power -> AntPathRequestMatcher.antMatcher(power.getRequestUrl()).matches(request) || - request.getRequestURI().matches(power.getRequestUrl())); - } -} diff --git a/service/src/main/java/cn/bunny/services/security/service/impl/CustomAuthorizationManagerServiceImpl.java b/service/src/main/java/cn/bunny/services/security/service/impl/CustomAuthorizationManagerServiceImpl.java new file mode 100644 index 0000000..6128c63 --- /dev/null +++ b/service/src/main/java/cn/bunny/services/security/service/impl/CustomAuthorizationManagerServiceImpl.java @@ -0,0 +1,125 @@ +package cn.bunny.services.security.service.impl; + +import cn.bunny.common.service.context.BaseContext; +import cn.bunny.common.service.utils.JwtHelper; +import cn.bunny.common.service.utils.ResponseUtil; +import cn.bunny.dao.entity.system.Power; +import cn.bunny.dao.pojo.constant.RedisUserConstant; +import cn.bunny.dao.pojo.result.Result; +import cn.bunny.dao.pojo.result.ResultCodeEnum; +import cn.bunny.dao.vo.system.user.LoginVo; +import cn.bunny.services.mapper.PowerMapper; +import cn.bunny.services.security.custom.CustomCheckIsAdmin; +import com.alibaba.fastjson2.JSON; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.security.authorization.AuthorizationDecision; +import org.springframework.security.authorization.AuthorizationManager; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.access.intercept.RequestAuthorizationContext; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import java.util.List; +import java.util.function.Supplier; + + +/** + * 自定义权限判断 + * 判断用户有哪些权限 + */ +@Component +@Slf4j +public class CustomAuthorizationManagerServiceImpl implements AuthorizationManager { + + @Autowired + private RedisTemplate redisTemplate; + + @Autowired + private PowerMapper powerMapper; + + @SneakyThrows + @Override + public AuthorizationDecision check(Supplier authentication, RequestAuthorizationContext context) { + // 用户的token和用户id、请求Url + HttpServletRequest request = context.getRequest(); + + // 是否访问的是接口内容 + boolean matches = AntPathRequestMatcher.antMatcher("/admin/**").matches(request); + if (!matches) return new AuthorizationDecision(true); + + if (checkToken(request)) { + return new AuthorizationDecision(true); + } + + // 校验权限 + return new AuthorizationDecision(hasAuth(request)); + } + + private boolean checkToken(HttpServletRequest request) { + HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getResponse(); + if (response == null) return false; + + // 判断是否有 token + String token = request.getHeader("token"); + if (token == null) { + ResponseUtil.out(response, Result.error(ResultCodeEnum.LOGIN_AUTH)); + return false; + } + + // 判断 token 是否过期 + if (JwtHelper.isExpired(token)) { + ResponseUtil.out(response, Result.error(ResultCodeEnum.AUTHENTICATION_EXPIRED)); + return false; + } + + // 查找 Redis + String username = JwtHelper.getUsername(token); + Long userId = JwtHelper.getUserId(token); + Object loginVoObject = redisTemplate.opsForValue().get(RedisUserConstant.getAdminLoginInfoPrefix(username)); + LoginVo loginVo = JSON.parseObject(JSON.toJSONString(loginVoObject), LoginVo.class); + + // 判断用户是否禁用 + if (loginVo != null && loginVo.getStatus()) { + ResponseUtil.out(response, Result.error(ResultCodeEnum.FAIL_NO_ACCESS_DENIED_USER_LOCKED)); + return false; + } + + // 设置用户信息 + BaseContext.setUsername(username); + BaseContext.setUserId(userId); + BaseContext.setLoginVo(loginVo); + return true; + } + + /** + * 查询用户所属的角色信息 + * + * @param request 请求url地址 + */ + private Boolean hasAuth(HttpServletRequest request) { + // 角色代码列表 + LoginVo loginVo = BaseContext.getLoginVo(); + List roleCodeList = loginVo.getRoles(); + + // 判断是否是管理员用户 + boolean checkedAdmin = CustomCheckIsAdmin.checkAdmin(roleCodeList, loginVo); + if (checkedAdmin) return true; + + // 不是 admin,查询角色权限关系表 + List powerCodes = loginVo.getPermissions(); + + // 根据权限码查询可以访问URL + List powerList = powerMapper.selectListByPowerCodes(powerCodes); + + // 判断是否与请求路径匹配 + return powerList.stream().anyMatch(power -> AntPathRequestMatcher.antMatcher(power.getRequestUrl()).matches(request) || + request.getRequestURI().matches(power.getRequestUrl())); + } +} diff --git a/service/src/main/java/cn/bunny/services/security/service/iml/CustomUserDetailsServiceImpl.java b/service/src/main/java/cn/bunny/services/security/service/impl/CustomUserDetailsServiceImpl.java similarity index 78% rename from service/src/main/java/cn/bunny/services/security/service/iml/CustomUserDetailsServiceImpl.java rename to service/src/main/java/cn/bunny/services/security/service/impl/CustomUserDetailsServiceImpl.java index 7d1b84d..49328e7 100644 --- a/service/src/main/java/cn/bunny/services/security/service/iml/CustomUserDetailsServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/security/service/impl/CustomUserDetailsServiceImpl.java @@ -1,9 +1,8 @@ -package cn.bunny.services.security.service.iml; +package cn.bunny.services.security.service.impl; import cn.bunny.common.service.exception.BunnyException; import cn.bunny.dao.dto.system.user.LoginDto; import cn.bunny.dao.entity.system.AdminUser; -import cn.bunny.dao.entity.system.Role; import cn.bunny.dao.pojo.result.ResultCodeEnum; import cn.bunny.dao.vo.system.user.LoginVo; import cn.bunny.services.factory.UserFactory; @@ -11,7 +10,6 @@ import cn.bunny.services.mapper.RoleMapper; import cn.bunny.services.mapper.UserMapper; import cn.bunny.services.security.custom.CustomUser; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import lombok.val; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.userdetails.UserDetails; @@ -19,8 +17,6 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Component; import org.springframework.util.DigestUtils; -import java.util.List; - @Component public class CustomUserDetailsServiceImpl implements cn.bunny.services.security.service.CustomUserDetailsService { @@ -29,24 +25,31 @@ public class CustomUserDetailsServiceImpl implements cn.bunny.services.security. @Autowired private UserFactory userFactory; + @Autowired private RoleMapper roleMapper; + /** + * 根据用户名获取用户对象(获取不到直接抛异常) + * + * @param username 用户名 + */ @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // 查询用户相关内容 - LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper().eq(AdminUser::getEmail, username).or().eq(AdminUser::getUsername, username); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() + .eq(AdminUser::getEmail, username) + .or() + .eq(AdminUser::getUsername, username); // 根据邮箱查询用户名 - val user = userMapper.selectOne(queryWrapper); - if (user == null) throw new UsernameNotFoundException("用户不存在"); + AdminUser adminUser = userMapper.selectOne(queryWrapper); + if (adminUser == null) throw new UsernameNotFoundException("用户不存在"); - // 根据用户id查询当前用户所有角色 - List roleList = roleMapper.selectListByUserId(user.getId()); - List roleCodeList = roleList.stream().map(Role::getRoleCode).toList(); - return new CustomUser(user, AuthorityUtils.createAuthorityList(roleCodeList)); + return new CustomUser(adminUser, AuthorityUtils.createAuthorityList()); } + /** * 前台用户登录接口 * diff --git a/service/src/main/java/cn/bunny/services/service/EmailTemplateService.java b/service/src/main/java/cn/bunny/services/service/EmailTemplateService.java index 1f200f0..f8fcded 100644 --- a/service/src/main/java/cn/bunny/services/service/EmailTemplateService.java +++ b/service/src/main/java/cn/bunny/services/service/EmailTemplateService.java @@ -18,7 +18,7 @@ import java.util.List; *

* * @author Bunny - * @since 2024-10-10 16:28:29 + * @since 2024-10-10 21:24:08 */ public interface EmailTemplateService extends IService { diff --git a/service/src/main/java/cn/bunny/services/service/impl/EmailTemplateServiceImpl.java b/service/src/main/java/cn/bunny/services/service/impl/EmailTemplateServiceImpl.java index f09115b..ef737ff 100644 --- a/service/src/main/java/cn/bunny/services/service/impl/EmailTemplateServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/impl/EmailTemplateServiceImpl.java @@ -23,7 +23,7 @@ import java.util.List; *

* * @author Bunny - * @since 2024-10-10 16:28:29 + * @since 2024-10-10 21:24:08 */ @Service public class EmailTemplateServiceImpl extends ServiceImpl implements EmailTemplateService { diff --git a/service/src/main/java/cn/bunny/services/service/impl/RouterServiceImpl.java b/service/src/main/java/cn/bunny/services/service/impl/RouterServiceImpl.java index 4268e30..e1e4736 100644 --- a/service/src/main/java/cn/bunny/services/service/impl/RouterServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/impl/RouterServiceImpl.java @@ -15,6 +15,7 @@ import cn.bunny.dao.vo.system.router.UserRouterVo; import cn.bunny.dao.vo.system.user.LoginVo; import cn.bunny.services.factory.RouterServiceFactory; import cn.bunny.services.mapper.RouterMapper; +import cn.bunny.services.security.custom.CustomCheckIsAdmin; import cn.bunny.services.service.RouterService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -64,6 +65,7 @@ public class RouterServiceImpl extends ServiceImpl impleme // 角色列表 List roleList = loginVo.getRoles(); + // 权限列表 List powerCodeList = loginVo.getPermissions(); @@ -74,7 +76,7 @@ public class RouterServiceImpl extends ServiceImpl impleme List list = new ArrayList<>(); // 查询用户角色,判断是否是管理员角色 - boolean isAdmin = roleList.stream().anyMatch(authUserRole -> authUserRole.equals("admin")); + boolean isAdmin = CustomCheckIsAdmin.checkAdmin(roleList, loginVo); if (isAdmin) routerList = list(); else { List routerIds = baseMapper.selectListByUserId(loginVo.getId()); diff --git a/service/src/main/resources/application.yml b/service/src/main/resources/application.yml index 33a3b3e..5775377 100644 --- a/service/src/main/resources/application.yml +++ b/service/src/main/resources/application.yml @@ -6,7 +6,7 @@ management: web: exposure: include: "*" - base-path: /bunny + base-path: /actuator info: env: enabled: true @@ -17,6 +17,7 @@ management: endpoint: health: show-details: always + spring: profiles: active: @profiles.active@ @@ -25,7 +26,12 @@ spring: servlet: multipart: max-file-size: 6MB - + boot: + admin: + client: + url: "http://localhost:7070" + username: admin + password: admin datasource: # type: com.zaxxer.hikari.HikariDataSource # driver-class-name: com.mysql.cj.jdbc.Driver @@ -69,6 +75,7 @@ spring: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8 + # rabbitmq: # host: ${bunny.rabbitmq.host} # port: ${bunny.rabbitmq.port} diff --git a/service/src/main/resources/mapper/EmailTemplateMapper.xml b/service/src/main/resources/mapper/EmailTemplateMapper.xml index ebdb6c5..affb546 100644 --- a/service/src/main/resources/mapper/EmailTemplateMapper.xml +++ b/service/src/main/resources/mapper/EmailTemplateMapper.xml @@ -2,11 +2,44 @@ + + + + + + + + + + + + + + + + + + id, create_time, update_time, create_user, update_user, is_deleted, template_name, subject, body, type, is_default + @@ -14,7 +47,7 @@ delete - from $tableName + from sys_email_template where id in #{id}