liujie
2026-08-11 323764c813a09cd56cdab780155ef659dbe0b364
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
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<String, String> 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<String, String> 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);
        }
    }
}