|
| 1 | +page.title=Enhancing Security with Device Management Policies |
| 2 | +parent.title=Developing Android Applications for the Enterprise |
| 3 | +parent.link=index.html |
| 4 | +@jd:body |
| 5 | + |
| 6 | + |
| 7 | +<div id="tb-wrapper"> |
| 8 | +<div id="tb"> |
| 9 | + |
| 10 | +<h2>This lesson teaches you to</h2> |
| 11 | +<ol> |
| 12 | + <li><a href="#DeclarePolicy">Define and Declare Your Policy</a></li> |
| 13 | + <li><a href="#CreateDeviceAdminReceiver">Create a Device Administration Receiver</a></li> |
| 14 | + <li><a href="#ActivateDeviceAdmin">Activate the Device Administrator</a></li> |
| 15 | + <li><a href="#ImplementDevicePolicyController">Implement the Device Policy Controller</a></li> |
| 16 | +</ol> |
| 17 | + |
| 18 | +<!-- related docs (NOT javadocs) --> |
| 19 | +<h2>You should also read</h2> |
| 20 | +<ul> |
| 21 | + <li><a href="{@docRoot}guide/topics/admin/device-admin.html">Device Administration</a></li> |
| 22 | +</ul> |
| 23 | + |
| 24 | +<h2>Try it out</h2> |
| 25 | + |
| 26 | +<div class="download-box"> |
| 27 | + <a href="http://developer.android.com/shareables/training/DeviceManagement.zip" |
| 28 | +class="button">Download the sample</a> |
| 29 | + <p class="filename">DeviceManagement.zip</p> |
| 30 | +</div> |
| 31 | + |
| 32 | +</div> |
| 33 | +</div> |
| 34 | + |
| 35 | + |
| 36 | +<p>Since Android 2.2 (API level 8), the Android platform offes system-level device management |
| 37 | +capabilities through the Device Administration APIs.</p> |
| 38 | + |
| 39 | +<p>In this lesson, you will learn how to create a security-aware application that manages access to |
| 40 | +its content by enforcing device management policies. Specifically, the application can be configured |
| 41 | +such that it ensures a screen-lock password of sufficient strength is set up before displaying |
| 42 | +restricted content to the user.</p> |
| 43 | + |
| 44 | + |
| 45 | +<h2 id="DeclarePolicy">Define and Declare Your Policy</h2> |
| 46 | + |
| 47 | +<p>First, you need to define the kinds of policy to support at the functional level. Policies may |
| 48 | +cover screen-lock password strength, expiration timeout, encryption, etc.</p> |
| 49 | + |
| 50 | +<p>You must declare the selected policy set, which will be enforced by the application, in the |
| 51 | +<code>res/xml/device_admin.xml</code> file. The Android manifest should also reference the |
| 52 | +declared policy set.</p> |
| 53 | + |
| 54 | +<p>Each declared policy corresponds to some number of related device policy methods in {@link |
| 55 | +android.app.admin.DevicePolicyManager} (defining minimum password length and minimum number of |
| 56 | +uppercase characters are two examples). If an application attempts to invoke methods whose |
| 57 | +corresponding policy is not declared in the XML, this will result in a {@link |
| 58 | +java.lang.SecurityException} at runtime. Other permissions, |
| 59 | +such as <code>force-lock</code>, are available if the application intends to manage |
| 60 | +other kinds of policy. As you'll see later, as part of the device administrator activation process, |
| 61 | +the list of declared policies will be presented to the user on a system screen.</p> |
| 62 | + |
| 63 | +<p>The following snippet declares the limit password policy in <code>res/xml/device_admin.xml</code>:</p> |
| 64 | + |
| 65 | +<pre> |
| 66 | +<device-admin xmlns:android="http://schemas.android.com/apk/res/android"> |
| 67 | + <uses-policies> |
| 68 | + <limit-password /> |
| 69 | + </uses-policies> |
| 70 | +</device-admin> |
| 71 | +</pre> |
| 72 | + |
| 73 | +<p>Policy declaration XML referenced in Android manifest:</p> |
| 74 | + |
| 75 | +<pre> |
| 76 | +<receiver android:name=".Policy$PolicyAdmin" |
| 77 | + android:permission="android.permission.BIND_DEVICE_ADMIN"> |
| 78 | + <strong><meta-data android:name="android.app.device_admin" |
| 79 | + android:resource="@xml/device_admin" /></strong> |
| 80 | + <intent-filter> |
| 81 | + <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" /> |
| 82 | + </intent-filter> |
| 83 | +</receiver> |
| 84 | +</pre> |
| 85 | + |
| 86 | + |
| 87 | +<h2 id="CreateDeviceAdminReceiver">Create a Device Administration Receiver</h2> |
| 88 | + |
| 89 | +<p>Create a Device Administration broadcast receiver, which gets notified of events related to the policies you’ve declared to support. An application can selectively override callback methods.</p> |
| 90 | + |
| 91 | +<p>In the sample application, Device Admin, when the device administrator is deactivated by the |
| 92 | +user, the configured policy is erased from the shared preference. You should consider implementing |
| 93 | +business logic that is relevant to your use case. For example, the application might take some |
| 94 | +actions to mitigate security risk by implementing some combination of deleting sensitive data on the |
| 95 | +device, disabling remote synchronization, alerting an administrator, etc.</p> |
| 96 | + |
| 97 | +<p>For the broadcast receiver to work, be sure to register it in the Android manifest as illustrated in the above snippet.</p> |
| 98 | + |
| 99 | +<pre> |
| 100 | +public static class PolicyAdmin extends DeviceAdminReceiver { |
| 101 | + |
| 102 | + @Override |
| 103 | + public void onDisabled(Context context, Intent intent) { |
| 104 | + // Called when the app is about to be deactivated as a device administrator. |
| 105 | + // Deletes previously stored password policy. |
| 106 | + super.onDisabled(context, intent); |
| 107 | + SharedPreferences prefs = context.getSharedPreferences(APP_PREF, Activity.MODE_PRIVATE); |
| 108 | + prefs.edit().clear().commit(); |
| 109 | + } |
| 110 | +} |
| 111 | +</pre> |
| 112 | + |
| 113 | + |
| 114 | +<h2 id="ActivateDeviceAdmin">Activate the Device Administrator</h2> |
| 115 | + |
| 116 | +<p>Before enforcing any policies, the user needs to manually activate the application as a device |
| 117 | +administrator. The snippet below illustrates how to trigger the settings activity in which the |
| 118 | +user can activate your application. It is good practice to include the explanatory text to highlight |
| 119 | +to users why the application is requesting to be a device administrator, by specifying the |
| 120 | +{@link android.app.admin.DevicePolicyManager#EXTRA_ADD_EXPLANATION} extra in the intent.</p> |
| 121 | + |
| 122 | +<div class="figure" style="width:220px"> |
| 123 | +<img src="/images/training/device-mgmt-activate-device-admin.png" /> |
| 124 | +<p class="img-caption"><strong>Figure 1.</strong> The user activation screen in which you can |
| 125 | +provide a description of your device policies.</p> |
| 126 | +</div> |
| 127 | + |
| 128 | +<pre> |
| 129 | +if (!mPolicy.isAdminActive()) { |
| 130 | + |
| 131 | + Intent activateDeviceAdminIntent = |
| 132 | + new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); |
| 133 | + |
| 134 | + activateDeviceAdminIntent.putExtra( |
| 135 | + DevicePolicyManager.EXTRA_DEVICE_ADMIN, |
| 136 | + mPolicy.getPolicyAdmin()); |
| 137 | + |
| 138 | + // It is good practice to include the optional explanation text to |
| 139 | + // explain to user why the application is requesting to be a device |
| 140 | + // administrator. The system will display this message on the activation |
| 141 | + // screen. |
| 142 | + activateDeviceAdminIntent.putExtra( |
| 143 | + DevicePolicyManager.EXTRA_ADD_EXPLANATION, |
| 144 | + getResources().getString(R.string.device_admin_activation_message)); |
| 145 | + |
| 146 | + startActivityForResult(activateDeviceAdminIntent, |
| 147 | + REQ_ACTIVATE_DEVICE_ADMIN); |
| 148 | +} |
| 149 | +</pre> |
| 150 | + |
| 151 | +<p>If the user chooses "Activate," the application becomes a device administrator and can begin |
| 152 | +configuring and enforcing the policy.</p> |
| 153 | + |
| 154 | +<p>The application also needs to be prepared to handle set back situations where the user abandons |
| 155 | +the activation process by hitting the Cancel button, the Back key, or the Home key. Therefore, |
| 156 | +{@link android.app.Activity#onResume onResume()} in the Policy Set Up Activity needs to have logic |
| 157 | +to reevaluate the condition and present the Device Administrator Activation option to the user if |
| 158 | +needed.</p> |
| 159 | + |
| 160 | + |
| 161 | +<h2 id="ImplementDevicePolicyController">Implement the Device Policy Controller</h2> |
| 162 | + |
| 163 | +<p>After the device administrator is activated successfully, the application then configures Device |
| 164 | +Policy Manager with the requested policy. Keep in mind that new policies are being added to |
| 165 | +Android with each release. It is appropriate to perform version checks in your application if using |
| 166 | +new policies while supporting older versions of the platform. For example, the Password Minimum |
| 167 | +Upper Case policy is only available with API level 11 (Honeycomb) and above. The following code |
| 168 | +demonstrates how you can check the version at runtime.</p> |
| 169 | + |
| 170 | +<pre> |
| 171 | +DevicePolicyManager mDPM = (DevicePolicyManager) |
| 172 | + context.getSystemService(Context.DEVICE_POLICY_SERVICE); |
| 173 | +ComponentName mPolicyAdmin = new ComponentName(context, PolicyAdmin.class); |
| 174 | +... |
| 175 | +mDPM.setPasswordQuality(mPolicyAdmin, PASSWORD_QUALITY_VALUES[mPasswordQuality]); |
| 176 | +mDPM.setPasswordMinimumLength(mPolicyAdmin, mPasswordLength); |
| 177 | +if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { |
| 178 | + mDPM.setPasswordMinimumUpperCase(mPolicyAdmin, mPasswordMinUpperCase); |
| 179 | +} |
| 180 | +</pre> |
| 181 | + |
| 182 | +<p>At this point, the application is able to enforce the policy. While the application has no access |
| 183 | +to the actual screen-lock password used, through the Device Policy Manager API it can determine |
| 184 | +whether the existing password satisfies the required policy. If it turns out that the existing |
| 185 | +screen-lock password is not sufficient, the device administration API does not automatically take |
| 186 | +corrective action. It is the application’s responsibility to explicitly launch the system |
| 187 | +password-change screen in the Settings app. For example:</p> |
| 188 | + |
| 189 | +<pre> |
| 190 | +if (!mDPM.isActivePasswordSufficient()) { |
| 191 | + ... |
| 192 | + // Triggers password change screen in Settings. |
| 193 | + Intent intent = |
| 194 | + new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD); |
| 195 | + startActivity(intent); |
| 196 | +} |
| 197 | +</pre> |
| 198 | + |
| 199 | +<p>Normally, the user can select from one of the available lock mechanisms, such as None, Pattern, |
| 200 | +PIN (numeric), or Password (alphanumeric). When a password policy is configured, those password |
| 201 | +types that are weaker than those defined in the policy are disabled. For example, if the |
| 202 | +“Numeric” password quality is configured, the user can select either PIN (numeric) or Password |
| 203 | +(alphanumeric) password only.</p> |
| 204 | + |
| 205 | +<p>Once the device is properly secured by setting up a proper screen-lock password, the application |
| 206 | +allows access to the secured content.</p> |
| 207 | + |
| 208 | +<pre> |
| 209 | +if (!mDPM.isAdminActive(..)) { |
| 210 | + // Activates device administrator. |
| 211 | + ... |
| 212 | +} else if (!mDPM.isActivePasswordSufficient()) { |
| 213 | + // Launches password set-up screen in Settings. |
| 214 | + ... |
| 215 | +} else { |
| 216 | + // Grants access to secure content. |
| 217 | + ... |
| 218 | + startActivity(new Intent(context, SecureActivity.class)); |
| 219 | +} |
| 220 | +</pre> |
0 commit comments