2012-01-11 23 views
52

Tengo dos aplicaciones.¿Cómo usar permisos personalizados en Android?

Uno está declarando permiso y que tiene solo Activity:

Parte de AndroidManifest.xml

<application 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" 
    android:permission="your.namespace.permission.TEST" > 
    <activity 
     android:name=".DeclaringPermissionActivity" 
     android:label="@string/app_name" > 

     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 

     <intent-filter> 
     <action android:name="android.intent.action.VIEW" /> 
     <category android:name="android.intent.category.DEFAULT" /> 
     <category android:name="android.intent.category.BROWSABLE" /> 
     <data android:scheme="myapp" 
      android:host="myapp.mycompany.com" /> 
     </intent-filter> 
    </activity> 
</application> 

El segundo declara que se utiliza permiso

Parte de AndroidManifest.xml

<uses-sdk android:minSdkVersion="10" /> 
<uses-permission android:name="your.namespace.permission.TEST" /> 

<application 

Parte de Activity:

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("myapp://myapp.mycompany.com/index"))); 
} 

estoy instalando el permiso declarando aplicación, entonces ejecutar la segunda aplicación.

En consecuencia me sale excepción de seguridad:

01-11 09:46:55.249: E/AndroidRuntime(347): java.lang.RuntimeException: Unable to start activity ComponentInfo{your.namespace2/your.namespace2.UsingPErmissionActivity}: java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.VIEW dat=myapp://myapp.mycompany.com/index cmp=your.namespace/.DeclaringPermissionActivity } from ProcessRecord{407842c0 347:your.namespace2/10082} (pid=347, uid=10082) requires your.namespace.permission.TEST 
+0

Solo quiero señalar esta vulnerabilidad: http://commonsware.com/blog/2014/02/12/vulnerabilities-custom-permissions.html – Tobrun

+0

En relación con el comentario de vulnerabilidad anterior, tenga en cuenta los cambios en Android 5.0 esa dirección este problema: http://developer.android.com/about/versions/android-5.0-changes.html#custom_permissions – Nonos

Respuesta

98

he creado un código de prueba que se puede utilizar y poner a prueba sus permisos . Hay dos aplicaciones PermissionTestClient que declaran el permiso y protegen su actividad con este permiso. Aquí está su archivo de manifiesto:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.testpackage.permissiontestclient" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk android:minSdkVersion="10" /> 
    <permission android:name="com.testpackage.mypermission" android:label="my_permission" android:protectionLevel="dangerous"></permission> 

    <application 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" > 
     <activity 
      android:permission="com.testpackage.mypermission" 
      android:name=".PermissionTestClientActivity" 
      android:label="@string/app_name" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 

      <intent-filter > 
       <action android:name="com.testpackage.permissiontestclient.MyAction" /> 
       <category android:name="android.intent.category.DEFAULT" />     
      </intent-filter> 
     </activity> 
    </application> 

</manifest> 

No hay nada especial en un archivo de actividad por lo que no se mostrará aquí.

La aplicación PermissionTestServer llama a actividad desde PermissionTestClient.Aquí está su archivo de manifiesto:

<?xml version="1.0" encoding="utf-8"?> 

<uses-sdk android:minSdkVersion="10" /> 
<uses-permission android:name="com.testpackage.mypermission"/> 

<application 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" > 
    <activity 
     android:name=".PermissionTestServerActivity" 
     android:label="@string/app_name" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
</application> 

</manifest> 

Y Actividad:

package com.testpackage.permissiontestserver; 

import android.app.Activity; 
import android.content.Intent; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 

public class PermissionTestServerActivity extends Activity { 
    private static final String TAG = "PermissionTestServerActivity"; 

    /** Called when the activity is first created. */ 
    Button btnTest; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     btnTest = (Button) findViewById(R.id.btnTest); 
     btnTest.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       Log.d(TAG, "Button pressed!"); 
       Intent in = new Intent(); 
       in.setAction("com.testpackage.permissiontestclient.MyAction"); 
       in.addCategory("android.intent.category.DEFAULT"); 
       startActivity(in); 
      } 
     }); 
    } 
} 

