当两者都使用相同的密钥签名时,从 App2 访问 App1 的内容提供者

Accessing a content provider of App1 from App2 when both are signed with the same key

我有 App1 和这个 build.gradle(app 文件夹中的那个)文件

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "26.0.1"
    defaultConfig {
        applicationId "com.example.security.app1"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    signingConfigs {
        debug {
            storeFile file("androidKey.jks")
            storePassword "StorePass123"
            keyAlias "MyAndroidKey"
            keyPassword "KeyPass123"
            v2SigningEnabled false
        }
        release {
            storeFile file("androidKey.jks")
            storePassword "StorePass123"
            keyAlias "MyAndroidKey"
            keyPassword "KeyPass123"
            v2SigningEnabled false
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
        debug {
            minifyEnabled false
            signingConfig signingConfigs.debug
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
}

androidKey.jks 也在应用程序文件夹中。应用程序的清单文件是这个

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.security.app1">
    <permission android:name="${applicationId}.providerPermission"
                android:protectionLevel="signature"/>
    <uses-permission android:name="${applicationId}.providerPermission" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <provider
            android:enabled="true"
            android:exported="true"
            android:authorities="${applicationId}.provider"
            android:name=".ContentProviderSecured"
            android:readPermission="${applicationId}.providerPermission">
        </provider>
    </application>
</manifest>

在 app1 中我可以访问 ContentProvider

readCursor("com.example.security.app1.provider");
    private void readCursor(String pAuthority) {
        Cursor c = null;
        try {
            c = getContentResolver().query(Uri.parse("content://" + pAuthority + "/query"), null, null, null, null);
            String res = "Result" + c.getCount() + c.getColumnNames()[0].toString();
            Toast.makeText(getApplicationContext(), res, Toast.LENGTH_LONG).show();
        }catch (Exception e){
            Log.d("Result", "Cannot access provider");
        }finally {
            if (c!=null){
                c.close();
            }
        }
    }

但是 app2 中的相同代码给了我一个权限拒绝。 App2 在其 app 文件夹中具有相同的密钥库,其 build.gradle 与 app1 build.gradle 文件相同。这些是我用来创建密钥的设置(其中一个设置 windows,其余设置是创建密码 - 我在 build.gradle 文件中使用的设置)http://pokit.org/get/?e983d5190e38ad24c59158b87b6cedb0.jpg。有谁知道我做错了什么——我相信这与签名有关,因为如果我从内容提供商那里删除该许可,我就可以访问它。谢谢。

but the same code in app2 gives me a Permission denial.

app2 显然没有 ${applicationId}.providerPermission 权限。您需要在 app2 的清单中为该自定义权限添加 <uses-permission> 属性。此外,要么 app2 需要在 app1 之后安装,要么 app2 也需要 <permission> 元素。

此外,如果您的 minSdkVersion 低于 21,请记住 there are security flaws inherent with custom permissions