本文介绍了为您的Android应用集成WAF App防护SDK(以下简称SDK)的操作方法。您必须在应用中集成SDK,才能为应用开启App防护。
使用限制
Android应用的API版本必须是16及以上,否则无法正常使用SDK。
前提条件
已开通WAF App防护模块且开启了App防护状态开关。
相关操作,请参见如何为应用开启App防护。
已获取Android应用对应的SDK。
您开通WAF App防护模块后,请提交工单,联系产品技术专家获取SDK。
Android应用对应的SDK包含1个AAR文件,文件名为AliTigerTally_X.Y.Z.aar,其中X.Y.Z表示版本号。
已获取SDK认证密钥(即
appkey
)。您在Web应用防火墙控制台的 页面开启App防护后,即可单击获取并复制appkey,获取SDK认证密钥。该密钥用于发起SDK初始化请求,需要在集成代码中使用。
说明每个阿里云账号拥有唯一的
appkey
(适用于所有接入WAF防护的域名),且Android和iOS应用集成SDK时都使用该appkey
。认证密钥示例:
****OpKLvM6zliu6KopyHIhmneb_****u4ekci2W8i6F9vrgpEezqAzEzj2ANrVUhvAXMwYzgY_****vc51aEQlRovkRoUhRlVsf4IzO9dZp6nN_****Wz8pk2TDLuMo4pVIQvGaxH3vrsnSQiK****
背景信息
App防护SDK主要用于对通过App客户端发起的请求进行签名。WAF服务端通过校验App请求签名,识别App业务中的风险、拦截恶意请求,实现App防护的目的。
关于App防护提供的SDK所涉及的隐私政策,请参见Web应用防火墙App防护SDK隐私政策。
创建一个测试工程(可选)
您可以直接在真实的Android工程中集成SDK,或者先创建一个测试工程进行测试,等熟悉操作后,再在真实环境中进行操作。
以Android Studio工具为例,新建一个测试用Android工程,并按照配置向导完成创建。
本文将测试工程命名为TigerTally_sdk_test,创建好的工程目录如下图所示。在集成SDK前,请确认测试工程可以正常运行。
操作步骤
使用Android Studio打开App工程,进入文件目录。
引用AAR包。
将您获取的AliTigerTally.aar文件复制到libs目录(可以直接拖放进去)。
打开build.gradle文件,修改以下配置:
将libs目录添加为查找依赖的源。
repositories{ flatDir { dirs 'libs' } }
添加编译依赖。
重要您需要将以下代码中AliTigerTally文件的版本号(X.Y.Z)替换成您获取的AAR文件的版本号。
dependencies { compile(name: 'AliTigerTally_X.Y.Z', ext: 'aar') }
在页面上方的提示信息中,单击Sync Now,将修改的配置同步到项目中。
添加SO引用。
如果您的项目已经使用过SO,请跳过该步骤;如果项目在此之前未使用过SO,请在build.gradle中添加以下配置:
android { defaultConfig { ndk { abiFilters 'arm64-v8a', 'x86', "armeabi-v7a" //abiFilters "armeabi-v7a" } } }
为应用申请以下权限。
权限
是否必须
说明
android.permission.INTERNET
是
用于连接网络。
android.permission.ACCESS_NETWORK_STATE
否
用于获取设备的网络状态。
android.permission.ACCESS_WIFI_STATE
否
用于获取设备的WIFI状态。
android.permission.READ_PHONE_STATE
否
用于读取设备状态和身份。
重要该权限在Android 6.0及以上需要动态申请。
android.permission.BLUETOOTH
否
用于获取设备的蓝牙权限。
android.permission. READ_EXTERNAL_STORAGE
否
用于读取设备的外部存储。
重要该权限在Android 6.0及以上需要动态申请。
android.permission.CHANGE_NETWORK_STATE
否
用于修改设备的网络状态。
添加集成代码。
设置用户标识。
接口定义:
int setAccount(String account);
功能:设置您业务中自定义的终端用户标识,方便您更灵活地配置WAF防护策略。
接口参数:<account>,String类型,表示标识一个用户的字符串(建议您使用脱敏后的格式)。
返回值:int类型,返回是否设置成功,0表示成功,-1表示失败。
示例代码:
final String account="account"; TigerTallyAPI.setAccount(account); // 如果当前登录的用户是游客身份,可以跳过这步,直接调用初始化函数。
SDK初始化。
接口定义:
int init(Context context, String appkey, int type);
功能:初始化SDK,执行一次初始化采集。一次初始化采集表示采集一次终端设备信息,您可以根据业务的不同,重新调用
init
函数进行初始化采集。初始化采集分为两种模式:采集全量数据、采集除需授权字段外的数据(不采集涉及终端设备用户隐私的字段,包括:imei、imsi、simSerial、wifiMac、wifiList、bluetoothMac)。
说明建议您在终端用户同意App的隐私政策前,采集除需授权字段外的数据;在终端用户同意App的隐私政策后,再采集全量数据。采集全量数据有利于更好地识别风险。
接口参数:
<context>:Context类型,传入您应用的上下文。
<appkey>:String类型,设置为您的SDK认证密钥。
<type>:CollectType类型,设置采集模式。取值:
DEFAULT:表示采集全量数据。
NO_GRANTED:表示采集除需授权字段外的数据。
返回值:int类型,返回初始化结果,0表示成功,-1表示失败。
示例代码:
final String appkey="your_appkey"; // 采集全量数据。 int ret = TigerTallyAPI.init(this.getApplicationContext(), appkey, TigerTallyAPI.CollectType.DEFAULT); // 采集除需授权字段外的数据。 int ret = TigerTallyAPI.init(this.getApplicationContext(), appkey, TigerTallyAPI.CollectType.NOT_GRANTED); Log.d("AliSDK", "ret:" + ret);
签名请求数据。
接口定义:
String vmpSign(int signType, byte[] input);
功能:对输入的数据进行签名,并且返回签名串。
接口参数:
<signType>:int类型,取值固定为1,表示默认的签名算法。
<input>:byte[]类型,表示待签名的数据。
待签名数据一般是整个请求体(RequestBody)。 如果请求体为空(例如,POST请求的Body为空或者使用了GET请求),则设置成空对象(
null
)或者空字符串的Bytes值(例如,"".getBytes("UTF-8")
)。
返回值:String类型,返回签名串。
示例代码:
说明示例代码中将签名串定义为wToken。
String request_body = "i am the request body, encrypted or not!"; String wToken = null; try { wToken = TigerTallyAPI.vmpSign(1, request_body.getBytes("UTF-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } Log.d("AliSDK", "wToken:" + wToken);
将签名串添加到HTTP协议头。
例如,如果您的项目使用
HttpURLConnection
,则可以将签名串(wToken)字段的内容添加到HttpURLConnection
类的对象中。示例代码:
String request_body = "i am the request body, encrypted or not!"; new Thread(new Runnable() { @Override public void run() { try { URL url = new URL("https://www.aliyundoc.com"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(5000); conn.setRequestMethod("POST"); // set wToken info to header conn.setRequestProperty("wToken", wToken); OutputStream os = conn.getOutputStream(); // set request body info byte[] requestBody = request_body.getBytes("UTF-8"); os.write(requestBody); os.flush(); os.close(); int code = conn.getResponseCode(); Log.d("respCode", Integer.toString(code)); } catch (MalformedURLException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }; }).start();
将修改好HTTP协议头的数据发送到应用服务器。
WAF服务端获得应用服务器收到的请求后,通过解析签名串(wToken)进行风险识别、拦截恶意请求,然后将合法请求转发回源站。
接口混淆配置
如果您使用ProGuard进行代码混淆,则可以使用-keep
选项对SDK的接口函数进行设置,保护SDK接口函数不被移除混淆。
示例代码:
-keep class com.aliyun.TigerTally.* {*;}