Android自定义权限-棉花糖 [英] Android custom permissions - Marshmallow

查看:89
本文介绍了Android自定义权限-棉花糖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景

从历史上看,Android自定义权限一团糟取决于安装顺序,这是公开漏洞.

Historically, Android Custom permissions have been a mess and were install order dependent, which was known to expose vulnerabilities.

在API 21之前,有一个令人不安的变通办法,即在清单中声明另一个应用程序的自定义权限,并授予该权限...但是,自API 21起,只有一个应用程序可以声明自定义权限并安装将会禁止进一步的应用声明相同的许可.

Prior to API 21, there was an unsettling workaround whereby declaring the custom permission of another application in your Manifest, granted the permission... However, since API 21, only one application can declare a custom permission and the installation of a further application declaring this same permission, will be prevented.

替代方法是重新安装需要许可的应用程序,因此系统会检测到它们,但这并非没有理论缺陷.

The alternatives are to reinstall the application requiring the permission, so they are detected by the System, but that is not a good user experience. Or check at runtime for the permissions of the calling application, but that is not without its theoretical flaws.

问题

从Android Marshmallow(6.0-API 23)开始,应用程序需要向用户请求权限,使用其自己的自定义权限.声明的自定义权限不会自动授予.

As of Android Marshmallow (6.0 - API 23) an application needs to request permission from the user, to use its own custom permission. A declared custom permission is not automatically granted.

这似乎很奇怪,因为现在只有一个应用程序可以声明它.

This seems peculiar, given that only one application can now declare it.

要复制

在清单中声明自定义权限和BroadcastReceiver.

Declare the custom permission and a BroadcastReceiver in the Manifest.

<permission
    android:name="com.example.app.permission.CONTROL_EXAMPLE_APP"
    android:description="@string/control_description"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/control_label"
    android:protectionLevel="normal or dangerous"/>

<uses-permission
    android:name="com.example.app.permission.CONTROL_EXAMPLE_APP"/>

// etc

<receiver
    android:name="com.example.app.MyBroadcastReceiver"
    android:permission="com.example.app.permission.CONTROL_EXAMPLE_APP">
    <intent-filter android:priority="999">
        <action android:name="com.example.app.REQUEST_RECEIVER"/>
    </intent-filter>
</receiver>

在第三方应用程序中,声明它使用清单中的自定义权限(并通过对话框或设置接受它)并调用:

From a third-party application, declare that it uses the custom permission in the Manifest (and accept it via a dialog or the settings) and call:

    final Intent intent = new Intent("com.example.app.REQUEST_RECEIVER");

    context.sendOrderedBroadcast(intent, "com.example.app.permission.CONTROL_EXAMPLE_APP", new BroadcastReceiver() {
        @Override
        public void onReceive(final Context context, final Intent intent) {

        // getResultCode();

        }
    }, null, Activity.RESULT_CANCELED, null, null);

结果将返回CANCELED,并且日志将显示:

The result will return CANCELED and the log will show:

system_process W/BroadcastQueue:拒绝权限:接收Intent { act = com.example.app.REQUEST_RECEIVER flg = 0x10(有其他功能)}到 com.example.app/.MyBroadcastReceiver要求 com.example.app.permission.CONTROL_EXAMPLE_APP由于发件人 com.example.thirdparty

system_process W/BroadcastQueue: Permission Denial: receiving Intent { act=com.example.app.REQUEST_RECEIVER flg=0x10 (has extras) } to com.example.app/.MyBroadcastReceiver requires com.example.app.permission.CONTROL_EXAMPLE_APP due to sender com.example.thirdparty

如果我使用标准的ActivityCompat.requestPermissions()对话框来允许用户接受许可,则接收器可以正常工作.

If I use the standard ActivityCompat.requestPermissions() dialog to allow the user to accept the permission, the receiver, as you would expect, works correctly.

问题

这是预期的行为吗?还是我以某种方式忽略了某些东西?

提出一个对话说似乎很荒谬

It would seem ridiculous to raise a dialog saying

示例应用程序的应用程序需要使用示例应用程序的权限

The application Example App wants permission to use Example App

它确实可能与用户有关,向他们提供了这种荒谬的要求.

And it may indeed concern the user, providing them with such a nonsensical request.

我当然可以将权限描述和名称更改为他们可以接受的名称,例如"与其他已安装的应用程序通信",但是在我叹息并采取这种方法之前,我想我会问这个问题.

I can of course change the permission description and name, to something that they would accept, such as 'communicate with other installed applications', but before I sigh and take that approach, I thought I'd ask this question.

注意

有序广播的示例就是要复制该问题.我的应用程序确实使用了内容提供程序和绑定服务的其他实现.这不是我需要的替代实现,它是对问题的确认.

The example of the ordered broadcast is to replicate the problem. My application does use other implementations of content providers and a bound service. It is not an alternative implementation I require, it's confirmation of the issue.

