Skip to content

Commit 347eaf0

Browse files
[feature]mapboxgl解密矢量瓦片 review by songym
1 parent b107e78 commit 347eaf0

File tree

11 files changed

+363
-52
lines changed

11 files changed

+363
-52
lines changed

src/common/index.common.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,8 @@ import {
334334
getMeterPerMapUnit,
335335
getWrapNum,
336336
conversionDegree,
337-
EncryptRequest
337+
EncryptRequest,
338+
getServiceKey
338339
} from './util';
339340
import { CartoCSS, ThemeStyle } from './style';
340341
import {
@@ -500,6 +501,7 @@ export {
500501
setCORS,
501502
FetchRequest,
502503
EncryptRequest,
504+
getServiceKey,
503505
ColorsPickerUtil,
504506
ArrayStatistic,
505507
getMeterPerMapUnit,

src/common/namespace.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ import {
338338
setCORS,
339339
FetchRequest,
340340
EncryptRequest,
341+
getServiceKey,
341342
ColorsPickerUtil,
342343
ArrayStatistic,
343344
CartoCSS,
@@ -495,7 +496,7 @@ SuperMap.setRequestTimeout = setRequestTimeout;
495496
SuperMap.getRequestTimeout = getRequestTimeout;
496497
SuperMap.FetchRequest = FetchRequest;
497498
SuperMap.EncryptRequest = EncryptRequest;
498-
499+
SuperMap.getServiceKey = getServiceKey;
499500
// commontypes
500501
SuperMap.inherit = inheritExt;
501502
SuperMap.mixin = mixinExt;

src/common/util/EncryptRequest.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,41 @@ export class EncryptRequest {
140140
return this.tunnelUrl;
141141
}
142142
}
143+
144+
/**
145+
* @function getServiceKey
146+
* @version 11.2.0
147+
* @category iServer
148+
* @description 获取矢量瓦片解密密钥
149+
* @param {string} serviceUrl - iserver服务地址,例如: 'http://127.0.0.1:8090/iserver/services/xxx'、 'http://127.0.0.1:8090/iserver/services/xxx/rest/maps' 、 'http://127.0.0.1:8090/iserver/services/xxx/restjsr/v1/vectortile'
150+
* @return {Promise} key - 矢量瓦片密钥
151+
*/
152+
export async function getServiceKey(serviceUrl) {
153+
try {
154+
const workspaceServerUrl = ((serviceUrl &&
155+
serviceUrl.match(/.+(?=(\/restjsr\/v1\/vectortile\/|\/rest\/maps\/))/)) ||
156+
[])[0];
157+
if (!workspaceServerUrl) {
158+
return;
159+
}
160+
const servicesResponse = await FetchRequest.get(workspaceServerUrl);
161+
const servicesResult = await servicesResponse.json();
162+
const matchRestData = (servicesResult || []).find(
163+
(item) => serviceUrl.includes(item.name) && item.serviceEncryptInfo
164+
);
165+
if (!matchRestData) {
166+
return;
167+
}
168+
const iserverHost = workspaceServerUrl.split('/services/')[0];
169+
const encryptRequest = new EncryptRequest(iserverHost);
170+
const svckeyUrl =
171+
matchRestData && `${iserverHost}/services/security/svckeys/${matchRestData.serviceEncryptInfo.encrptKeyID}.json`;
172+
const svcReponse = await encryptRequest.request({
173+
method: 'get',
174+
url: svckeyUrl
175+
});
176+
return await svcReponse.json();
177+
} catch (error) {
178+
console.error(error);
179+
}
180+
}

src/common/util/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111

1212
import { ColorsPickerUtil } from './ColorsPickerUtil';
1313

14-
import { EncryptRequest } from './EncryptRequest';
14+
import { EncryptRequest, getServiceKey } from './EncryptRequest';
1515

1616
import { ArrayStatistic } from './ArrayStatistic';
1717
import { getMeterPerMapUnit, getWrapNum, conversionDegree } from './MapCalculateUtil';
@@ -73,6 +73,7 @@ export {
7373
getRequestTimeout,
7474
FetchRequest,
7575
EncryptRequest,
76+
getServiceKey,
7677
ColorsPickerUtil,
7778
ArrayStatistic,
7879
getMeterPerMapUnit,

src/mapboxgl/core/MapExtend.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,26 @@
22
* This program are made available under the terms of the Apache License, Version 2.0
33
* which accompanies this distribution and is available at http://www.apache.org/licenses/LICENSE-2.0.html.*/
44
import mapboxgl from 'mapbox-gl';
5+
import { decryptSources } from './decryptSource';
6+
import { getServiceKey } from '@supermap/iclient-common/util/EncryptRequest';
57

68
/**
79
* @function MapExtend
810
* @description 扩展了 mapboxgl.Map 对图层相关的操作。
911
* @private
1012
*/
1113
export var MapExtend = (function () {
14+
if (mapboxgl.VectorTileSource.prototype.beforeLoadBak === undefined) {
15+
mapboxgl.VectorTileSource.prototype.beforeLoadBak = mapboxgl.VectorTileSource.prototype.beforeLoad;
16+
mapboxgl.VectorTileSource.prototype.beforeLoad = async function (id, options) {
17+
const url = options && options.tiles && options.tiles[0];
18+
if (decryptSources.values.includes(id) && url) {
19+
const decryptKey = await getServiceKey(url);
20+
this.decryptKey = decryptKey;
21+
}
22+
this.beforeLoadBak(id, options);
23+
};
24+
}
1225
mapboxgl.Map.prototype.overlayLayersManager = {};
1326
if (mapboxgl.Map.prototype.addLayerBak === undefined) {
1427
mapboxgl.Map.prototype.addLayerBak = mapboxgl.Map.prototype.addLayer;

src/mapboxgl/core/decryptSource.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* @name decryptSources
3+
* @namespace
4+
* @category BaseTypes Util
5+
* @description 配置需要解密的矢量瓦片的sourceId。
6+
* @usage
7+
* ```
8+
* // 浏览器
9+
* <script type="text/javascript" src="{cdn}"></script>
10+
* <script>
11+
* const result = {namespace}.decryptSources.set(sourceIdsArray);
12+
*
13+
* </script>
14+
* // ES6 Import
15+
* import { decryptSources } from '{npm}';
16+
*
17+
* const result = decryptSources.set(sourceIdsArray);
18+
* ```
19+
*/
20+
const decryptSources = {
21+
values: [],
22+
/**
23+
* @function decryptSources.set
24+
* @description 设置需要解密的矢量瓦片的sourceId数组
25+
* @param {Array.<string>} sourceIds sourceId数组
26+
* @returns {Array.<string>} sourceId数组
27+
*/
28+
set(sourceIds) {
29+
this.values = sourceIds;
30+
return this.values;
31+
},
32+
/**
33+
* @function decryptSources.add
34+
* @description 添加需要解密的矢量瓦片的sourceId
35+
* @param {string} sourceId sourceId
36+
* @returns {Array.<string>} sourceId
37+
*/
38+
add(sourceId) {
39+
this.values.push(sourceId);
40+
return this.values;
41+
}
42+
};
43+
44+
export { decryptSources };

src/mapboxgl/core/index.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/* Copyright© 2000 - 2023 SuperMap Software Co.Ltd. All rights reserved.
22
* This program are made available under the terms of the Apache License, Version 2.0
33
* which accompanies this distribution and is available at http://www.apache.org/licenses/LICENSE-2.0.html.*/
4-
export {Util} from './Util';
5-
export {MapExtend} from './MapExtend';
4+
export { Util } from './Util';
5+
export { MapExtend } from './MapExtend';
6+
export { decryptSources } from './decryptSource';

src/mapboxgl/namespace.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* This program are made available under the terms of the Apache License, Version 2.0
33
* which accompanies this distribution and is available at http://www.apache.org/licenses/LICENSE-2.0.html.*/
44
import { Logo } from './control';
5-
import { Util } from './core';
5+
import { Util, decryptSources } from './core';
66
import {
77
GraphThemeLayer,
88
LabelThemeLayer,
@@ -69,10 +69,10 @@ import mapboxgl from 'mapbox-gl';
6969

7070
mapboxgl.supermap = {...SuperMap, ...mapboxgl.supermap};
7171
mapboxgl.supermap.map = mapboxgl.supermap.map || {};
72-
7372
mapboxgl.supermap.LogoControl = Logo;
7473
mapboxgl.supermap.Logo = Logo;
7574
mapboxgl.supermap.Util = Util;
75+
mapboxgl.supermap.decryptSources = decryptSources;
7676
mapboxgl.supermap.WebMap = WebMap;
7777
mapboxgl.supermap.initMap = initMap;
7878
mapboxgl.supermap.Graphic = Graphic;

test/mapboxgl/core/MapExtendSpec.js

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
import mapboxgl from 'mapbox-gl';
2+
import mbglmap from '../../tool/mock_mapboxgl_map';
3+
import { FetchRequest } from '../../../src/common/util/FetchRequest';
4+
import cipher from 'node-forge/lib/cipher';
5+
import { MapExtend } from '../../../src/mapboxgl/core/MapExtend';
6+
import { decryptSources } from '../../../src/mapboxgl/core/decryptSource';
7+
8+
describe('getServiceKey', () => {
9+
let originalTimeout;
10+
const url = 'http:/fake:8090/iserver/iserver/services/map-China107/rest/maps/A';
11+
MapExtend;
12+
beforeEach(() => {
13+
spyOn(mapboxgl, 'Map').and.callFake(mbglmap);
14+
window.atob = () =>
15+
`ú\x86\x00ë\x14ø\n0Ø\x9C¶¬\x1D\x16ü\x99\x19rì;c\x8A\x8F\x83» þH©ü*TÂ.ÒxæêÏKëÔ|^¯à\x14*h\x96à\x80\x1E|\x8E¢\x8F)ÔÐ÷Á-/ì@iCð×F7û\x8B\x01k\x13\x18\x9BA\x88\x923]bSáÒLºÎ\v[váÐÁÆZi\x87\x1DþV\x91o\x97\x02~rÃñ¾\x051¥¬\x1CL\x01úºüê\x95\x0EEs¸/\\{6\x9A\x9DwRËÂ{¨~6T\x91\x19\x12\x1C_\x9Bb÷vhB\f{\x03éØ\x19w-Âϳ/\x1B»²C²\x1F\x97¢\x99\x88C\x8DÁCÂ8ð\x96t)ZùÞÓ\x03¨f\x1E´*\x97\x8Fµ±´í\x8B\x9ChíMlÅ\x06\x9Biþ\x03k¢\x83\x9A\x95\x8Fé\x03ùÓ¶N\x02qR?CÙê·Æ\x89\x854 ÞÐÒræéø¢]\x81ú®Ã0\x89ßMòPkå²E\x8DF\x1C¶æ\x84Bj¦\x99'[CÁ\x14ýaP\x1AÛu ×úHÃ:.\x1Eû\x0Eå\x0Féê\x91\x82ÓKÞ6T\x92é6©\x91v¨\f\x1A\x85·\x02¾\x87͵V[ç\x14DÑ8\x1Bm\x82ö\x1BBÿ\x87þí¬§f´¶\x9Fé\x1Ds¼:µt@\x15Í\x96bÛ"ý\x16~H0¥#l®\x02b`;
16+
cipher.createDecipher = () => ({
17+
start: () => {},
18+
update: () => {},
19+
finish: () => true,
20+
output: {
21+
data: `{"headers":{"X-Frame-Options":"SAMEORIGIN","Access-Control-Expose-Headers":"Access-Control-Allow-Origin,Access-Control-Allow-Credentials","Access-Control-Allow-Origin":"*","Set-Cookie":"rememberMe=deleteMe; Path=/iserver; Max-Age=0; Expires=Tue, 19-Mar-2024 01:43:12 GMT; SameSite=lax"},"data":"P8h08GonNjuCB4+CAykAGmLYwNsiv4G6H8KFrFi7Afk=","status":200}`
22+
}
23+
});
24+
spyOn(FetchRequest, 'get').and.callFake((url) => {
25+
if (url.includes('map-China107')) {
26+
return Promise.resolve(
27+
new Response(
28+
JSON.stringify([
29+
{
30+
componentType: 'com.supermap.services.components.impl.MapImpl',
31+
interfaceType: 'com.supermap.services.rest.RestServlet',
32+
additions: [
33+
'China',
34+
'China_4326',
35+
'ChinaDark',
36+
'China_4490',
37+
'China_4610',
38+
'China_4214',
39+
'China1',
40+
'China_Capital_pt@China',
41+
'A'
42+
],
43+
name: 'map-China107/rest',
44+
alias: 'map-China107',
45+
serviceEncryptInfo: {
46+
encrptSpec: {
47+
keyLength: 256,
48+
attributes: 'abcd',
49+
version: '1.1',
50+
algorithm: 'AES'
51+
},
52+
updateTime: 'Tue Mar 19 09:34:18 CST 2024',
53+
encrptKeyID: 'keyIDNAME'
54+
},
55+
url: 'http://fake:8090/iserver/services/map-China107/rest',
56+
status: 'OK'
57+
},
58+
{
59+
componentType: 'com.supermap.services.components.impl.MapImpl',
60+
interfaceType: 'com.supermap.services.rest.JaxrsServletForJersey',
61+
additions: [
62+
'China',
63+
'China_4326',
64+
'ChinaDark',
65+
'China_4490',
66+
'China_4610',
67+
'China_4214',
68+
'China1',
69+
'China_Capital_pt@China',
70+
'A'
71+
],
72+
name: 'map-China107/restjsr',
73+
alias: 'map-China107',
74+
serviceEncryptInfo: {
75+
encrptSpec: {
76+
keyLength: 256,
77+
attributes: 'abcd',
78+
version: '1.1',
79+
algorithm: 'AES'
80+
},
81+
updateTime: 'Tue Mar 19 09:34:18 CST 2024',
82+
encrptKeyID: 'keyIDNAME'
83+
},
84+
url: 'http://fake:8090/iserver/services/map-China107/restjsr',
85+
status: 'OK'
86+
}
87+
])
88+
)
89+
);
90+
}
91+
if (url.includes('publickey')) {
92+
return Promise.resolve(
93+
new Response(
94+
JSON.stringify({
95+
keyLength: 2048,
96+
publicKey:
97+
'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnYZxbL+oTbMDGQsFtVR674Zm/v04PhupLBrnm+BRja0bKV0zEsIWNUJ+fcOHBimCBPlU1ykZa2zibKRy+NOsfAIXUjd33Q8dPOOoF3m2ydbDxL7v6PB+f38jyXmvLd8EgyiMFuYUBvbnrHDPuodjWWUqNqdaBFl4wqp2fKTjsmsHevDwsf3plnCOu7mfsTemzCqlnD6W2uGbS71VI91VmYfIQMbExixAXjQ6CT35sV4b3CHmxhq+BrKnsiVpxvNrLkWrcli0DQDz1Opv7NdiGtw+bHNN2kxcQym/uDP3ClXDPmCYzsvB+GIW5GM78b7nsZjYy8VHjtyVdAkQwY27jQIDAQAB',
98+
keyScheme: 'PKCS#8'
99+
})
100+
)
101+
);
102+
}
103+
if (url.includes('vectorstyles')) {
104+
return Promise.resolve(new Response(JSON.stringify({})));
105+
}
106+
});
107+
spyOn(FetchRequest, 'post').and.callFake((url) => {
108+
if (
109+
url.includes(
110+
'tunnels/RmcvL1VHcVcyZU1ldXk5bW5rbGFTdkI4b1owWnRUVGg5K0E5aGo3MUQrTWRDbWdnMzhwSWlGSjRydFJoV0s4YjJlSjJZWHBoUnRRRnNMVDlLc3hmdXZDOFRqUnYzMUJtcXVqa0VTRE05Ukx2QjZLVTh2VGZUVzRndlM4Rmw4b1BsNTVNUVYzL215WXJIbkE4MC9GZzcrZnhrRUY2YUpsMmI1azBtQmljREZMUnREUkljdVBuWGFhK01jWmtUZDFUZjUxUnkwSlNsUFRuR1ZoWGV3VmZnOFI2bnM5K01yWWtPZm1kVnJManUxVmh5NUlIRmEyZXNUbzRHVDVKR3I2ZHpkOWVwRXFGdFdaMmxMMFM2YmhjNEorZHlvZXVQMmg3VGlCOGVYV1FJanE4bVYvcTNTRE5JRjRqR2RkSkJ6MENRSmVqcXpTbVdidnRxNm5jdDlmeDZBPT0='
111+
)
112+
) {
113+
return Promise.resolve(
114+
new Response(
115+
'4xwVfv35tWo01yLmIV8Yf5t+lJUl8kERVP9aOH+x/1iynjFKx6cpbxCPPCTvUK5RlX3xjFGMMz+hBTOt7Ke911tE8wlUkClWMNuDbJGdxuinM2BF9MyBd6U7NNiwSWvfk3tRdY8+sGlquYyXRRc1HTkKUSoaJNhqgx9xZMi740AxArOINgOqBnl1tS2i5R2MyjyJcrYDUfjb8wZL5LLU/y/jysUCBtiNrrdlY3hV1BgtWUSgHPdTSxXA595CbdK3Nx0DhGIhNCQWby9QJUDhTHAqsdcWYyTAozMf/J8Q8vmwf2pHEMbvWyq0Etstg6IJeUqcdPG2XNcmNX3/xpsgjseg1/AJhvMnv1morsXNsN+hDYg8NJgCyZ6fnTL2EC5y3ivhNgzccFIgPcaZRtAveOx3iiU8SAy9hP3tkR5toqeZsU//8awh4RZgFDDM+QKX7ipUVO+YihkIYmNlXwMMpsSg2SMKfeqUV/3D8CvxQZPlTA=='
116+
)
117+
);
118+
}
119+
if (url.includes('tunnels')) {
120+
return Promise.resolve(
121+
new Response(
122+
JSON.stringify({
123+
blockedUrlRegex: {
124+
DELETE: [],
125+
POST: [
126+
'.*/_setup/v2/querylicense.?(json|rjson)',
127+
'.*/services/security/login.?(json|rjson)',
128+
'.*/services/security/tokens.?(json|rjson)',
129+
'.*/manager/serviceSynchronizingJobs.?(json|rjson)',
130+
'.*/services/geoprocessing/restjsr/gpmodeler/runmodel',
131+
'.*/services/geoprocessing/restjsr/gpmodeler/modelui'
132+
],
133+
GET: [
134+
'.*/_setup/v2.?(json|rjson)',
135+
'.*/_setup/v2/currentlicense.?(json|rjson)',
136+
'.*/_setup.?(json|rjson)',
137+
'.*/_setup/currentuserlicenseinfo.?(json|rjson)',
138+
'.*/services/geoprocessing/restjsr/gpmodeler/list/.*/property',
139+
'.*/services/security/svckeys/[a-zA-Z]+\\.json'
140+
],
141+
PUT: [
142+
'.*/_setup/v2.?(json|rjson)',
143+
'.*/_setup/v2/querylicense.?(json|rjson)',
144+
'.*/_setup/v2/activelicense.?(json|rjson)',
145+
'.*/_setup.?(json|rjson)',
146+
'.*/_setup/cloudlicenselogin.?(json|rjson)',
147+
'.*/_setup/weblicense.?(json|rjson)',
148+
'.*/_setup/edulicense.?(json|rjson)',
149+
'.*/_setup/activecloudlicense.?(json|rjson)',
150+
'.*/_setup/activeWebLicense.?(json|rjson)',
151+
'.*/_setup/activeEduLicense.?(json|rjson)',
152+
'.*/services/security/profile.?(json|rjson)',
153+
'.*/manager/servicestorage.?(json|rjson)',
154+
'.*/services/geoprocessing/restjsr/gpmodeler/list/.*/property'
155+
]
156+
},
157+
tunnelUrl:
158+
'http://fake:8090/iserver/services/security/tunnel/v1/tunnels/RmcvL1VHcVcyZU1ldXk5bW5rbGFTdkI4b1owWnRUVGg5K0E5aGo3MUQrTWRDbWdnMzhwSWlGSjRydFJoV0s4YjJlSjJZWHBoUnRRRnNMVDlLc3hmdXZDOFRqUnYzMUJtcXVqa0VTRE05Ukx2QjZLVTh2VGZUVzRndlM4Rmw4b1BsNTVNUVYzL215WXJIbkE4MC9GZzcrZnhrRUY2YUpsMmI1azBtQmljREZMUnREUkljdVBuWGFhK01jWmtUZDFUZjUxUnkwSlNsUFRuR1ZoWGV3VmZnOFI2bnM5K01yWWtPZm1kVnJManUxVmh5NUlIRmEyZXNUbzRHVDVKR3I2ZHpkOWVwRXFGdFdaMmxMMFM2YmhjNEorZHlvZXVQMmg3VGlCOGVYV1FJanE4bVYvcTNTRE5JRjRqR2RkSkJ6MENRSmVqcXpTbVdidnRxNm5jdDlmeDZBPT0='
159+
})
160+
)
161+
);
162+
}
163+
});
164+
originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
165+
jasmine.DEFAULT_TIMEOUT_INTERVAL = 50000;
166+
});
167+
168+
afterEach(() => {
169+
jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
170+
});
171+
172+
it('getServiceKey', async () => {
173+
try {
174+
const source = {
175+
tiles: [
176+
'http://172.16.13.234:8090/iserver/services/map-China107/rest/maps/A/tileFeature.mvt?returnAttributes=true&width=512&height=512&z={z}&x={x}&y={y}'
177+
],
178+
bounds: [-180, -90, 180, 90],
179+
type: 'vector'
180+
};
181+
const vectorSource = new mapboxgl.VectorTileSource('A', source, () => {}, {});
182+
await vectorSource.beforeLoad('A', source);
183+
expect(vectorSource.decryptKey).toEqual(undefined);
184+
decryptSources.set(['A']);
185+
decryptSources.add('B');
186+
expect(decryptSources.values).toEqual(['A', 'B']);
187+
await vectorSource.beforeLoad('A', source);
188+
expect(vectorSource.decryptKey).toEqual('P8h08GonNjuCB4+CAykAGmLYwNsiv4G6H8KFrFi7Afk=');
189+
} catch (error) {
190+
expect(error).toEqual(new Error('mapbox-gl cannot support plane coordinate system.'));
191+
}
192+
});
193+
});

test/test-main-mapboxgl.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,4 @@ import './mapboxgl/services/ChartServiceSpec';
7575
/*mapboxgl -- mapping*/
7676
import './mapboxgl/mapping/WebMapSpec.js';
7777
import './mapboxgl/mapping/InitMapSpec.js';
78+
import './mapboxgl/core/MapExtendSpec.js';

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy