diff --git a/dao/pom.xml b/dao/pom.xml index 41ebece..1737d03 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -23,6 +23,11 @@ org.projectlombok lombok + + + org.springframework.boot + spring-boot-starter-security + com.baomidou diff --git a/dao/src/main/java/cn/bunny/dao/entity/system/AdminUser.java b/dao/src/main/java/cn/bunny/dao/entity/system/AdminUser.java index 8773b07..ae9358b 100644 --- a/dao/src/main/java/cn/bunny/dao/entity/system/AdminUser.java +++ b/dao/src/main/java/cn/bunny/dao/entity/system/AdminUser.java @@ -6,6 +6,11 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Collection; +import java.util.List; /** *

@@ -20,7 +25,7 @@ import lombok.experimental.Accessors; @Accessors(chain = true) @TableName("sys_user") @Schema(name = "AdminUser对象", title = "用户信息", description = "用户信息") -public class AdminUser extends BaseEntity { +public class AdminUser extends BaseEntity implements UserDetails { @Schema(name = "username", title = "用户名") private String username; @@ -55,5 +60,9 @@ public class AdminUser extends BaseEntity { @Schema(name = "status", title = "状态", description = "1:禁用 0:正常") private Boolean status; + @Override + public Collection getAuthorities() { + return List.of(); + } } 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 032c471..126af86 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,11 +1,11 @@ package cn.bunny.services.security.config; import cn.bunny.services.security.custom.CustomPasswordEncoder; +import cn.bunny.services.security.custom.service.CustomUserDetailsService; +import cn.bunny.services.security.custom.service.impl.CustomAuthorizationManagerServiceImpl; 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.impl.CustomAuthorizationManagerServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; 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 deleted file mode 100644 index 4650302..0000000 --- a/service/src/main/java/cn/bunny/services/security/custom/CustomCheckIsAdmin.java +++ /dev/null @@ -1,51 +0,0 @@ -package cn.bunny.services.security.custom; - -import cn.bunny.common.service.context.BaseContext; -import cn.bunny.dao.entity.system.AdminUser; - -import java.util.List; - -/** - * 检查是否是管理员 - */ -public class CustomCheckIsAdmin { - - /** - * 判断是否是管理员 - * - * @param roleList 角色代码列表 - * @return 是否是管理员 - */ - public static boolean checkAdmin(List roleList) { - // 判断是否是超级管理员 - if (BaseContext.getUserId().equals(1L)) return true; - - // 判断是否是 admin - return roleList.stream().anyMatch(role -> role.equals("admin")); - } - - /** - * 判断是否是管理员 - * - * @param roleList 角色代码列表 - * @param permissions 权限列表 - * @param adminUser 用户信息 - * @return 是否是管理员 - */ - 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 deleted file mode 100644 index 5ac7e96..0000000 --- a/service/src/main/java/cn/bunny/services/security/custom/CustomUser.java +++ /dev/null @@ -1,23 +0,0 @@ -package cn.bunny.services.security.custom; - -import cn.bunny.dao.entity.system.AdminUser; -import lombok.Getter; -import lombok.Setter; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.userdetails.User; - -import java.util.Collection; - -/** - * 重写自带的User - */ -@Getter -@Setter -public class CustomUser extends User { - private AdminUser user; - - public CustomUser(AdminUser user, Collection 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/service/CustomUserDetailsService.java b/service/src/main/java/cn/bunny/services/security/custom/service/CustomUserDetailsService.java similarity index 94% rename from service/src/main/java/cn/bunny/services/security/service/CustomUserDetailsService.java rename to service/src/main/java/cn/bunny/services/security/custom/service/CustomUserDetailsService.java index af8f6d0..59a691e 100644 --- a/service/src/main/java/cn/bunny/services/security/service/CustomUserDetailsService.java +++ b/service/src/main/java/cn/bunny/services/security/custom/service/CustomUserDetailsService.java @@ -1,4 +1,4 @@ -package cn.bunny.services.security.service; +package cn.bunny.services.security.custom.service; import cn.bunny.dao.dto.system.user.LoginDto; import cn.bunny.dao.vo.system.user.LoginVo; diff --git a/service/src/main/java/cn/bunny/services/security/service/impl/CustomAuthorizationManagerServiceImpl.java b/service/src/main/java/cn/bunny/services/security/custom/service/impl/CustomAuthorizationManagerServiceImpl.java similarity index 96% rename from service/src/main/java/cn/bunny/services/security/service/impl/CustomAuthorizationManagerServiceImpl.java rename to service/src/main/java/cn/bunny/services/security/custom/service/impl/CustomAuthorizationManagerServiceImpl.java index cd71340..b46fbe9 100644 --- a/service/src/main/java/cn/bunny/services/security/service/impl/CustomAuthorizationManagerServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/security/custom/service/impl/CustomAuthorizationManagerServiceImpl.java @@ -1,4 +1,4 @@ -package cn.bunny.services.security.service.impl; +package cn.bunny.services.security.custom.service.impl; import cn.bunny.common.service.context.BaseContext; import cn.bunny.common.service.utils.JwtHelper; @@ -10,7 +10,7 @@ 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.CustomAuthenticationException; -import cn.bunny.services.security.custom.CustomCheckIsAdmin; +import cn.bunny.services.utils.RoleUtil; import com.alibaba.fastjson2.JSON; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; @@ -103,7 +103,7 @@ public class CustomAuthorizationManagerServiceImpl implements AuthorizationManag List roleCodeList = roleList.stream().map(Role::getRoleCode).toList(); // 判断是否是管理员用户 - boolean checkedAdmin = CustomCheckIsAdmin.checkAdmin(roleCodeList); + boolean checkedAdmin = RoleUtil.checkAdmin(roleCodeList); if (checkedAdmin) return true; // 判断请求地址是否是 noManage 不需要被验证的 diff --git a/service/src/main/java/cn/bunny/services/security/service/impl/CustomUserDetailsServiceImpl.java b/service/src/main/java/cn/bunny/services/security/custom/service/impl/CustomUserDetailsServiceImpl.java similarity index 91% rename from service/src/main/java/cn/bunny/services/security/service/impl/CustomUserDetailsServiceImpl.java rename to service/src/main/java/cn/bunny/services/security/custom/service/impl/CustomUserDetailsServiceImpl.java index cf9e9bf..48b294e 100644 --- a/service/src/main/java/cn/bunny/services/security/service/impl/CustomUserDetailsServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/security/custom/service/impl/CustomUserDetailsServiceImpl.java @@ -1,4 +1,4 @@ -package cn.bunny.services.security.service.impl; +package cn.bunny.services.security.custom.service.impl; import cn.bunny.common.service.exception.AuthCustomerException; import cn.bunny.dao.dto.system.user.LoginDto; @@ -8,7 +8,7 @@ import cn.bunny.dao.vo.result.Result; import cn.bunny.dao.vo.result.ResultCodeEnum; import cn.bunny.dao.vo.system.user.LoginVo; import cn.bunny.services.mapper.UserMapper; -import cn.bunny.services.security.custom.CustomUser; +import cn.bunny.services.security.custom.service.CustomUserDetailsService; import cn.bunny.services.utils.UserUtil; import cn.bunny.services.utils.login.DefaultLoginStrategy; import cn.bunny.services.utils.login.EmailLoginStrategy; @@ -18,7 +18,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Component; @@ -30,7 +29,7 @@ import java.util.HashMap; import static cn.bunny.common.service.utils.ResponseUtil.out; @Component -public class CustomUserDetailsServiceImpl implements cn.bunny.services.security.service.CustomUserDetailsService { +public class CustomUserDetailsServiceImpl implements CustomUserDetailsService { @Autowired private RedisTemplate redisTemplate; @@ -58,7 +57,8 @@ public class CustomUserDetailsServiceImpl implements cn.bunny.services.security. AdminUser adminUser = userMapper.selectOne(queryWrapper); if (adminUser == null) throw new UsernameNotFoundException(ResultCodeEnum.USER_IS_EMPTY.getMessage()); - return new CustomUser(adminUser, AuthorityUtils.createAuthorityList()); + // return new CustomUser(adminUser, AuthorityUtils.createAuthorityList()); + return adminUser; } /** diff --git a/service/src/main/java/cn/bunny/services/security/filter/TokenLoginFilterService.java b/service/src/main/java/cn/bunny/services/security/filter/TokenLoginFilterService.java index a004874..39fc9ab 100644 --- a/service/src/main/java/cn/bunny/services/security/filter/TokenLoginFilterService.java +++ b/service/src/main/java/cn/bunny/services/security/filter/TokenLoginFilterService.java @@ -6,9 +6,9 @@ import cn.bunny.dao.enums.LoginEnums; import cn.bunny.dao.vo.result.Result; import cn.bunny.dao.vo.result.ResultCodeEnum; import cn.bunny.dao.vo.system.user.LoginVo; +import cn.bunny.services.security.custom.service.CustomUserDetailsService; import cn.bunny.services.security.handelr.SecurityAuthenticationFailureHandler; import cn.bunny.services.security.handelr.SecurityAuthenticationSuccessHandler; -import cn.bunny.services.security.service.CustomUserDetailsService; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.servlet.FilterChain; import jakarta.servlet.http.HttpServletRequest; @@ -27,8 +27,8 @@ import java.io.IOException; import static cn.bunny.common.service.utils.ResponseUtil.out; /** - * * UsernamePasswordAuthenticationFilter - * * 也可以在这里添加验证码、短信等的验证 + * UsernamePasswordAuthenticationFilter + * 也可以在这里添加验证码、短信等的验证 * 由于SpringSecurity的登录只能是表单形式 并且用户名密码需要时username、password,可以通过继承 UsernamePasswordAuthenticationFilter 获取登录请求的参数 * 再去设置到 UsernamePasswordAuthenticationToken 中 来改变请求传参方式、参数名等 或者也可以在登录的时候加入其他参数等等 */ diff --git a/service/src/main/java/cn/bunny/services/security/handelr/SecurityAccessDeniedHandler.java b/service/src/main/java/cn/bunny/services/security/handelr/SecurityAccessDeniedHandler.java index d8707ff..fca61aa 100644 --- a/service/src/main/java/cn/bunny/services/security/handelr/SecurityAccessDeniedHandler.java +++ b/service/src/main/java/cn/bunny/services/security/handelr/SecurityAccessDeniedHandler.java @@ -7,11 +7,12 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.SneakyThrows; import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.web.access.AccessDeniedHandler; /** * 没有权限访问 */ -public class SecurityAccessDeniedHandler implements org.springframework.security.web.access.AccessDeniedHandler { +public class SecurityAccessDeniedHandler implements AccessDeniedHandler { @SneakyThrows @Override public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) { diff --git a/service/src/main/java/cn/bunny/services/security/handelr/SecurityAuthenticationFailureHandler.java b/service/src/main/java/cn/bunny/services/security/handelr/SecurityAuthenticationFailureHandler.java index 75f8942..65c0b67 100644 --- a/service/src/main/java/cn/bunny/services/security/handelr/SecurityAuthenticationFailureHandler.java +++ b/service/src/main/java/cn/bunny/services/security/handelr/SecurityAuthenticationFailureHandler.java @@ -5,10 +5,11 @@ import com.alibaba.fastjson2.JSON; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.AuthenticationFailureHandler; import java.io.IOException; -public class SecurityAuthenticationFailureHandler implements org.springframework.security.web.authentication.AuthenticationFailureHandler { +public class SecurityAuthenticationFailureHandler implements AuthenticationFailureHandler { @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException { // 错误消息 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 1cc5211..ce47750 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 @@ -19,8 +19,8 @@ import cn.bunny.services.mapper.RoleMapper; import cn.bunny.services.mapper.RolePowerMapper; import cn.bunny.services.mapper.RouterMapper; import cn.bunny.services.mapper.RouterRoleMapper; -import cn.bunny.services.security.custom.CustomCheckIsAdmin; import cn.bunny.services.service.RouterService; +import cn.bunny.services.utils.RoleUtil; import cn.bunny.services.utils.RouterServiceUtil; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; @@ -84,7 +84,7 @@ public class RouterServiceImpl extends ServiceImpl impleme List list = new ArrayList<>(); // 查询用户角色,判断是否是管理员角色 - boolean isAdmin = CustomCheckIsAdmin.checkAdmin(userRoleCodeList); + boolean isAdmin = RoleUtil.checkAdmin(userRoleCodeList); // 查询路由和角色对应关系 List routerRoleList = routerRoleMapper.viewRouterRolesWithAll(); diff --git a/service/src/main/java/cn/bunny/services/utils/RoleUtil.java b/service/src/main/java/cn/bunny/services/utils/RoleUtil.java index 67e8f88..78e373f 100644 --- a/service/src/main/java/cn/bunny/services/utils/RoleUtil.java +++ b/service/src/main/java/cn/bunny/services/utils/RoleUtil.java @@ -1,5 +1,6 @@ package cn.bunny.services.utils; +import cn.bunny.common.service.context.BaseContext; import cn.bunny.dao.constant.RedisUserConstant; import cn.bunny.dao.entity.system.AdminUser; import cn.bunny.services.mapper.UserMapper; @@ -22,6 +23,45 @@ public class RoleUtil { @Autowired private UserUtil userUtil; + /** + * 判断是否是管理员 + * + * @param roleList 角色代码列表 + * @param permissions 权限列表 + * @param adminUser 用户信息 + * @return 是否是管理员 + */ + 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; + } + + /** + * 判断是否是管理员 + * + * @param roleList 角色代码列表 + * @return 是否是管理员 + */ + public static boolean checkAdmin(List roleList) { + // 判断是否是超级管理员 + if (BaseContext.getUserId().equals(1L)) return true; + + // 判断是否是 admin + return roleList.stream().anyMatch(role -> role.equals("admin")); + } + /** * 批量更新Redis中用户信息 * diff --git a/service/src/main/java/cn/bunny/services/utils/UserUtil.java b/service/src/main/java/cn/bunny/services/utils/UserUtil.java index cc83660..849388a 100644 --- a/service/src/main/java/cn/bunny/services/utils/UserUtil.java +++ b/service/src/main/java/cn/bunny/services/utils/UserUtil.java @@ -16,7 +16,6 @@ import cn.bunny.services.mapper.PowerMapper; import cn.bunny.services.mapper.RoleMapper; import cn.bunny.services.mapper.UserLoginLogMapper; import cn.bunny.services.mapper.UserMapper; -import cn.bunny.services.security.custom.CustomCheckIsAdmin; import jakarta.servlet.http.HttpServletRequest; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -132,7 +131,7 @@ public class UserUtil { List permissions = new ArrayList<>(); // 判断是否是 admin 如果是admin 赋予所有权限 - boolean isAdmin = CustomCheckIsAdmin.checkAdmin(roles, permissions, user); + boolean isAdmin = RoleUtil.checkAdmin(roles, permissions, user); if (!isAdmin) { permissions = powerMapper.selectListByUserId(userId).stream().map(Power::getPowerCode).toList(); }