0
# Configuration
1
2
Comprehensive configuration management supporting memory-based and Redis-based storage with multi-app support, access token management, and production-ready deployment options for WeChat MiniApp applications.
3
4
## Capabilities
5
6
### Configuration Interface
7
8
Core configuration interface providing access to all WeChat MiniApp settings and credentials.
9
10
```java { .api }
11
public interface WxMaConfig {
12
// Basic Configuration
13
String getAppid();
14
void setAppid(String appid);
15
String getSecret();
16
void setSecret(String secret);
17
String getToken();
18
void setToken(String token);
19
String getAesKey();
20
void setAesKey(String aesKey);
21
String getOriginalId();
22
void setOriginalId(String originalId);
23
String getCloudEnv();
24
void setCloudEnv(String cloudEnv);
25
26
// Access Token Management
27
String getAccessToken();
28
Lock getAccessTokenLock();
29
boolean isAccessTokenExpired();
30
void expireAccessToken();
31
void updateAccessToken(WxAccessToken accessToken);
32
void updateAccessToken(String accessToken, int expiresInSeconds);
33
34
// Stable Access Token Support
35
boolean isStableAccessToken();
36
void useStableAccessToken(boolean use);
37
38
// JSAPI Ticket Management
39
String getJsapiTicket();
40
Lock getJsapiTicketLock();
41
boolean isJsapiTicketExpired();
42
void expireJsapiTicket();
43
void updateJsapiTicket(String jsapiTicket, int expiresInSeconds);
44
45
// Card API Ticket Management
46
String getCardApiTicket();
47
Lock getCardApiTicketLock();
48
boolean isCardApiTicketExpired();
49
void expireCardApiTicket();
50
void updateCardApiTicket(String cardApiTicket, int expiresInSeconds);
51
52
// HTTP Configuration
53
String getHttpProxyHost();
54
void setHttpProxyHost(String httpProxyHost);
55
int getHttpProxyPort();
56
void setHttpProxyPort(int httpProxyPort);
57
String getHttpProxyUsername();
58
void setHttpProxyUsername(String httpProxyUsername);
59
String getHttpProxyPassword();
60
void setHttpProxyPassword(String httpProxyPassword);
61
62
// HTTP Client Configuration
63
int getRetrySleepMillis();
64
void setRetrySleepMillis(int retrySleepMillis);
65
int getMaxRetryTimes();
66
void setMaxRetryTimes(int maxRetryTimes);
67
ApacheHttpClientBuilder getApacheHttpClientBuilder();
68
void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder);
69
70
// API Signature (for server-side API)
71
String getApiSignatureRsaPrivateKey();
72
void setApiSignatureRsaPrivateKey(String apiSignatureRsaPrivateKey);
73
String getApiSignatureAesKey();
74
void setApiSignatureAesKey(String apiSignatureAesKey);
75
String getApiSignatureRsaPrivateKeySn();
76
void setApiSignatureRsaPrivateKeySn(String apiSignatureRsaPrivateKeySn);
77
String getApiSignatureAesKeySn();
78
void setApiSignatureAesKeySn(String apiSignatureAesKeySn);
79
80
// Third-party Platform Support
81
String getWechatMpAppid();
82
void setWechatMpAppid(String wechatMpAppid);
83
}
84
```
85
86
### Default Configuration Implementation
87
88
Memory-based configuration implementation suitable for single-instance deployments.
89
90
```java { .api }
91
public class WxMaDefaultConfigImpl implements WxMaConfig, Serializable {
92
// Configuration Storage
93
private String appid; // Mini program App ID
94
private String secret; // Mini program App Secret
95
private String token; // Message encryption token
96
private String aesKey; // Message encryption AES key
97
private String originalId; // Original ID
98
private String cloudEnv; // Cloud environment ID
99
100
// Access Token Management
101
private volatile String accessToken; // Current access token
102
private volatile long accessTokenExpiresTime; // Expiration timestamp
103
private final Lock accessTokenLock = new ReentrantLock();
104
private boolean stableAccessToken = false; // Use stable access token interface
105
106
// Token Update Callbacks
107
private Consumer<WxAccessTokenEntity> updateAccessTokenBefore;
108
private boolean enableUpdateAccessTokenBefore = false;
109
110
// JSAPI Ticket Management
111
private volatile String jsapiTicket; // JSAPI ticket
112
private volatile long jsapiTicketExpiresTime; // JSAPI ticket expiration
113
private final Lock jsapiTicketLock = new ReentrantLock();
114
115
// Card API Ticket Management
116
private volatile String cardApiTicket; // Card API ticket
117
private volatile long cardApiTicketExpiresTime; // Card API ticket expiration
118
private final Lock cardApiTicketLock = new ReentrantLock();
119
120
// HTTP Configuration
121
private String httpProxyHost; // HTTP proxy host
122
private int httpProxyPort = 0; // HTTP proxy port
123
private String httpProxyUsername; // HTTP proxy username
124
private String httpProxyPassword; // HTTP proxy password
125
private int retrySleepMillis = 1000; // Retry delay in milliseconds
126
private int maxRetryTimes = 5; // Maximum retry attempts
127
128
// HTTP Client Builder
129
private ApacheHttpClientBuilder apacheHttpClientBuilder;
130
131
// API Signature Configuration
132
private String apiSignatureRsaPrivateKey; // RSA private key for API signature
133
private String apiSignatureAesKey; // AES key for API signature
134
private String apiSignatureRsaPrivateKeySn; // RSA key serial number
135
private String apiSignatureAesKeySn; // AES key serial number
136
137
// Third-party Platform
138
private String wechatMpAppid; // Component app ID for third-party platforms
139
140
// Constructors
141
public WxMaDefaultConfigImpl();
142
143
// Token Management Methods
144
@Override
145
public boolean isAccessTokenExpired();
146
@Override
147
public void updateAccessToken(String accessToken, int expiresInSeconds);
148
@Override
149
public void updateAccessToken(WxAccessToken accessToken);
150
151
// Callback Configuration
152
public void setUpdateAccessTokenBefore(Consumer<WxAccessTokenEntity> updateAccessTokenBefore);
153
public void enableUpdateAccessTokenBefore(boolean enable);
154
155
// All getters and setters...
156
}
157
```
158
159
### Redis Configuration Implementations
160
161
Production-ready Redis-based configuration implementations for distributed deployments.
162
163
```java { .api }
164
// Basic Redis Configuration
165
public class WxMaRedisConfigImpl extends AbstractWxMaRedisConfig {
166
private final RedisTemplate<String, String> redisTemplate;
167
168
public WxMaRedisConfigImpl(RedisTemplate<String, String> redisTemplate);
169
public WxMaRedisConfigImpl(RedisTemplate<String, String> redisTemplate, String keyPrefix);
170
171
// Redis operations using RedisTemplate
172
@Override
173
public String getConfigValue(String key, String defaultValue);
174
@Override
175
public void setConfigValue(String key, String value);
176
@Override
177
public void expireConfigValue(String key, int seconds);
178
}
179
180
// Redisson Configuration
181
public class WxMaRedissonConfigImpl extends AbstractWxMaRedisConfig {
182
private final RedissonClient redissonClient;
183
184
public WxMaRedissonConfigImpl(RedissonClient redissonClient);
185
public WxMaRedissonConfigImpl(RedissonClient redissonClient, String keyPrefix);
186
187
// Redisson operations with distributed locks
188
@Override
189
public Lock getConfigLock(String key);
190
@Override
191
public String getConfigValue(String key, String defaultValue);
192
@Override
193
public void setConfigValue(String key, String value);
194
}
195
196
// Enhanced Redis Configuration
197
public class WxMaRedisBetterConfigImpl extends AbstractWxMaRedisConfig {
198
private final RedisTemplate<String, String> redisTemplate;
199
private final StringRedisTemplate stringRedisTemplate;
200
201
public WxMaRedisBetterConfigImpl(RedisTemplate<String, String> redisTemplate,
202
StringRedisTemplate stringRedisTemplate);
203
204
// Enhanced Redis operations with better performance
205
@Override
206
public void updateAccessToken(String accessToken, int expiresInSeconds);
207
@Override
208
public boolean isAccessTokenExpired();
209
}
210
211
// Redis Connection Configuration
212
public class WxMaRedisConnectionConfigImpl extends AbstractWxMaRedisConfig {
213
private final RedisConnectionFactory connectionFactory;
214
215
public WxMaRedisConnectionConfigImpl(RedisConnectionFactory connectionFactory);
216
public WxMaRedisConnectionConfigImpl(RedisConnectionFactory connectionFactory, String keyPrefix);
217
218
// Direct Redis connection operations
219
}
220
```
221
222
### Abstract Redis Configuration
223
224
Base class providing common Redis configuration functionality.
225
226
```java { .api }
227
public abstract class AbstractWxMaRedisConfig implements WxMaConfig {
228
protected String keyPrefix = "wx:ma:"; // Redis key prefix
229
230
// Configuration Keys
231
protected static final String ACCESS_TOKEN_KEY = "access_token";
232
protected static final String JSAPI_TICKET_KEY = "jsapi_ticket";
233
protected static final String CARD_API_TICKET_KEY = "card_api_ticket";
234
235
// Lock Keys
236
protected static final String ACCESS_TOKEN_LOCK_KEY = "access_token:lock";
237
protected static final String JSAPI_TICKET_LOCK_KEY = "jsapi_ticket:lock";
238
protected static final String CARD_API_TICKET_LOCK_KEY = "card_api_ticket:lock";
239
240
// Abstract methods to be implemented by subclasses
241
protected abstract String getValue(String key);
242
protected abstract void setValue(String key, String value, int expireSeconds);
243
protected abstract void expire(String key, int seconds);
244
protected abstract Long getExpire(String key);
245
protected abstract Lock getLock(String key);
246
247
// Common Redis operations
248
protected String buildKey(String key) {
249
return keyPrefix + getAppid() + ":" + key;
250
}
251
252
// Token management using Redis
253
@Override
254
public String getAccessToken() {
255
return getValue(buildKey(ACCESS_TOKEN_KEY));
256
}
257
258
@Override
259
public boolean isAccessTokenExpired() {
260
Long expire = getExpire(buildKey(ACCESS_TOKEN_KEY));
261
return expire == null || expire < 200; // 200 second buffer
262
}
263
264
@Override
265
public void updateAccessToken(String accessToken, int expiresInSeconds) {
266
setValue(buildKey(ACCESS_TOKEN_KEY), accessToken, expiresInSeconds - 200);
267
}
268
269
@Override
270
public Lock getAccessTokenLock() {
271
return getLock(buildKey(ACCESS_TOKEN_LOCK_KEY));
272
}
273
}
274
```
275
276
## Usage Examples
277
278
### Basic Configuration Setup
279
280
#### Memory-based Configuration (Development)
281
282
```java
283
@Configuration
284
public class WeChatMiniAppConfig {
285
286
@Value("${wechat.miniapp.appid}")
287
private String appid;
288
289
@Value("${wechat.miniapp.secret}")
290
private String secret;
291
292
@Value("${wechat.miniapp.token:}")
293
private String token;
294
295
@Value("${wechat.miniapp.aes-key:}")
296
private String aesKey;
297
298
@Bean
299
public WxMaConfig wxMaConfig() {
300
WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
301
config.setAppid(appid);
302
config.setSecret(secret);
303
config.setToken(token);
304
config.setAesKey(aesKey);
305
306
// HTTP configuration
307
config.setRetrySleepMillis(1000);
308
config.setMaxRetryTimes(3);
309
310
// Enable stable access token (recommended for production)
311
config.useStableAccessToken(true);
312
313
return config;
314
}
315
316
@Bean
317
public WxMaService wxMaService(WxMaConfig wxMaConfig) {
318
WxMaServiceImpl service = new WxMaServiceImpl();
319
service.setWxMaConfig(wxMaConfig);
320
return service;
321
}
322
}
323
```
324
325
#### Redis-based Configuration (Production)
326
327
```java
328
@Configuration
329
@ConditionalOnProperty(name = "wechat.redis.enabled", havingValue = "true")
330
public class WeChatRedisConfig {
331
332
@Autowired
333
private RedisTemplate<String, String> redisTemplate;
334
335
@Bean
336
public WxMaConfig wxMaRedisConfig() {
337
WxMaRedisConfigImpl config = new WxMaRedisConfigImpl(redisTemplate, "wechat:ma:");
338
config.setAppid("your-appid");
339
config.setSecret("your-secret");
340
config.setToken("your-token");
341
config.setAesKey("your-aes-key");
342
343
// Configure HTTP settings
344
config.setHttpProxyHost("proxy.company.com");
345
config.setHttpProxyPort(8080);
346
config.setHttpProxyUsername("proxy-user");
347
config.setHttpProxyPassword("proxy-pass");
348
349
// Configure retry settings
350
config.setRetrySleepMillis(2000);
351
config.setMaxRetryTimes(5);
352
353
return config;
354
}
355
}
356
```
357
358
### Multi-App Configuration
359
360
#### Multiple Mini Programs Support
361
362
```java
363
@Configuration
364
public class MultiAppWeChatConfig {
365
366
@Bean
367
public WxMaService multiAppWxMaService() {
368
WxMaServiceImpl service = new WxMaServiceImpl();
369
370
// Configure multiple apps
371
Map<String, WxMaConfig> configs = new HashMap<>();
372
373
// App 1 - Main app
374
WxMaDefaultConfigImpl config1 = new WxMaDefaultConfigImpl();
375
config1.setAppid("app1-appid");
376
config1.setSecret("app1-secret");
377
config1.setToken("app1-token");
378
configs.put("main", config1);
379
380
// App 2 - Secondary app
381
WxMaDefaultConfigImpl config2 = new WxMaDefaultConfigImpl();
382
config2.setAppid("app2-appid");
383
config2.setSecret("app2-secret");
384
config2.setToken("app2-token");
385
configs.put("secondary", config2);
386
387
// App 3 - Test environment
388
WxMaDefaultConfigImpl config3 = new WxMaDefaultConfigImpl();
389
config3.setAppid("test-appid");
390
config3.setSecret("test-secret");
391
config3.setToken("test-token");
392
configs.put("test", config3);
393
394
service.setMultiConfigs(configs, "main"); // "main" as default
395
396
return service;
397
}
398
}
399
400
@Service
401
public class MultiAppService {
402
403
@Autowired
404
private WxMaService wxMaService;
405
406
public void handleMainAppRequest(String jsCode) {
407
// Use main app (default)
408
WxMaJscode2SessionResult session = wxMaService.getUserService()
409
.getSessionInfo(jsCode);
410
// Process main app request...
411
}
412
413
public void handleSecondaryAppRequest(String jsCode) {
414
// Switch to secondary app
415
wxMaService.switchoverTo("secondary");
416
try {
417
WxMaJscode2SessionResult session = wxMaService.getUserService()
418
.getSessionInfo(jsCode);
419
// Process secondary app request...
420
} finally {
421
// Switch back to default
422
wxMaService.switchoverTo("main");
423
}
424
}
425
426
public void handleTestRequest(String jsCode) {
427
// Use test environment
428
wxMaService.switchoverTo("test");
429
try {
430
WxMaJscode2SessionResult session = wxMaService.getUserService()
431
.getSessionInfo(jsCode);
432
// Process test request...
433
} finally {
434
wxMaService.switchoverTo("main");
435
}
436
}
437
}
438
```
439
440
### Advanced Configuration
441
442
#### Custom HTTP Client Configuration
443
444
```java
445
@Configuration
446
public class CustomHttpClientConfig {
447
448
@Bean
449
public WxMaConfig customHttpConfig() {
450
WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
451
config.setAppid("your-appid");
452
config.setSecret("your-secret");
453
454
// Custom Apache HttpClient configuration
455
ApacheHttpClientBuilder httpClientBuilder = ApacheHttpClientBuilder.create()
456
.setConnectionTimeout(10000) // 10 seconds connection timeout
457
.setSocketTimeout(30000) // 30 seconds socket timeout
458
.setConnectionRequestTimeout(5000) // 5 seconds connection request timeout
459
.setMaxTotalConnections(200) // Max total connections
460
.setMaxConnectionsPerRoute(50) // Max connections per route
461
.setRetryCount(3); // Retry count
462
463
// Custom connection pool configuration
464
httpClientBuilder.setConnectionTimeToLive(300, TimeUnit.SECONDS);
465
httpClientBuilder.setConnectionKeepAlive(true);
466
467
config.setApacheHttpClientBuilder(httpClientBuilder);
468
469
// Configure retry behavior
470
config.setRetrySleepMillis(1500);
471
config.setMaxRetryTimes(3);
472
473
return config;
474
}
475
}
476
```
477
478
#### Access Token Callback Configuration
479
480
```java
481
@Component
482
public class TokenManagementService {
483
484
@Bean
485
public WxMaConfig tokenCallbackConfig() {
486
WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
487
config.setAppid("your-appid");
488
config.setSecret("your-secret");
489
490
// Enable token update callbacks
491
config.enableUpdateAccessTokenBefore(true);
492
493
// Set token update callback
494
config.setUpdateAccessTokenBefore(tokenEntity -> {
495
logger.info("Access token about to be updated: {} -> {}",
496
tokenEntity.getOldToken(), tokenEntity.getNewToken());
497
498
// Store token update in audit log
499
auditService.logTokenUpdate(tokenEntity);
500
501
// Update token in external cache if needed
502
externalCacheService.updateToken(tokenEntity.getNewToken());
503
504
// Notify monitoring system
505
monitoringService.notifyTokenUpdate(tokenEntity);
506
});
507
508
return config;
509
}
510
511
@Autowired
512
private AuditService auditService;
513
514
@Autowired
515
private ExternalCacheService externalCacheService;
516
517
@Autowired
518
private MonitoringService monitoringService;
519
}
520
```
521
522
### Production Configuration Examples
523
524
#### Redis Cluster Configuration
525
526
```java
527
@Configuration
528
@Profile("production")
529
public class ProductionRedisConfig {
530
531
@Bean
532
public LettuceConnectionFactory redisConnectionFactory() {
533
RedisClusterConfiguration clusterConfig = new RedisClusterConfiguration(
534
Arrays.asList(
535
"redis-cluster-node1:7000",
536
"redis-cluster-node2:7000",
537
"redis-cluster-node3:7000"
538
)
539
);
540
clusterConfig.setPassword("redis-password");
541
542
LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
543
.commandTimeout(Duration.ofSeconds(2))
544
.shutdownTimeout(Duration.ZERO)
545
.build();
546
547
return new LettuceConnectionFactory(clusterConfig, clientConfig);
548
}
549
550
@Bean
551
public WxMaConfig productionWxMaConfig(RedisConnectionFactory connectionFactory) {
552
WxMaRedisConnectionConfigImpl config = new WxMaRedisConnectionConfigImpl(
553
connectionFactory, "prod:wechat:ma:"
554
);
555
556
config.setAppid("prod-appid");
557
config.setSecret("prod-secret");
558
config.setToken("prod-token");
559
config.setAesKey("prod-aes-key");
560
561
// Production settings
562
config.useStableAccessToken(true);
563
config.setRetrySleepMillis(2000);
564
config.setMaxRetryTimes(5);
565
566
// Configure for high availability
567
config.setHttpProxyHost(null); // No proxy in production
568
config.setMaxRetryTimes(10); // More retries for reliability
569
570
return config;
571
}
572
}
573
```
574
575
#### Environment-specific Configuration
576
577
```java
578
@Configuration
579
public class EnvironmentAwareConfig {
580
581
@Value("${spring.profiles.active:dev}")
582
private String activeProfile;
583
584
@Bean
585
@ConditionalOnProperty(name = "spring.profiles.active", havingValue = "dev")
586
public WxMaConfig devConfig() {
587
WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
588
config.setAppid("dev-appid");
589
config.setSecret("dev-secret");
590
config.setRetrySleepMillis(500); // Faster retries in dev
591
config.setMaxRetryTimes(2); // Fewer retries in dev
592
593
return config;
594
}
595
596
@Bean
597
@ConditionalOnProperty(name = "spring.profiles.active", havingValue = "staging")
598
public WxMaConfig stagingConfig(RedisTemplate<String, String> redisTemplate) {
599
WxMaRedisConfigImpl config = new WxMaRedisConfigImpl(
600
redisTemplate, "staging:wechat:ma:"
601
);
602
config.setAppid("staging-appid");
603
config.setSecret("staging-secret");
604
config.useStableAccessToken(true);
605
606
return config;
607
}
608
609
@Bean
610
@ConditionalOnProperty(name = "spring.profiles.active", havingValue = "prod")
611
public WxMaConfig productionConfig(RedissonClient redissonClient) {
612
WxMaRedissonConfigImpl config = new WxMaRedissonConfigImpl(
613
redissonClient, "prod:wechat:ma:"
614
);
615
config.setAppid("prod-appid");
616
config.setSecret("prod-secret");
617
config.useStableAccessToken(true);
618
config.setRetrySleepMillis(3000);
619
config.setMaxRetryTimes(8);
620
621
return config;
622
}
623
}
624
```
625
626
### Configuration Monitoring and Health Checks
627
628
```java
629
@Component
630
public class WeChatConfigHealthIndicator implements HealthIndicator {
631
632
@Autowired
633
private WxMaService wxMaService;
634
635
@Override
636
public Health health() {
637
try {
638
WxMaConfig config = wxMaService.getWxMaConfig();
639
640
// Check basic configuration
641
if (config.getAppid() == null || config.getSecret() == null) {
642
return Health.down()
643
.withDetail("error", "Missing required configuration")
644
.build();
645
}
646
647
// Check access token
648
String accessToken = config.getAccessToken();
649
boolean tokenExpired = config.isAccessTokenExpired();
650
651
Health.Builder builder = Health.up()
652
.withDetail("appid", config.getAppid())
653
.withDetail("hasAccessToken", accessToken != null)
654
.withDetail("tokenExpired", tokenExpired)
655
.withDetail("configType", config.getClass().getSimpleName());
656
657
// Check Redis connection if using Redis config
658
if (config instanceof AbstractWxMaRedisConfig) {
659
builder.withDetail("storageType", "Redis");
660
} else {
661
builder.withDetail("storageType", "Memory");
662
}
663
664
return builder.build();
665
666
} catch (Exception e) {
667
return Health.down()
668
.withDetail("error", e.getMessage())
669
.build();
670
}
671
}
672
}
673
674
@Component
675
public class ConfigurationMetrics {
676
677
@Autowired
678
private WxMaService wxMaService;
679
680
@Autowired
681
private MeterRegistry meterRegistry;
682
683
@PostConstruct
684
public void initMetrics() {
685
// Track access token age
686
Gauge.builder("wechat.access_token.age.seconds")
687
.description("Age of current access token in seconds")
688
.register(meterRegistry, this, metrics -> {
689
try {
690
WxMaConfig config = wxMaService.getWxMaConfig();
691
// Calculate token age based on expiration
692
return config.isAccessTokenExpired() ? -1 :
693
calculateTokenAge(config.getAccessToken());
694
} catch (Exception e) {
695
return -1;
696
}
697
});
698
}
699
700
@EventListener
701
public void onAccessTokenUpdate(AccessTokenUpdateEvent event) {
702
meterRegistry.counter("wechat.access_token.updates.total")
703
.increment();
704
}
705
706
@Scheduled(fixedRate = 60000) // Every minute
707
public void recordConfigMetrics() {
708
try {
709
WxMaConfig config = wxMaService.getWxMaConfig();
710
711
// Record token expiration status
712
meterRegistry.gauge("wechat.access_token.expired",
713
config.isAccessTokenExpired() ? 1 : 0);
714
715
// Record JSAPI ticket status
716
meterRegistry.gauge("wechat.jsapi_ticket.expired",
717
config.isJsapiTicketExpired() ? 1 : 0);
718
719
} catch (Exception e) {
720
logger.error("Failed to record config metrics: {}", e.getMessage());
721
}
722
}
723
}
724
```
725
726
### Configuration Security Best Practices
727
728
```java
729
@Configuration
730
public class SecureConfigurationExample {
731
732
// Use environment variables for sensitive data
733
@Value("${WECHAT_APPID}")
734
private String appid;
735
736
@Value("${WECHAT_SECRET}")
737
private String secret;
738
739
@Value("${WECHAT_AES_KEY}")
740
private String aesKey;
741
742
@Bean
743
public WxMaConfig secureConfig() {
744
WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
745
config.setAppid(appid);
746
config.setSecret(secret);
747
config.setAesKey(aesKey);
748
749
// Configure API signature for enhanced security
750
config.setApiSignatureRsaPrivateKey(loadRsaPrivateKey());
751
config.setApiSignatureAesKey(loadApiAesKey());
752
753
return config;
754
}
755
756
private String loadRsaPrivateKey() {
757
try {
758
// Load from secure key management system
759
return keyManagementService.getPrivateKey("wechat-rsa");
760
} catch (Exception e) {
761
logger.error("Failed to load RSA private key: {}", e.getMessage());
762
throw new ConfigurationException("Security key loading failed", e);
763
}
764
}
765
766
private String loadApiAesKey() {
767
try {
768
return keyManagementService.getAesKey("wechat-api");
769
} catch (Exception e) {
770
logger.error("Failed to load API AES key: {}", e.getMessage());
771
throw new ConfigurationException("Security key loading failed", e);
772
}
773
}
774
775
@Autowired
776
private KeyManagementService keyManagementService;
777
}
778
```
779
780
This configuration module provides comprehensive setup options for WeChat MiniApp applications, supporting both development and production environments with proper security, monitoring, and scalability considerations.