Para probarlo basta con retirar el permiso de usos-Application Server. Obtendrá un error de violación de seguridad.

+2

Gracias, mi error fue poner el atributo 'permission' solo en el elemento' '. – pixel

+0

Esto no funciona para mí cuando uso android: protectionLevel = "signature" en PermissionTestClient, utilizo el permiso en ese iniciador de aplicaciones y obtengo: Denegación de permiso: inicio de intención {act = android.intent.action.MAIN cat = [android.intent.category.Launcher] flg = 0x10000000 cmp = my.package.foobar/.DashboardActivity} desde null (pid = 4070, uid = 2000) requiere my.custom.permission.ACCESS_ACTIVITY - por lo que la aplicación no puede iniciar su propia actividad 0_o – fr1550n

+2

El nivel de permiso de firma significa que su cliente y servidor deben estar firmados con el mismo certificado. Intente ejecutar el código utilizando un nivel peligroso y, si todo está bien, intente iniciarse con la firma. Una cosa más, si usa la firma, creo que necesita exportar un archivo apk firmado y luego instalarlo. – Yury

29

Es necesario crear un permiso en el manifiesto de la aplicación de base por la que se declara exclusivamente. Por ejemplo:

<permission android:name="your.namespace.permission.TEST" 
    android:protectionLevel="normal" android:label="This is my custom permission" /> 

Y después hacer uso de ella en su aplicación deseada como:

<uses-permission android:name="your.namespace.permission.TEST" /> 

Nota:Es de vital importancia para mantener el orden en el que se instale sus aplicaciones con permisos personalizados . es decir, debe necesitar instalar esa aplicación primero que declara el permiso y luego instala el que hace uso de él. Cualquier interrupción en este orden puede romper el uso de la costumbre. permisos.

+0

concisa y corta y funciona. La respuesta mejor votada es mejor, pero esto es exactamente lo que se preguntó en la pregunta. Una nota, esto es TODO lo que necesita para usar permisos personalizados, porque el gerente de seguridad se ocupa del resto. – PSIXO

+0

No puedo hacer que esto funcione, incluso cuando declaro permiso de uso en la aplicación que creó el permiso. Lanza una excepción de seguridad al inicio – Anshu

+1

Siempre y cuando lo recuerde correctamente, el orden en que instale las aplicaciones también es importante. Primero instale la aplicación que declara un permiso personalizado y luego instale la aplicación que usa ese permiso personalizado. – waqaslam

0

Definición de permisos personalizado se realiza mediante <Permission> etiqueta .. Por favor, siga el siguiente enlace para utilizar los permisos definidos por el usuario en la aplicación:

Declaring and Enforcing Permissions

1

Como se menciona en las respuestas, también debe tener en cuenta el orden en que instala las aplicaciones.

Esto es importante porque:

si la aplicación que solicita el permiso (App B) está instalado antes de la aplicación que define el permiso (App A), entonces no habrá tal permiso definido en el dispositivo específico por lo que el sistema operativo no solicitará el permiso en absoluto.

Más tarde, cuando instale la Aplicación A y trate de ejecutar la Aplicación B, esta última no podrá acceder al componente seguro.

Una solución consistiría en definir el mismo permiso personalizado en ambas aplicaciones, A y B para asegurarse de que el permiso existe en el dispositivo independientemente de qué aplicación esté instalada primero, de modo que cuando se instala la aplicación A, el permiso será ya concedida a App B.

en ese caso, sin embargo, usted debe asegurarse de que el nivel de protección es el mismo en ambos declaraciones ya que esto puede dar lugar a riesgos de seguridad .

(tenga en cuenta que desde Android 5.0 y en adelante no puede definir el mismo permiso en más de una aplicación, excepto cuando esas aplicaciones están firmadas con la misma clave de firma).

Cuestiones relacionadas