感谢您阅读本文.

为了澄清,对于其他实现,例如,声明对服务的许可(最容易复制),将自动授予声明的自定义权限.

To clarify, for other implementations, such as declaring a permmission on a Service (which would be most simple to replicate) the declared custom permission is automatically granted.

推荐答案

据我了解,您尝试做下一件事(至少,这是我能够重现您的问题的方式):

As I understood you tried to do next thing (At least, that's how I was able to reproduce your problem):

  1. 您在第一个(称为F)应用程序中声明新的自定义权限

  1. You declare your new custom permission in first (lets call it F) application

<permission
    android:name="com.example.app.permission.CONTROL_EXAMPLE_APP"
    android:description="@string/control_description"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/control_label"
    android:protectionLevel="normal or dangerous"/>

  • 您定义F应用程序使用com.example.app.permission.CONTROL_EXAMPLE_APP权限.正如指导原则所述,这是正确的.

  • You define that your F app uses com.example.app.permission.CONTROL_EXAMPLE_APP permission. That is right as the guideline says.

    <uses-permission
        android:name="com.example.app.permission.CONTROL_EXAMPLE_APP"/>
    

  • 您可以在F应用程序中声明自定义广播接收器.要与该广播进行通信,您的应用程序(无论是哪个,F或其他应用程序)都必须获得您的自定义权限

  • You declare your custom broadcast receiver in your F app. To communicate with that broadcast your app (it's no matter which one, F or other app) must obtain your custom permission

    <receiver
        android:name="com.example.app.MyBroadcastReceiver"
        android:permission="com.example.app.permission.CONTROL_EXAMPLE_APP">
        <intent-filter android:priority="999">
            <action android:name="com.example.app.REQUEST_RECEIVER"/>
        </intent-filter>
    </receiver>
    

  • 您定义您第二个(称为S)应用程序使用com.example.app.permission.CONTROL_EXAMPLE_APP权限.因为您要允许S app向F app接收方发送广播消息.

  • You define that you second (lets call it S) application uses com.example.app.permission.CONTROL_EXAMPLE_APP permission. Because you want to allow S app to send broadcast messages to F app receiver.

    <uses-permission
        android:name="com.example.app.permission.CONTROL_EXAMPLE_APP"/>
    

  • 最后,您尝试使用此代码从S应用发送广播消息.

  • Finally you try to send broadcast message from your S app using this code.

    final Intent intent = new Intent("com.example.app.REQUEST_RECEIVER");
    context.sendOrderedBroadcast(intent, "com.example.app.permission.CONTROL_EXAMPLE_APP", new BroadcastReceiver() {
            @Override
            public void onReceive(final Context context, final Intent intent) {
                // getResultCode();
            }
        }, null, Activity.RESULT_CANCELED, null, null);
    

    这很重要,您授予了S应用程序权限,但没有授予F应用程序权限.

    And, this is important, you granted permission to your S app, but you didn't grant permission to your F app.

    结果是,您在F app中声明的广播接收器没有收到任何东西.

    As result your broadcast receiver declared in F app didn't receive anything.

    在您授予F应用程序权限后(请注意,现在S和F已授予您的自定义权限),一切正常.在F app中声明的广播接收器收到来自S app的消息.

    After you granted permission to your F app (Note that now S and F granted your custom permission) everything works fine. Broadcast receiver declared in F app received message from S app.

    我认为这是正确的行为,因为此 doc 对我们说:

    I guess that is correct behaviour, because this doc says us:

    请注意,在此示例中,DEBIT_ACCT权限不仅是 用元素声明,它的使用也被要求 元素.您必须请求其使用才能 应用程序的其他组件以启动受保护的活动, 即使该保护是由应用程序本身施加的.

    Note that, in this example, the DEBIT_ACCT permission is not only declared with the element, its use is also requested with the element. You must request its use in order for other components of the application to launch the protected activity, even though the protection is imposed by the application itself.

    声明权限的应用还必须请求相同的权限才能与自身通信.

    And app which declare permission also must request the same permission to communicate with itself.

    因此,Android API 23应该首先获得使用您的权限表单用户的访问权限.而且我们必须获得2个授予的权限,第一个是从F应用程序(因为这样的指导),第二个是从S应用程序(因为我们只需要获得访问权限).

    As result, android API 23 should to get access to use your permission form user first. And we must to get 2 granted permissions, first from F app (because guidline says as that) and second from S app (because we just need to get access).

    但是我没有抓住你的下一个要点:

    But I didn't catch your next point:

    提出一个对话说似乎很荒谬

    It would seem ridiculous to raise a dialog saying

    示例应用程序的应用程序需要使用示例应用程序的权限

    The application Example App wants permission to use Example App

    我的原生Android API 23向我显示了以下内容:

    My native Android API 23 displays me something like that:

    示例应用程序想要的应用程序

    The application Example App wants

    这篇关于Android自定义权限-棉花糖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