diff --git a/common/common-utils/pom.xml b/common/common-utils/pom.xml
index 40082a6..09b891c 100644
--- a/common/common-utils/pom.xml
+++ b/common/common-utils/pom.xml
@@ -23,5 +23,10 @@
httpclient
4.5.14
+
+ javax.xml.bind
+ jaxb-api
+ 2.1
+
diff --git a/common/common-utils/src/main/java/cn/bunny/common/utils/JwtHelper.java b/common/common-utils/src/main/java/cn/bunny/common/utils/JwtHelper.java
index f8a792e..de2422e 100644
--- a/common/common-utils/src/main/java/cn/bunny/common/utils/JwtHelper.java
+++ b/common/common-utils/src/main/java/cn/bunny/common/utils/JwtHelper.java
@@ -11,7 +11,7 @@ public class JwtHelper {
public static String createToken(Long userId, String userName) {
return Jwts.builder()
- .setSubject("OA-USER")
+ .setSubject("Bunny-USER")
.setExpiration(new Date(System.currentTimeMillis() + tokenExpiration))
.claim("userId", userId)
.claim("userName", userName)
@@ -27,7 +27,6 @@ public class JwtHelper {
Claims claims = claimsJws.getBody();
Integer userId = (Integer) claims.get("userId");
return userId.longValue();
- // return 1L;
}
public static String getUserName(String token) {
diff --git a/common/service-utils/src/main/java/cn/bunny/common/service/config/WebMvcConfiguration.java b/common/service-utils/src/main/java/cn/bunny/common/service/config/WebMvcConfiguration.java
index f62701b..82f1b5a 100644
--- a/common/service-utils/src/main/java/cn/bunny/common/service/config/WebMvcConfiguration.java
+++ b/common/service-utils/src/main/java/cn/bunny/common/service/config/WebMvcConfiguration.java
@@ -3,6 +3,7 @@ package cn.bunny.common.service.config;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@@ -17,4 +18,18 @@ public class WebMvcConfiguration implements WebMvcConfigurer {
registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
+
+ /**
+ * 跨域配置
+ *
+ * @param registry 跨域注册表
+ */
+ @Override
+ public void addCorsMappings(CorsRegistry registry) {
+ registry.addMapping("/**")
+ // 是否发送Cookies
+ .allowCredentials(true)
+ // 放行哪些原始域
+ .allowedOriginPatterns("*").allowedMethods("GET", "POST", "PUT", "DELETE").allowedHeaders("*").exposedHeaders("*");
+ }
}
diff --git a/common/service-utils/src/main/java/cn/bunny/common/service/context/BaseContext.java b/common/service-utils/src/main/java/cn/bunny/common/service/context/BaseContext.java
index 26ad7fb..2910d37 100644
--- a/common/service-utils/src/main/java/cn/bunny/common/service/context/BaseContext.java
+++ b/common/service-utils/src/main/java/cn/bunny/common/service/context/BaseContext.java
@@ -2,6 +2,7 @@ package cn.bunny.common.service.context;
public class BaseContext {
private static final ThreadLocal userId = new ThreadLocal<>();
+ private static final ThreadLocal username = new ThreadLocal();
private static final ThreadLocal wareId = new ThreadLocal<>();
private static final ThreadLocal adminId = new ThreadLocal<>();
@@ -18,6 +19,14 @@ public class BaseContext {
userId.remove();
}
+ public static String getUsername() {
+ return username.get();
+ }
+
+ public static void setUsername(String _username) {
+ username.set(_username);
+ }
+
// adminId 相关
public static Long getAdminId() {
return adminId.get();
diff --git a/common/spring-security/src/main/java/cn/bunny/security/config/WebSecurityConfig.java b/common/spring-security/src/main/java/cn/bunny/security/config/WebSecurityConfig.java
index 5c70d0b..d589e84 100644
--- a/common/spring-security/src/main/java/cn/bunny/security/config/WebSecurityConfig.java
+++ b/common/spring-security/src/main/java/cn/bunny/security/config/WebSecurityConfig.java
@@ -1,14 +1,17 @@
package cn.bunny.security.config;
import cn.bunny.security.custom.CustomPasswordEncoder;
-import cn.bunny.security.handelr.*;
+import cn.bunny.security.filter.TokenAuthenticationFilter;
+import cn.bunny.security.handelr.SecurityAccessDeniedHandler;
+import cn.bunny.security.handelr.SecurityAuthenticationEntryPoint;
import cn.bunny.security.service.MyUserDetailsService;
+import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.authentication.ProviderManager;
+import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
@@ -19,8 +22,7 @@ import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.web.SecurityFilterChain;
-
-import static org.springframework.security.config.Customizer.withDefaults;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
@@ -32,62 +34,52 @@ public class WebSecurityConfig {
private MyUserDetailsService myUserDetailsService;
@Autowired
private CustomPasswordEncoder customPasswordEncoder;
- @Autowired
- private AuthenticationConfiguration authenticationConfiguration;
@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeHttpRequests(authorize -> {
- authorize.requestMatchers("/", "/test/**", "/diagram-viewer/**", "/editor-app/**", "/*.html",
- "/admin/system/index/login",
- "/favicon.ico", "/swagger-resources/**", "/webjars/**", "/v3/**", "/swagger-ui.html/**", "/doc.html").permitAll().anyRequest().authenticated();
- });
-
- // 注销登录
- httpSecurity
- .logout(logout -> {
- logout.logoutSuccessHandler(new SecurityLogoutSuccessHandler());
+ authorize.requestMatchers("/", "/test/**", "/diagram-viewer/**", "/editor-app/**", "/*.html", "/admin/system/index/login",
+ "/favicon.ico", "/swagger-resources/**", "/webjars/**", "/v3/**", "/swagger-ui.html/**", "/doc.html").permitAll().anyRequest().authenticated();
})
+ // 前端段分离不需要---禁用明文验证
+ .httpBasic(AbstractHttpConfigurer::disable)
+ // 前端段分离不需要---禁用默认登录页
+ .formLogin(AbstractHttpConfigurer::disable)
+ // 前端段分离不需要---禁用退出页
+ .logout(AbstractHttpConfigurer::disable)
+ // 前端段分离不需要---csrf攻击
+ .csrf(AbstractHttpConfigurer::disable)
+ // 跨域访问权限
+ .cors(AbstractHttpConfigurer::disable)
+ // 前后端分离不需要---因为是无状态的
+ .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.exceptionHandling(exception -> {
// 请求未授权接口
exception.authenticationEntryPoint(new SecurityAuthenticationEntryPoint());
// 没有权限访问
exception.accessDeniedHandler(new SecurityAccessDeniedHandler());
})
- // 后登录的账号会使先登录的账号失效
- .sessionManagement(session -> {
- // 禁用session
- session.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
- // 最大登录数为1
- session.maximumSessions(1)
- // 可以获取到所有登录的用户,以及登录状态,设置session状态
- .sessionRegistry(sessionRegistry())
- // 有相同用户已登录时
- .expiredSessionStrategy(new SecuritySessionInformationExpiredStrategy());
- // 会话失效,同时内容
- session.invalidSessionStrategy(new SecurityInvalidSessionStrategy());
- });
- // 关闭csrf攻击
- httpSecurity.csrf(AbstractHttpConfigurer::disable);
- // 跨域访问权限
- httpSecurity.cors(withDefaults());
- // 记住我
- httpSecurity.rememberMe(e -> e.rememberMeParameter("rememberBunny").rememberMeCookieName("rememberBunny").key("BunnyKey"));
- // 自定义过滤器
- // httpSecurity.addFilterAt(loginFilter(), UsernamePasswordAuthenticationFilter.class);
- // httpSecurity.addFilterBefore(new TokenAuthenticationFilter(redisTemplate), UsernamePasswordAuthenticationFilter.class);
- // httpSecurity.addFilter(new TokenLoginFilter(authenticationConfiguration, redisTemplate));
+ // 记住我
+ .rememberMe(e -> e.rememberMeParameter("rememberBunny").rememberMeCookieName("rememberBunny").key("BunnyKey"))
+ // 自定义过滤器
+ // .addFilterAt(TokenLoginFilter(), UsernamePasswordAuthenticationFilter.class)
+ // .addFilter(new TokenLoginFilter(redisTemplate))
+ .addFilterBefore(new TokenAuthenticationFilter(redisTemplate), UsernamePasswordAuthenticationFilter.class);
return httpSecurity.build();
}
- // 自定义用户认证和密码
@Bean
- public AuthenticationManager authenticationManager() {
+ public AuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setPasswordEncoder(customPasswordEncoder);
provider.setUserDetailsService(myUserDetailsService);
- return new ProviderManager(provider);
+ return provider;
+ }
+
+ @Bean
+ public AuthenticationManager authenticationManager(@NotNull AuthenticationConfiguration config) throws Exception {
+ return config.getAuthenticationManager();
}
@Bean
diff --git a/common/spring-security/src/main/java/cn/bunny/security/custom/CustomAuthorizationManager.java b/common/spring-security/src/main/java/cn/bunny/security/custom/CustomAuthorizationManager.java
index 8c088f2..7e09fb9 100644
--- a/common/spring-security/src/main/java/cn/bunny/security/custom/CustomAuthorizationManager.java
+++ b/common/spring-security/src/main/java/cn/bunny/security/custom/CustomAuthorizationManager.java
@@ -14,6 +14,7 @@ import java.util.function.Supplier;
public class CustomAuthorizationManager implements AuthorizationManager {
@Override
public AuthorizationDecision check(Supplier authentication, RequestAuthorizationContext object) {
+ String token = object.getRequest().getHeader("token");
return null;
}
}
diff --git a/common/spring-security/src/main/java/cn/bunny/security/filter/TokenAuthenticationFilter.java b/common/spring-security/src/main/java/cn/bunny/security/filter/TokenAuthenticationFilter.java
index 2ac9138..bc7511e 100644
--- a/common/spring-security/src/main/java/cn/bunny/security/filter/TokenAuthenticationFilter.java
+++ b/common/spring-security/src/main/java/cn/bunny/security/filter/TokenAuthenticationFilter.java
@@ -1,13 +1,13 @@
package cn.bunny.security.filter;
-import cn.bunny.common.result.Result;
-import cn.bunny.common.utils.ResponseUtil;
-import cn.bunny.enums.ResultCodeEnum;
+import cn.bunny.common.service.context.BaseContext;
+import cn.bunny.common.utils.JwtHelper;
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.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
@@ -28,40 +28,46 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter {
}
@Override
- protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
- // 如果是登录接口,直接放行
- if ("/admin/system/index/login".equals(request.getRequestURI())) {
- chain.doFilter(request, response);
+ protected void doFilterInternal(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain chain) throws ServletException, IOException {
+ String token = request.getHeader("token");
+
+ // login请求就没token,直接放行,因为后边有其他的过滤器
+ if (token == null) {
+ doFilter(request, response, chain);
return;
}
+ // 如果是登录接口,直接放行
UsernamePasswordAuthenticationToken authentication = getAuthentication(request);
-
- if (authentication != null) {
- SecurityContextHolder.getContext().setAuthentication(authentication);
- chain.doFilter(request, response);
- } else {
- ResponseUtil.out(response, Result.error(ResultCodeEnum.LOGIN_MOBLE_ERROR));
- }
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+ chain.doFilter(request, response);
}
private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
- // 请求头是否有Token
+ // 请求头是否有token
String token = request.getHeader("token");
- if (!StringUtils.hasText(token)) {
- Object authObject = redisTemplate.opsForValue().get(token);
- String authString = JSON.toJSONString(authObject);
- if (StringUtils.hasText(authString)) {
- List