yangys
2024-04-04 ed4a5236bab800094be4a8378f5098eebe3de6ac
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
package com.qianwen.core.secure.utils;
 
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.security.Key;
import java.util.Base64;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.Objects;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import com.qianwen.core.jwt.JwtUtil;
import com.qianwen.core.jwt.props.JwtProperties;
import com.qianwen.core.secure.TokenInfo;
import com.qianwen.core.secure.constant.SecureConstant;
import com.qianwen.core.secure.exception.SecureException;
import com.qianwen.core.secure.provider.IClientDetails;
import com.qianwen.core.secure.provider.IClientDetailsService;
import com.qianwen.core.tool.utils.Charsets;
import com.qianwen.core.tool.utils.Func;
import com.qianwen.core.tool.utils.SpringUtil;
import com.qianwen.core.tool.utils.StringUtil;
import com.qianwen.core.tool.utils.WebUtil;
 
/* loaded from: blade-core-secure-9.3.0.0-SNAPSHOT.jar:org/springblade/core/secure/utils/SecureUtil.class */
public class SecureUtil extends AuthUtil {
    private static final String CLIENT_ID = "client_id";
    private static IClientDetailsService clientDetailsService;
    private static JwtProperties jwtProperties;
    static final /* synthetic */ boolean $assertionsDisabled;
 
    static {
        $assertionsDisabled = !SecureUtil.class.desiredAssertionStatus();
    }
 
    private static IClientDetailsService getClientDetailsService() {
        if (clientDetailsService == null) {
            clientDetailsService = (IClientDetailsService) SpringUtil.getBean(IClientDetailsService.class);
        }
        return clientDetailsService;
    }
 
    private static JwtProperties getJwtProperties() {
        if (jwtProperties == null) {
            jwtProperties = (JwtProperties) SpringUtil.getBean(JwtProperties.class);
        }
        return jwtProperties;
    }
 
    public static TokenInfo createJWT(Map<String, Object> user, String audience, String issuer, String tokenType) {
        long expireMillis;
        String[] tokens = extractAndDecodeHeader();
        String clientId = tokens[0];
        String clientSecret = tokens[1];
        IClientDetails clientDetails = clientDetails(clientId);
        if (!validateClient(clientDetails, clientId, clientSecret)) {
            throw new SecureException("客户端认证失败, 请检查请求头 [Authorization] 信息");
        }
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        byte[] apiKeySecretBytes = Base64.getDecoder().decode(JwtUtil.getBase64Security());
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
        JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT").setIssuer(issuer).setAudience(audience).signWith(signingKey);
        
        user.forEach(builder::claim);
        builder.claim(CLIENT_ID, clientId);
        if (tokenType.equals("access_token")) {
            expireMillis = clientDetails.getAccessTokenValidity().intValue() * 1000;
        } else if (tokenType.equals("refresh_token")) {
            expireMillis = clientDetails.getRefreshTokenValidity().intValue() * 1000;
        } else {
            expireMillis = getExpire();
        }
        long expMillis = nowMillis + expireMillis;
        Date exp = new Date(expMillis);
        builder.setExpiration(exp).setNotBefore(now);
        TokenInfo tokenInfo = new TokenInfo();
        tokenInfo.setToken(builder.compact());
        tokenInfo.setExpire((int) (expireMillis / 1000));
        if (getJwtProperties().getState().booleanValue() && "access_token".equals(tokenType)) {
            String tenantId = String.valueOf(user.get("tenant_id"));
            String userId = String.valueOf(user.get("user_id"));
            JwtUtil.addAccessToken(tenantId, userId, tokenInfo.getToken(), tokenInfo.getExpire());
        }
        if (getJwtProperties().getState().booleanValue() && getJwtProperties().getSingle().booleanValue() && "refresh_token".equals(tokenType)) {
            String tenantId2 = String.valueOf(user.get("tenant_id"));
            String userId2 = String.valueOf(user.get("user_id"));
            JwtUtil.addRefreshToken(tenantId2, userId2, tokenInfo.getToken(), tokenInfo.getExpire());
        }
        return tokenInfo;
    }
 
