接口对接

This commit is contained in:
wangjianhong
2025-07-17 09:24:08 +08:00
parent ca7bf71474
commit 144fa79201
4 changed files with 27 additions and 16 deletions

View File

@@ -1,7 +1,6 @@
package com.arrokoth.standalone.authorization.config; package com.arrokoth.standalone.authorization.config;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
@@ -20,22 +19,22 @@ public class CorsConfig {
/** /**
* 默认允许的跨域源Origin所有域名都允许访问。 * 默认允许的跨域源Origin所有域名都允许访问。
*/ */
private static final String DEFAULT_ALLOWED_ORIGINS = "*"; public static final String DEFAULT_ALLOWED_ORIGINS = "*";
/** /**
* 默认允许的请求头Headers接受所有类型的请求头。 * 默认允许的请求头Headers接受所有类型的请求头。
*/ */
private static final String DEFAULT_ALLOWED_HEADERS = "*"; public static final String DEFAULT_ALLOWED_HEADERS = "*";
/** /**
* 默认允许的 HTTP 方法:包括 OPTIONS, HEAD, GET, POST, PUT, DELETE, PATCH。 * 默认允许的 HTTP 方法:包括 OPTIONS, HEAD, GET, POST, PUT, DELETE, PATCH。
*/ */
private static final String DEFAULT_ALLOWED_METHODS = "OPTIONS,HEAD,GET,POST,PUT,DELETE,PATCH"; public static final String DEFAULT_ALLOWED_METHODS = "OPTIONS,HEAD,GET,POST,PUT,DELETE,PATCH";
/** /**
* 预检请求preflight的最大缓存时间单位默认为 3600 秒1 小时)。 * 预检请求preflight的最大缓存时间单位默认为 3600 秒1 小时)。
*/ */
private static final String DEFAULT_MAX_AGE = "3600"; public static final String DEFAULT_MAX_AGE = "3600";
/** /**
* 构建并返回一个 CORS 配置对象。 * 构建并返回一个 CORS 配置对象。
@@ -62,7 +61,7 @@ public class CorsConfig {
* *
* @return CorsFilter 实例 * @return CorsFilter 实例
*/ */
@Bean // @Bean
public CorsFilter corsFilter() { public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig()); // 对所有路径启用 CORS 配置 source.registerCorsConfiguration("/**", buildConfig()); // 对所有路径启用 CORS 配置

View File

@@ -20,7 +20,6 @@ import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource; import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import java.util.Arrays;
import java.util.List; import java.util.List;
@Slf4j @Slf4j
@@ -38,7 +37,7 @@ public class SecurityWebAutoConfigurer {
log.debug("Configuring default security filter chain"); log.debug("Configuring default security filter chain");
http http
.csrf(AbstractHttpConfigurer::disable) // 前后端分离通常关闭CSRF .csrf(AbstractHttpConfigurer::disable) // 前后端分离通常关闭CSRF
.cors(cors -> cors.configurationSource(corsConfigurationSource())) // 启用 CORS 并使用自定义配置 .cors(AbstractHttpConfigurer::disable) // 前后端分离通常关闭CSRF
.sessionManagement(session -> session .sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)) // 无状态Session .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)) // 无状态Session
.authorizeHttpRequests(auth -> auth .authorizeHttpRequests(auth -> auth
@@ -76,10 +75,13 @@ public class SecurityWebAutoConfigurer {
public CorsConfigurationSource corsConfigurationSource() { public CorsConfigurationSource corsConfigurationSource() {
log.info("Configuring cors configuration source"); log.info("Configuring cors configuration source");
CorsConfiguration configuration = new CorsConfiguration(); CorsConfiguration configuration = new CorsConfiguration();
configuration.setExposedHeaders(List.of("Authorization")); // 允许前端访问Authorization头
configuration.addAllowedOrigin(CorsConfig.DEFAULT_ALLOWED_ORIGINS); // 允许任意来源
configuration.addAllowedHeader(CorsConfig.DEFAULT_ALLOWED_HEADERS); // 允许任意请求头
configuration.addAllowedMethod(CorsConfig.DEFAULT_ALLOWED_METHODS); // 允许指定的方法
configuration.setMaxAge(Long.parseLong(CorsConfig.DEFAULT_MAX_AGE)); // 设置预检请求缓存时间
configuration.setAllowedOrigins(List.of("*")); // 替换为前端域名 configuration.setAllowedOrigins(List.of("*")); // 替换为前端域名
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type", "X-Requested-With", "accept", "X-XSRF-TOKEN"));
configuration.setAllowCredentials(false); configuration.setAllowCredentials(false);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration); source.registerCorsConfiguration("/**", configuration);

View File

@@ -26,8 +26,7 @@ public class JwtRequestFilter extends OncePerRequestFilter {
private final RedisTokenService redisTokenService; private final RedisTokenService redisTokenService;
@Override @Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
throws ServletException, IOException {
final String authorizationHeader = request.getHeader("Authorization"); final String authorizationHeader = request.getHeader("Authorization");
@@ -39,8 +38,14 @@ public class JwtRequestFilter extends OncePerRequestFilter {
try { try {
username = JwtUtils.extractUsername(jwt); username = JwtUtils.extractUsername(jwt);
} catch (Exception e) { } catch (Exception e) {
logger.warn("Failed to extract username from token", e); logger.warn("Failed to extract username from token");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid token");
return;
} }
} else {
// 没有 token继续链可能是登录接口等不需要认证的路径
chain.doFilter(request, response);
return;
} }
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
@@ -55,6 +60,10 @@ public class JwtRequestFilter extends OncePerRequestFilter {
UsernamePasswordAuthenticationToken authentication = UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication); SecurityContextHolder.getContext().setAuthentication(authentication);
} else {
// token 无效或已过期
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Token is expired or invalid");
return;
} }
} }

View File

@@ -2,6 +2,8 @@ server:
port: 8080 port: 8080
arrokoth: arrokoth:
logger:
enabled: false
authorization: authorization:
server: server:
consent-page: /oauth2/consent consent-page: /oauth2/consent
@@ -16,6 +18,7 @@ arrokoth:
- /home/login - /home/login
- /login/oauth2/** - /login/oauth2/**
- /oauth2/token - /oauth2/token
- /system/dict/getDictData
# RestApi增强配置 # RestApi增强配置
graceful-rest-response: graceful-rest-response:
@@ -63,5 +66,3 @@ logging:
com.arrokoth: DEBUG com.arrokoth: DEBUG
org.springdoc: INFO org.springdoc: INFO
org.springframework: INFO org.springframework: INFO
org.springframework.security: DEBUG
org.springframework.security.oauth2: DEBUG