# 接入安全éšç§æ¡†æž¶ 安全éšç§æŽ¥å…¥æ¡†æž¶å…许两ç§æŽ¥å…¥æ–¹å¼ï¼šExtensionAbilityå’ŒUIAbilityæ–¹å¼æŽ¥å…¥ã€‚ 应用接入åŽï¼Œå°†æŒ‰ç…§bundleNameçš„å—æ¯é¡ºåºåœ¨éšç§ä¸å¿ƒå±•ç¤ºã€‚ 业务接入方需在本应用模å—下的module.json5é…置文件ä¸é…置相应的actionå’Œmetadata,供安全éšç§ä¸å¿ƒèœå•æŽ¥å…¥æ¡†æž¶æ‰«æã€è§£æžã€‚ å¼€å‘者å¯å‚考以下æ¥éª¤ï¼Œå®Œæˆå¯¹å®‰å…¨éšç§æ¡†æž¶çš„接入。 ## 新增元数æ®èµ„æºé…置文件 业务接入方需è¦æ–°å¢žä¸€ä¸ªå…ƒæ•°æ®èµ„æºé…ç½®json文件,用于承载接入安全éšç§æ¡†æž¶çš„æ–¹å¼ã€è·³è½¬çš„Abilityç‰å†…容,具体å—段说明如表所示: | key值(属性å称) | value值 | 是å¦å¿…å¡« | 说明 | | ----------------- | ------------------------------------------------------------ | -------- | ------------------------------------------------- | | displayedMode | - list:代表列表方å¼æŽ¥å…¥ã€‚<br />- card:代表å¡ç‰‡æ–¹å¼æŽ¥å…¥ï¼Œå½“å‰ç‰ˆæœ¬æš‚ä¸æ”¯æŒã€‚ | 是 | ç›®å‰ä»…支æŒåˆ—表展示,输入card/listå‡æŒ‰ç…§åˆ—表展示。 | | mainTitleResource | å…¥å£èœå•æ˜¾ç¤ºçš„ä¸»æ ‡é¢˜å—串的资æºå | 是 | - | | dstAbilityMode | - 0: 表示被拉起的ability为UIAbility。<br />- 1: 表示被拉起的ability为UIExtensionAbility。 | 是 | - | | dstAbilityName | è·³è½¬çš„ç›®æ ‡Ability。<br />- 当dstAbilityMode为0时,该ability为UIAbility。<br />- 当dstAbilityMode为1时,该ability需继承自UIExtensionAbility,接入方在æ¤abilityä¸åŠ 载自身页é¢ã€‚ | 是 | - | | dstBundleName | 跳转的目的bundleå称。 | 是 | - | | displayUserConfig | - ONLY_PRIMARY_USER:仅主用户展示。<br />- ONLY_SUB_USER:仅å用户展示。 | å¦ | 如果ä¸å¡«ï¼Œé»˜è®¤ä¸ºå‘所有用户展示。 | 本文档ä¸ä»¥æ–°å»ºä¸€ä¸ªsecurity_privacy.json文件为例,æ¥æŒ‡å¯¼ä¸šåŠ¡æŽ¥å…¥æ–¹å®Œæˆé…置,实际的json文件的å称å¯ç”±å¼€å‘者自定义。 æ¤æ–‡ä»¶éœ€æ”¾ç½®åœ¨å¯¹åº”模å—çš„`"resource/rawfile/xxx.json"`ä¸ã€‚ ```json { "displayedMode": "list", "mainTitleResource": "$string:main_title", "dstAbilityMode": 0, "dstAbilityName": "EntryAbility", "dstBundleName": "com.example.test" } ``` ## 修改应用é…置文件 å„模å—çš„module.json5é…置文件ä¸ï¼Œæ‰¿è½½äº†è¯¥æ¨¡å—UIAbility组件和ExtensionAbility组件的æè¿°ä¿¡æ¯ã€åº”用è¿è¡Œè¿‡ç¨‹ä¸æ‰€éœ€çš„æƒé™ç‰ä¿¡æ¯ã€‚接入安全éšç§æ¡†æž¶éœ€å°†ä¸€ä¸‹ç›¸å…³å—段é…置到module.json5ä¸ã€‚ ### é…ç½®action 在module.json5文件的“ skill â€æ ‡ç¾ä¸ï¼Œé…ç½®éšç§ä¸å¿ƒçš„action值`"action.access.privacy.center"`。 ```typescript "skills": [ { "actions": [ "action.access.privacy.center" ] } ] ``` ### é…ç½®metadata 在module.json5文件的“ metadata â€æ ‡ç¾ä¸ï¼Œæ–°å¢žâ€œ name â€ä¸ºâ€œ metadata.access.privacy.center â€ã€â€œ value â€ä¸ºå…ƒæ•°æ®json文件å称的æ¡ç›®ã€‚ 元数æ®json文件å³ä¸ºä¸Šä¸€æ¥æ–°å¢žçš„`"resource/rawfile/xxx.json"`。 > **说明:** > > å¼€å‘者需è¦æ ¹æ®dstAbilityModeæ¥é€‰æ‹©actionã€metadataçš„é…置。 > > - 如果被拉起的页é¢æ˜¯UIAbility,则需é…置到“ abilities â€ä¸ï¼Œ > > - 如果是UIExtensionAbility,则需é…置到“ extensionAbilities †ä¸ã€‚ > > **在é…ç½®extensionAbilities时,其ä¸type类型需é…ç½®æˆ"sys/commonUI"。** 当å‰ç¤ºä¾‹ä»…æ供接入安全éšç§æ¡†æž¶æ¶‰åŠçš„æ ‡ç¾ç”¨æ³•ï¼Œmodule.json5ä¸çš„å…¶ä½™æ ‡ç¾å—段,需è¦å¼€å‘è€…æ ¹æ®å®žé™…情况填写。 ```typescript // UIAbilityæ–¹å¼æŽ¥å…¥ "abilities": [ { "skills": [ { "actions": [ "action.access.privacy.center" ] } ], "metadata": [ { "name": 'metadata.access.privacy.center', "value": 'security_privacy.json' } ] } ] ``` ```typescript // ExtensionAbilityæ–¹å¼æŽ¥å…¥ "extensionAbilities": [ { "type": "sys/commonUI", "skills": [ { "actions": [ "action.access.privacy.center" ] } ], "metadata": [ { "name": 'metadata.access.privacy.center', "value": 'security_privacy.json' } ] } ] ``` ### é…ç½®æƒé™ 业务接入方需申请æƒé™[ohos.permission.ACCESS_SECURITY_PRIVACY_CENTER](../AccessToken/permissions-for-system-apps.md#ohospermissionaccess_security_privacy_center),æ¥ç¡®ä¿åº”用å¯ä»¥æŽ¥å…¥æ¡†æž¶èœå•ã€‚ 申请方å¼è¯·å‚考[访问控制开å‘指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/security/AccessToken/determine-application-mode.md)。 ## é…ç½®Ability页é¢ï¼ˆä»¥UIAbilityæ–¹å¼æŽ¥å…¥ï¼‰ 如果为UIAbilityæ–¹å¼æŽ¥å…¥ï¼Œåˆ™ä¸éœ€è¦å•ç‹¬åšç›¸å…³çš„é…置,直接使用默认生æˆçš„æ–¹å¼ã€‚ 示例: ```typescript import AbilityConstant from '@ohos.app.ability.AbilityConstant'; import hilog from '@ohos.hilog'; import UIAbility from '@ohos.app.ability.UIAbility'; import Want from '@ohos.app.ability.Want'; import window from '@ohos.window'; export default class EntryAbility extends UIAbility { onWindowStageCreate(windowStage: window.WindowStage): void { // Main window is created, set main page for this ability hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); windowStage.loadContent('pages/Index', (err, data) => { if (err.code) { hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); return; } hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); }); } } ``` ## é…ç½®Ability页é¢ï¼ˆä»¥ExtensionAbilityæ–¹å¼æŽ¥å…¥ï¼‰ 如果为ExtensionAbilityæ–¹å¼æŽ¥å…¥ï¼ŒAbility页é¢éœ€ç»§æ‰¿è‡ªExtensionAbility,并且需修改相应é…置,使用sessionçš„æ–¹å¼æ¥æ‹‰èµ·æŽ¥å…¥åº”用的主页é¢ã€‚ 示例: ```typescript import hilog from '@ohos.hilog'; import Want from '@ohos.app.ability.Want'; import ExtensionAbility from '@ohos.app.ability.ExtensionAbility'; import UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession'; export default class EntryAbility extends ExtensionAbility { onSessionCreate(want: Want, session: UIExtensionContentSession) { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onSessionCreate'); let param: Record<string, Object> = { 'session': session } let storage: LocalStorage = new LocalStorage(param) session.loadContent('pages/Index', storage) } } ``` ## 接入页é¢é€€å‡ºï¼ˆä»¥UIAbilityæ–¹å¼æŽ¥å…¥ï¼‰ 如果是UIAbilityçš„æ–¹å¼æŽ¥å…¥ï¼ŒæŽ¥å…¥æ–¹éœ€ä¸»åŠ¨é€€å‡ºæ—¶ï¼Œä¾‹å¦‚页é¢æœ‰è¿”回按钮,想è¦é”€æ¯åº”用的页é¢æ—¶ï¼Œå¯ä»¥ç›´æŽ¥è°ƒç”¨router.back()或者terminateSelf()æ¥é”€æ¯å½“å‰é¡µé¢ã€‚ 示例: ```typescript import router from '@ohos.router'; @Entry() @Component struct Index { build() { Row() { Column() { Button("click to back") .onClick(() => { router.back() }) } .width('100%') } .height('100%') } } ``` ## 接入页é¢é€€å‡ºï¼ˆä»¥ExtensionAbilityæ–¹å¼æŽ¥å…¥ï¼‰ 如果是UIExtensionAbilityçš„æ–¹å¼æŽ¥å…¥ï¼ŒæŽ¥å…¥æ–¹éœ€ä¸»åŠ¨é€€å‡ºæ—¶ï¼Œä¾‹å¦‚页é¢æœ‰è¿”回按钮,想è¦é”€æ¯åº”用的页é¢æ—¶ï¼Œå¯ä»¥é€šè¿‡UIExtensionContentSessionçš„sendDataå‘使用方å‘é€æ•°æ® `{“actionâ€: "exit"}`,使用方接收到消æ¯ä¹‹åŽå°†é€€å‡ºæ‹‰èµ·çš„页é¢ã€‚ 示例: ```typescript import UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession' let storage = LocalStorage.getShared() @Entry(storage) @Component struct Index { private session: UIExtensionContentSession = storage.get<UIExtensionContentSession>('session') as UIExtensionContentSession build() { Row() { Column() { Button("click to back") .onClick(() => { this.session.sendData({ 'action': "exit" }) }) } .width('100%') } .height('100%') } } ```