fix: 修改部分bug和缺陷

This commit is contained in:
Bunny 2024-11-09 02:06:29 +08:00
parent 65685d6cd9
commit 151a2027ae
9 changed files with 73 additions and 152 deletions

1
.gitignore vendored
View File

@ -15,6 +15,7 @@ logs/
.springBeans
.sts4-cache
application-prod.yml
### IntelliJ IDEA ###
.idea

View File

@ -1,3 +1,11 @@
# 感谢
项目由[小铭](https://github.com/xiaoxian521)开源权限模板[Pure-admin](https://pure-admin.github.io/vue-pure-admin/)
Pure-admin文档https://pure-admin.github.io/pure-admin-doc
项目整体都由此模板开发
# 项目预览
不知道为什么图床用的使自己的Gitee就是不显示其它GitHub和Gitea都能显示就Gitee显示不出来如果想用Gitee就把ReadMe文件下载下来也行或者把项目clone下来看也可以

View File

@ -3,11 +3,11 @@ package cn.bunny.common.generator.generator;
import cn.bunny.common.generator.entity.BaseField;
import cn.bunny.common.generator.entity.BaseResultMap;
import cn.bunny.common.generator.utils.GeneratorCodeUtils;
import cn.bunny.dao.dto.financial.category.CategoryAddDto;
import cn.bunny.dao.dto.financial.category.CategoryDto;
import cn.bunny.dao.dto.financial.category.CategoryUpdateDto;
import cn.bunny.dao.entity.financial.Category;
import cn.bunny.dao.vo.financial.CategoryVo;
import cn.bunny.dao.dto.system.user.AdminUserAddDto;
import cn.bunny.dao.dto.system.user.AdminUserDto;
import cn.bunny.dao.dto.system.user.AdminUserUpdateDto;
import cn.bunny.dao.entity.system.AdminUser;
import cn.bunny.dao.vo.system.user.AdminUserVo;
import com.baomidou.mybatisplus.annotation.TableName;
import com.google.common.base.CaseFormat;
import io.swagger.v3.oas.annotations.media.Schema;
@ -52,11 +52,11 @@ public class WebGeneratorCode {
public static String resourceMapperPath = "D:\\MyFolder\\financial\\financial-server\\service\\src\\main\\resources\\mapper\\financial\\";
public static void main(String[] args) throws Exception {
Class<?> originalClass = Category.class;
Class<?> dtoClass = CategoryDto.class;
Class<?> addDtoClass = CategoryAddDto.class;
Class<?> updateDtoClass = CategoryUpdateDto.class;
Class<?> voClass = CategoryVo.class;
Class<?> originalClass = AdminUser.class;
Class<?> dtoClass = AdminUserDto.class;
Class<?> addDtoClass = AdminUserAddDto.class;
Class<?> updateDtoClass = AdminUserUpdateDto.class;
Class<?> voClass = AdminUserVo.class;
// 设置velocity资源加载器
Properties prop = new Properties();

View File

@ -27,7 +27,7 @@ ENTRYPOINT ["java","-jar","/home/server/app.jar"]
#暴露 8000 端口
EXPOSE 8000
# 开发环境
# 生产环境
# mvn clean package -Pprod -DskipTests
# 测试环境

View File

@ -1,8 +1,6 @@
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;
@ -16,7 +14,6 @@ import org.springframework.security.config.annotation.authentication.configurati
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.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@ -43,6 +40,12 @@ public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
String[] annotations = {
"/", "/ws/**",
"/*/*/noAuth/**", "/*/noAuth/**", "/noAuth/**",
"/media.ico", "/favicon.ico", "*.html", "/webjars/**", "/v3/api-docs/**", "swagger-ui/**",
"/error", "/*/i18n/getI18n",
};
httpSecurity
// 前端段分离不需要---禁用明文验证
.httpBasic(AbstractHttpConfigurer::disable)
@ -56,9 +59,11 @@ public class WebSecurityConfig {
.cors(AbstractHttpConfigurer::disable)
// 前后端分离不需要---因为是无状态的
.sessionManagement(AbstractHttpConfigurer::disable)
// 前后端分离不需要---记住我e -> e.rememberMeParameter("rememberBunny").rememberMeCookieName("rememberBunny").key("BunnyKey")
// 前后端分离不需要---记住我
.rememberMe(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(authorize -> authorize.anyRequest().access(customAuthorizationManagerService))
.authorizeHttpRequests(authorize -> authorize.requestMatchers(annotations).permitAll()
.requestMatchers(RegexRequestMatcher.regexMatcher(".*\\.(css|js)$")).permitAll()
.anyRequest().access(customAuthorizationManagerService))
.exceptionHandling(exception -> {
// 请求未授权接口
exception.authenticationEntryPoint(new SecurityAuthenticationEntryPoint());
@ -67,25 +72,9 @@ public class WebSecurityConfig {
})
// 登录验证过滤器
.addFilterBefore(new TokenLoginFilterService(authenticationConfiguration, redisTemplate, customUserDetailsService), UsernamePasswordAuthenticationFilter.class)
// 其它权限鉴权过滤器
.addFilterAt(new NoTokenAuthenticationFilter(redisTemplate), UsernamePasswordAuthenticationFilter.class)
.addFilterAt(new TokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
// 自定义密码加密器和用户登录
.passwordManagement(customPasswordEncoder).userDetailsService(customUserDetailsService);
return httpSecurity.build();
}
// 排出鉴定路径
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
String[] annotations = {
"/", "/ws/**",
"/*/*/noAuth/**", "/*/noAuth/**", "/noAuth/**",
"/media.ico", "/favicon.ico", "*.html", "/webjars/**", "/v3/api-docs/**", "swagger-ui/**",
"/error", "/*/i18n/getI18n",
};
return web -> web.ignoring().requestMatchers(annotations)
.requestMatchers(RegexRequestMatcher.regexMatcher(".*\\.(css|js)$"));
}
}

View File

@ -1,72 +0,0 @@
package cn.bunny.services.security.filter;
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.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 com.alibaba.fastjson2.JSON;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
public class NoTokenAuthenticationFilter extends OncePerRequestFilter {
private final RedisTemplate<String, Object> redisTemplate;
public NoTokenAuthenticationFilter(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
@Override
protected void doFilterInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain) throws ServletException, IOException {
// 判断是否有 token
String token = request.getHeader("token");
if (token == null) {
ResponseUtil.out(response, Result.error(ResultCodeEnum.LOGIN_AUTH));
return;
}
// 判断 token 是否过期
if (JwtHelper.isExpired(token)) {
ResponseUtil.out(response, Result.error(ResultCodeEnum.AUTHENTICATION_EXPIRED));
return;
}
// 解析JWT中的用户名
String username = JwtHelper.getUsername(token);
Long userId = JwtHelper.getUserId(token);
// 查找 Redis
Object loginVoObject = redisTemplate.opsForValue().get(RedisUserConstant.getAdminLoginInfoPrefix(username));
LoginVo loginVo = JSON.parseObject(JSON.toJSONString(loginVoObject), LoginVo.class);
// 登录信息为空
if (loginVo == null) {
ResponseUtil.out(response, Result.error(ResultCodeEnum.LOGIN_AUTH));
return;
}
// 判断用户是否禁用
if (loginVo.getStatus()) {
ResponseUtil.out(response, Result.error(ResultCodeEnum.FAIL_NO_ACCESS_DENIED_USER_LOCKED));
return;
}
// 设置用户信息
BaseContext.setUsername(username);
BaseContext.setUserId(userId);
BaseContext.setLoginVo(loginVo);
// 执行下一个过滤器
doFilter(request, response, filterChain);
}
}

View File

@ -1,47 +0,0 @@
package cn.bunny.services.security.filter;
import cn.bunny.common.service.context.BaseContext;
import cn.bunny.dao.vo.system.user.LoginVo;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.jetbrains.annotations.NotNull;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class TokenAuthenticationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
// 自定义实现内容
UsernamePasswordAuthenticationToken authentication = getAuthentication();
SecurityContextHolder.getContext().setAuthentication(authentication);
chain.doFilter(request, response);
}
/**
* 用户请求判断
*
* @return 验证码方法
*/
private UsernamePasswordAuthenticationToken getAuthentication() {
// 请求头是否有token
LoginVo loginVo = BaseContext.getLoginVo();
String username = loginVo.getUsername();
List<String> roleList = loginVo.getRoles();
// 角色列表
List<SimpleGrantedAuthority> authList = roleList.stream().map(SimpleGrantedAuthority::new).toList();
if (authList.isEmpty()) return new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>());
return new UsernamePasswordAuthenticationToken(username, null, authList);
}
}

View File

@ -16,7 +16,7 @@ import org.springframework.security.web.AuthenticationEntryPoint;
public class SecurityAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) {
String token = response.getHeader("token");
String token = request.getHeader("token");
String message = authException.getMessage();
// 创建结果对象
Result<Object> result;

View File

@ -1,15 +1,20 @@
package cn.bunny.services.security.service.impl;
import cn.bunny.common.service.context.BaseContext;
import cn.bunny.common.service.utils.JwtHelper;
import cn.bunny.dao.entity.system.Power;
import cn.bunny.dao.entity.system.Role;
import cn.bunny.dao.pojo.constant.RedisUserConstant;
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 com.alibaba.fastjson2.JSON;
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;
@ -36,12 +41,49 @@ public class CustomAuthorizationManagerServiceImpl implements AuthorizationManag
@Autowired
private RoleMapper roleMapper;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@SneakyThrows
@Override
public AuthorizationDecision check(Supplier<Authentication> authentication, RequestAuthorizationContext context) {
// 用户的token和用户id请求Url
HttpServletRequest request = context.getRequest();
// 判断是否有 token
String token = request.getHeader("token");
if (token == null) {
return new AuthorizationDecision(false);
}
// 判断 token 是否过期
if (JwtHelper.isExpired(token)) {
return new AuthorizationDecision(false);
}
// 解析JWT中的用户名
String username = JwtHelper.getUsername(token);
Long userId = JwtHelper.getUserId(token);
// 查找 Redis
Object loginVoObject = redisTemplate.opsForValue().get(RedisUserConstant.getAdminLoginInfoPrefix(username));
LoginVo loginVo = JSON.parseObject(JSON.toJSONString(loginVoObject), LoginVo.class);
// 登录信息为空
if (loginVo == null) {
return new AuthorizationDecision(false);
}
// 判断用户是否禁用
if (loginVo.getStatus()) {
return new AuthorizationDecision(false);
}
// 设置用户信息
BaseContext.setUsername(username);
BaseContext.setUserId(userId);
BaseContext.setLoginVo(loginVo);
// 校验权限
return new AuthorizationDecision(hasAuth(request));
}