    public static TokenInfo createJWT(Map<String, Object> user, String audience, String issuer, String tokenType, String clientId, String clientSecret) {
        long expireMillis;
        IClientDetails clientDetails = clientDetails(clientId);
        if (!validateClient(clientDetails, clientId, clientSecret)) {
            throw new SecureException("client authentication failed, please check the header parameters");
        }
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        byte[] apiKeySecretBytes = Base64.getDecoder().decode(JwtUtil.getBase64Security());
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
        JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT").setIssuer(issuer).setAudience(audience).signWith(signingKey);
        user.forEach(builder::claim);
        builder.claim(CLIENT_ID, clientId);
        if (tokenType.equals("access_token")) {
            expireMillis = clientDetails.getAccessTokenValidity().intValue() * 1000;
        } else if (tokenType.equals("refresh_token")) {
            expireMillis = clientDetails.getRefreshTokenValidity().intValue() * 1000;
        } else {
            expireMillis = getExpire();
        }
        long expMillis = nowMillis + expireMillis;
        Date exp = new Date(expMillis);
        builder.setExpiration(exp).setNotBefore(now);
        TokenInfo tokenInfo = new TokenInfo();
        tokenInfo.setToken(builder.compact());
        tokenInfo.setExpire((int) (expireMillis / 1000));
        if (getJwtProperties().getState().booleanValue() && "access_token".equals(tokenType)) {
            String tenantId = String.valueOf(user.get("tenant_id"));
            String userId = String.valueOf(user.get("user_id"));
            JwtUtil.addAccessToken(tenantId, userId, tokenInfo.getToken(), tokenInfo.getExpire());
        }
        return tokenInfo;
    }
 
    public static long getExpire() {
        Calendar cal = Calendar.getInstance();
        cal.add(6, 1);
        cal.set(11, 3);
        cal.set(13, 0);
        cal.set(12, 0);
        cal.set(14, 0);
        return cal.getTimeInMillis() - System.currentTimeMillis();
    }
 
    public static String[] extractAndDecodeHeader() {
        
        try {
            byte[] decoded;
            String header = ((HttpServletRequest) Objects.<HttpServletRequest>requireNonNull(WebUtil.getRequest()))
                    .getHeader("Authorization");
            header = Func.toStr(header).replace("Basic%20", "Basic ");
            if (!header.startsWith(SecureConstant.BASIC_HEADER_PREFIX))
                throw new SecureException("未获取到请求头[Authorization]的信息");
            byte[] base64Token = header.substring(6).getBytes(Charsets.UTF_8_NAME);
            try {
                decoded = Base64.getDecoder().decode(base64Token);
            } catch (IllegalArgumentException var7) {
                throw new RuntimeException("客户端令牌解析失败");
            }
            String token = new String(decoded, Charsets.UTF_8_NAME);
            int index = token.indexOf(":");
            if (index == -1)
                throw new RuntimeException("客户端令牌不合法");
            return new String[] { token.substring(0, index), token.substring(index + 1) };
        } catch (Throwable ex) {
            throw new RuntimeException("客户端令牌解析失败", ex);
        }
        
        
    }
 
    public static String getClientIdFromHeader() {
        String[] tokens = extractAndDecodeHeader();
        if ($assertionsDisabled || tokens.length == 2) {
            return tokens[0];
        }
        throw new AssertionError();
    }
 
    private static IClientDetails clientDetails(String clientId) {
        return getClientDetailsService().loadClientByClientId(clientId);
    }
 
    private static boolean validateClient(IClientDetails clientDetails, String clientId, String clientSecret) {
        return clientDetails != null && StringUtil.equals(clientId, clientDetails.getClientId()) && StringUtil.equals(clientSecret, clientDetails.getClientSecret());
    }
}