package com.ruoyi.web.controller.tool; import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.exception.ServiceException; import okhttp3.Request; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; /** * 中台请求认证头回归测试。 */ public class BaseDataApiUtilAuthorizationTest { public static void main(String[] args) throws Exception { shouldSkipAuthorizationForLogin(); shouldAddAuthorizationForMiddlePlatformRequest(); shouldAllowExplicitAuthorizationHeader(); shouldRequireReloginForExpiredMiddlePlatformSession(); shouldForbidLocalFallbackSession(); } private static void shouldSkipAuthorizationForLogin() throws IOException { SecurityContextHolder.clearContext(); Request.Builder builder = requestBuilder(); addHeaders(builder, BaseDataApiUtil.Api.POST_AUTH_USER_LOGIN, null); require(builder.build().header("Authorization") == null, "中台登录请求不应携带认证头"); } private static void shouldAddAuthorizationForMiddlePlatformRequest() throws IOException { LoginUser loginUser = new LoginUser(); loginUser.setMiddlePlatformToken("middle-token"); SecurityContextHolder.getContext().setAuthentication( new UsernamePasswordAuthenticationToken(loginUser, null, Collections.emptyList())); Request.Builder builder = requestBuilder(); addHeaders(builder, BaseDataApiUtil.Api.GET_REGION_TREE, null); require("Bearer middle-token".equals(builder.build().header("Authorization")), "中台业务请求未携带正确的 Bearer Token"); SecurityContextHolder.clearContext(); } private static void shouldAllowExplicitAuthorizationHeader() throws IOException { SecurityContextHolder.clearContext(); Map headers = new LinkedHashMap<>(); headers.put("Authorization", "Bearer explicit-token"); Request.Builder builder = requestBuilder(); addHeaders(builder, BaseDataApiUtil.Api.POST_AUTH_USER_LOGOUT, headers); require("Bearer explicit-token".equals(builder.build().header("Authorization")), "显式中台认证头未被保留"); } private static void shouldRequireReloginForExpiredMiddlePlatformSession() { SecurityContextHolder.clearContext(); try { addHeaders(requestBuilder(), BaseDataApiUtil.Api.GET_REGION_TREE, null); throw new AssertionError("缺少中台 Token 时请求未被拒绝"); } catch (ServiceException e) { require(Integer.valueOf(401).equals(e.getCode()), "中台认证失效时未返回401"); } catch (IOException e) { throw new AssertionError("中台认证失效时异常类型错误", e); } } private static void shouldForbidLocalFallbackSession() { LoginUser loginUser = new LoginUser(); loginUser.setLoginSource("local"); SecurityContextHolder.getContext().setAuthentication( new UsernamePasswordAuthenticationToken(loginUser, null, Collections.emptyList())); try { addHeaders(requestBuilder(), BaseDataApiUtil.Api.GET_REGION_TREE, null); throw new AssertionError("本地回落账号访问中台数据时请求未被拒绝"); } catch (ServiceException e) { require(Integer.valueOf(403).equals(e.getCode()), "本地回落账号访问中台数据时未返回403"); } catch (IOException e) { throw new AssertionError("本地回落账号访问中台数据时异常类型错误", e); } finally { SecurityContextHolder.clearContext(); } } private static Request.Builder requestBuilder() { return new Request.Builder().url("http://localhost/test"); } private static void addHeaders(Request.Builder builder, BaseDataApiUtil.Api api, Map headers) throws IOException { try { Method method = BaseDataApiUtil.class.getDeclaredMethod( "addHeaders", Request.Builder.class, BaseDataApiUtil.Api.class, Map.class); method.setAccessible(true); method.invoke(null, builder, api, headers); } catch (InvocationTargetException e) { if (e.getCause() instanceof IOException) { throw (IOException) e.getCause(); } if (e.getCause() instanceof RuntimeException) { throw (RuntimeException) e.getCause(); } throw new IllegalStateException(e.getCause()); } catch (ReflectiveOperationException e) { throw new IllegalStateException(e); } } private static void require(boolean condition, String message) { if (!condition) { throw new AssertionError(message); } } }