マニフェストファイルの権限を管理する方法

序文

なぜパーミッションが制御するのですか?プライバシーコンプライアンスはますます厳しくなっているため、機密性の高いアクセス許可の使用は、隐私协议ドキュメント、企業レベルでも、そのようなアクセス許可を適用することは許可されていません。私たちのプロジェクトはコンポーネント開発を採用しているため、一部の小規模なパートナーは、技術的な解決策のために機密性の高い権限を申請する必要がある場合があります。そのため、パートナーは独自のモジュールで権限を'自作主张'直接宣言し、要件の開発とセルフテストを直接実施して、最終的にすぐにオンラインになります。 。セキュリティ部門から、許可は機密性の高い許可であり、適用が許可されていないことが通知されたため、リクエストはバスに乗ることができず、延期されました。権限を統一的に管理する必要があります。機密性の高い権限のアプリケーションは報告および報告する必要があり、小規模なパートナーが開発に機密性の高い権限を導入すると、すぐにエラーを報告できます。オープンを回避するために、早期に抑制不友好される緊急のニーズのために緑。通路。

プログラム

オプション1

マージされたマニフェストファイルを動的に変更し、uses-permissionノードをトラバースし、構成にないアクセス許可が見つかった場合はノードを削除してから、クリーニング後に最終結果を書き戻すか、ここに直接例外をスローします。不一致を出力します。開発者にプロンプ​​トを表示する権限。アドバンテージ:

  • コンパイルおよびパッケージ化時に自動的に解析され、開発者に明確に促すことができます

欠点:

  • プラグインでは構成権限がクローズドソースであるため、現在どの権限が要件を満たしていないかを確認することはできません。コンパイルが失敗した場合にのみ、プロンプトが表示されます。

オプションII

プラグインで構成されたアクセス許可を一時的なマニフェストファイルに出力し、sourceSet.manifestを介してマニフェストファイルをインポートしてコンパイルに参加し、リソースマージルールを使用して機密性の高いアクセス許可を自動的に削除します。公式文書。削除ルールの利点:

  • 一時ファイルを使用して、機密性の高いアクセス許可、保持されるアクセス許可、および削除されるアクセス許可を確認できます。

欠点:

  • コンポーネントモジュールによって宣言された機密権限がメインプロジェクトのマニフェストファイルによってマージおよび削除された場合、プロンプトを表示することはできません。

どちらのスキームも、主にあなた自身の選択に依存する典拠コントロールの効果を達成することができます。この記事で方案二は、

達成

1.メインモジュールのマニフェストファイルを取得し、マニフェストファイルのアクセス許可宣言を削除して、プロジェクトを実行するためにメインモジュールのマニフェストファイルで機密性の高いアクセス許可を小さなパートナーが宣言しないようにします。

// 1、获取 main 下的清单文件,如果找不到,则手动指定清单文件
val mainAndroidManifest = project.extensions.getByType(AppExtension::class.java)
    .sourceSets.find { it.name == "main" }?.manifest?.srcFile
?: File(project.projectDir, "src/main/AndroidManifest.xml")

// 2、读取主工程下清单文件的权限,并从主工程中删除,避免有小伙伴在该文件中提交敏感权限
val parentNode = XmlParser(false, false).parse(mainAndroidManifest)
val childrenNode = parentNode.children()
val permissionNodes = childrenNode.map { it as Node }.filter { it.name() == "uses-permission" }.toList()
if (permissionNodes.isNotEmpty()) {
    // 3、移除所有权限
    childrenNode.removeAll(permissionNodes)
    val xmlText = XmlUtil.serialize(parentNode)
    // 4、回写主工程的清单文件
    mainAndroidManifest.writeText(xmlText)
}

2.一時マニフェストファイルを生成し、プラグインの権限を一時マニフェストファイルに書き戻し、sourceSetを介してコンパイルを導入して参加します。

// 获取插件内配置的权限,并将权限添加进 manifest 节点
getPermission().forEach {
    childrenNode.add(0, Node(null, it))
}
// 将权限写入临时清单文件
val xmlText2 = XmlUtil.serialize(parentNode)
permissionFile.writeText(xmlText2)

project.afterEvaluate {
    // 将生成的临时清单文件添加进 main sourceSet.manifest 中参与项目编译
    project.extensions.getByType(AppExtension::class.java)
        .sourceSets.find { it.name == "main" }?.manifest?.srcFile(permissionFile)
}

ソースコードはPermissionPluginを表示できます

拡張知識(マニフェストファイルのマージ)

優先度のマージ:image.png優先度の最も低いマニフェストファイル(左)から優先度の最も高いマニフェストファイル(右)まで、3つのマニフェストファイルをマージするプロセス。

したがって、コンポーネントモジュールで宣言されたパーミッション(Library)は、メインプロジェクトで宣言されたパーミッション(main)よりも優先度が低いため、削除ルールはメインプロジェクトモジュールで高い優先度で宣言でき、パーミッションは低い優先度で宣言されます。優先度を削除できます。たとえば、次のように削除します。

image.pngインターネット権限のみを保持して、結果をマージします。

image.pngしたがって、私たちは発散的に考えることができます。Android12のエクスポートされた適応については、このルールも使用できますか?コンポーネントで宣言する必要があるエクスポートされたものについては、スクリプトを使用して、コンポーネントと同じノードを処理および生成できます。 。、およびexportedがfalseであることを宣言し、マージに参加するマージノードを追加して、コンポーネントの元の宣言されていないエクスポートを追加する例は次のとおりです。image.pngマージ結果は次のとおりです。

image.png

おすすめ

転載: juejin.im/post/7116145079193960461