このドキュメントでは、アプリのデベロッパーが Android のセキュリティ機能を使用して、独自の権限を定義する方法について説明します。カスタム権限を定義することで、アプリは他のアプリとリソースや機能を共有できます。権限の詳細については、権限の概要をご覧ください。
背景
Android は、権限が分離されたオペレーティング システムで、各アプリは個別のシステム ID(Linux ユーザー ID とグループ ID)で実行されます。システムの一部は、個別の ID にも分割されます。これにより、Linux はアプリ同士やシステム間でアプリを分離します。
アプリは、他のアプリが要求できる権限を定義して、アプリの機能を他のアプリに対して公開できます。また、同じ証明書で署名された他のアプリで自動的に使用できるようになる権限も定義できます。
アプリ署名
APK はすべて、デベロッパーが秘密鍵を保持する証明書で署名する必要があります。この証明書は、アプリの作成者を識別します。証明書は、認証局による署名を必要としません。Android アプリでは通常、自己署名証明書を使用することが問題なく許可されます。Android における証明書の目的は、アプリの作成者を区別することです。これにより、システムはアプリに対して署名レベルの権限へのアクセスを許可または拒否し、別のアプリと同じ Linux ID の付与に関するリクエストを許可または拒否できます。
ユーザー ID とファイル アクセス
インストール時に、Android は各パッケージに個別の Linux ユーザー ID を付与します。ID は、そのデバイスのパッケージの有効期間中は変わりません。別のデバイスでは、同じパッケージの UID が異なる場合があります。重要なのは、各パッケージが特定のデバイスで識別できる UID を持つことです。
セキュリティの適用はプロセスレベルで行われるため、2 つのパッケージのコードは通常、異なる Linux ユーザーとして実行する必要があることから、同じプロセスでは実行できません。各パッケージで AndroidManifest.xml
の manifest タグの sharedUserId 属性を使用して、同じユーザー ID を割り当てることができます。これにより、セキュリティ上、2 つのパッケージは、同じユーザー ID とファイル権限を持つ同じアプリとして扱われます。セキュリティを維持するため、同じ署名で署名された(同じ sharedUserId をリクエストする)2 つのアプリのみが、同じユーザー ID を付与される点に留意してください。
アプリによって保存されたデータには、そのアプリのユーザー ID が割り当てられ、通常は他のパッケージからはアクセスできません。
Android のセキュリティ モデルの詳細については、Android のセキュリティの概要をご覧ください。
権限の定義と適用を行う
独自の権限を適用するには、まず AndroidManifest.xml
で 1 つ以上の <permission>
要素を使用して、その権限を宣言する必要があります。
たとえば、誰がアクティビティの 1 つを開始できるかを制御する必要があるアプリでは、このオペレーションの権限を次のように宣言できます。
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp" > <permission android:name="com.example.myapp.permission.DEADLY_ACTIVITY" android:label="@string/permlab_deadlyActivity" android:description="@string/permdesc_deadlyActivity" android:permissionGroup="android.permission-group.COST_MONEY" android:protectionLevel="dangerous" /> ... </manifest>
注: すべてのパッケージが同じ証明書を使用して署名されている場合を除き、複数のパッケージで同じ名前の権限を宣言することはできません。パッケージで権限を宣言すると、ユーザーは同じ権限名の他のパッケージをインストールできなくなります(他のパッケージが最初のパッケージと同じ証明書を使用して署名されている場合を除く)。名前の競合を回避するために、カスタムの権限には逆ドメイン形式の名前(例: com.example.myapp.ENGAGE_HYPERSPACE
)を使用することをおすすめします。
リンク先のドキュメントに記載されているように、権限が必要なアプリについてユーザーに通知する方法や、誰がその権限を持つことを許可されるのかについてシステムに指示する
protectionLevel
属性が必要です。
android:permissionGroup
属性はオプションで、システムがユーザーに権限を表示できるようにするためにのみ使用されます。ご自分でグループを定義できますが、ほとんどの場合、この属性を標準システム グループ(android.Manifest.permission_group
に記載)に設定する必要があります。
ユーザーに表示される権限 UI が簡略化されることから、既存のグループの使用をおすすめします。
権限のラベルと説明の両方を指定する必要があります。これらの文字列リソースは、ユーザーが権限のリスト(android:label
)または、1 つの権限の詳細(android:description
)を表示しているときに表示できます。ラベルは短くする必要があり、数個の単語を使用して権限が保護している重要な機能を説明するようにします。説明は、権限が所有者に実行を許可する内容を説明する一組の文にします。通常は 2 つの文で説明します。1 文目は権限について説明し、2 文目は、アプリに権限が付与された場合に、発生する可能性があるエラーの種類についてユーザーに警告します。
以下に CALL_PHONE
権限のラベルと説明の例を示します。
<string name="permlab_callPhone">directly call phone numbers</string> <string name="permdesc_callPhone">Allows the app to call phone numbers without your intervention. Malicious apps may cause unexpected calls on your phone bill. Note that this does not allow the app to call emergency numbers.</string>
権限グループを作成する
前のセクションで説明したように、android:permissionGroup
属性を使用して、システムがユーザーに権限を説明するようにできます。ほとんどの場合、標準のシステム グループ(android.Manifest.permission_group
に記載)に設定することをおすすめしますが、<permission-group>
を使用して独自のグループを定義することもできます。
<permission-group>
要素は、権限セット(<permission>
要素を使用してマニフェストで宣言されている権限と他の場所で宣言されている権限の両方)のラベルを定義します。これは、ユーザーに表示された際の権限のグループ化方法にのみ影響します。<permission-group>
要素は、グループに属する権限を指定しませんが、グループに名前を付与します。
グループに権限を割り当てるには、グループ名を <permission>
要素の permissionGroup
属性に割り当てます。
<permission-tree>
要素は、コードで定義されている権限のグループの名前空間を宣言します。
カスタム権限についての推奨事項
アプリは独自のカスタム権限を定義でき、また <uses-permission>
要素を定義することで他のアプリのカスタム権限をリクエストできます。ただし、これをアプリで行う必要があるかどうか、慎重に判断する必要があります。
- 互いに機能を公開する一連のアプリを設計する場合は、それぞれの権限が 1 回のみ定義されるようにアプリを設計してください。アプリがすべて同じ証明書で署名されているわけではない場合は、このようにする必要があります。アプリがすべて同じ証明書で署名されていても、各権限を 1 回のみ定義することをおすすめします。
- 機能が、提供元アプリと同じ署名で署名されたアプリでのみ使用できる場合は、署名チェック機能を使用してカスタム権限を定義せずに済ませることができます。いずれかのアプリが別のアプリのリクエストを行うと、2 つ目のアプリはリクエストに応える前に両方のアプリが同じ証明書で署名されていることを確認できます。
続きを読む:
<uses-permission>
- アプリが必要とするシステム権限を宣言するマニフェスト タグの API リファレンス。
その他の情報:
- Android のセキュリティの概要
- Android プラットフォームのセキュリティ モデルに関する詳細な説明。