通过绑定远程服务进行通信,有时需要做一些安全验证。有两种方式可以进行验证权限。
在服务端的Service的onBind()方法中进行验证
- 首先要定义权限:
在服务端的AndroidManifest.xml中定义权限
其中protectionLevel有以下几种:
"normal"
"dangerous"
"signature"
"signatureOrSystem"
如果定义的是前面两种normal或者dangerous, 我们自己的应用需要去访问其对应受保护的资源时只需要在androidManifest.xml中添加相同的uses-permission就行了。 如果是signature, 我们仅仅添加对权限的使用还不行, 必须同时具有相同的签名。 如果是signatureOrSystem(这种权限的应用第三方的应用无法单独访问), 不仅要有相同的签名,而且签名必须是系统签名,此外可能还需要android:sharedUserId="android.uid.system"
。
- 在onBind()方法中验证定义的权限
@Override
public IBinder onBind(Intent intent) {
DDLog.i(ServerService.class, "onBind");
int check = checkCallingPermission("com.flyscale.permission.TEST");
if (check == PackageManager.PERMISSION_DENIED){
DDLog.i(ServerService.class, "permission denied!");
return null;
}
if (mServerBinder == null)
mServerBinder = new ServerBinder();
return mServerBinder;
}
PS:测试的时候总是权限验证失败,还没找到问题原因。
3.客户端AndroidManifest.xml中添加权限
在实现aidl接口的时候,重写onTransact方法,验证权限及包名
验证权限与在onBind()方法中相同。
验证包名需要用到一个getCallingUid方法,根据uid来获取包名
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
//权限验证
int check = checkCallingPermission(Constants.BIND_SERVICE_PERMISSION);
if(check == PackageManager.PERMISSION_DENIED){
return false;
}
//包名验证
String packageName = null;
String[] packages = getPackageManager().getPackagesForUid(getCallingUid());
if(packages != null && packages.length > 0){
packageName = packages[0];
}
assert packageName != null;
if(!packageName.startsWith("com.flyscale.testpermission")){
return false;
}
return super.onTransact(code, data, reply, flags);
}
protectionLevel补充说明
normal
The default value. A lower-risk permission that gives requesting applications access to isolated application-level features, with minimal risk to other applications, the system, or the user. The system automatically grants this type of permission to a requesting application at installation, without asking for the user's explicit approval (though the user always has the option to review these permissions before installing).
dangerous
A higher-risk permission that would give a requesting application access to private user data or control over the device that can negatively impact the user. Because this type of permission introduces potential risk, the system may not automatically grant it to the requesting application. For example, any dangerous permissions requested by an application may be displayed to the user and require confirmation before proceeding, or some other approach may be taken to avoid the user automatically allowing the use of such facilities.
signature
A permission that the system grants only if the requesting application is signed with the same certificate as the application that declared the permission. If the certificates match, the system automatically grants the permission without notifying the user or asking for the user's explicit approval.
signatureOrSystem
A permission that the system grants only to applications that
are in the Android system image or that are signed with the
same certificate as the application that declared the
permission. Please avoid using this option, as
the signature protection level should be sufficient for most
needs and works regardless of exactly where applications are
installed. The "signatureOrSystem" permission is used for
certain special situations where multiple vendors have
applications built into a system image and need to share
specific features explicitly because they are being built
together.