Para configurar políticas de mitigação baseadas em cenário para seu aplicativo no console do Bot Management, é necessário integrar o App Protection SDK do Web Application Firewall (WAF). Este tópico descreve como integrar o App Protection SDK em um aplicativo iOS.
Informações gerais
O App Protection SDK assina as requisições enviadas pelo client do aplicativo. O servidor do WAF verifica a assinatura da requisição para identificar e bloquear requisições maliciosas, protegendo seu aplicativo.
Limitações
-
O iOS SDK está disponível em duas versões: uma versão com Identifier for Advertising (IDFA) e uma versão sem IDFA. Os arquivos SDK correspondentes são:
AliTigerTally_IDFA.framework
AliTigerTally_NOIDFA.framework
Se o seu projeto iOS utiliza IDFA, recomendamos integrar a versão AliTigerTally_IDFA do SDK. Caso contrário, utilize a versão AliTigerTally_NOIDFA.
A interface
initpode ser demorada. Para garantir proteção ideal, aguarde pelo menos 2 segundos após chamar a interfaceinitantes de chamar a interfacevmpSign. Embora esse intervalo não seja obrigatório, um intervalo menor pode impedir que os recursos de segurança entrem em pleno efeito. Ajuste o intervalo conforme as necessidades do seu negócio.O App Protection SDK exige iOS versão 9.0 ou posterior.
Pré-requisitos
-
Você já obteve o SDK para seu aplicativo iOS.
Para obter o SDK, envie um ticket para entrar em contato com um especialista técnico do product.
NotaO arquivo SDK para um aplicativo iOS é nomeado
tigertally-X.Y.Z-xxxx-ios.zip, onde X.Y.Z é o número da versão. O arquivo contém dois arquivos framework e dois arquivos xcframework. -
Você já obteve a chave de autenticação do SDK (também conhecida como appkey).
Após ativar o Bot Management, faça login no Web Application Firewall 3.0 console. Na barra de menus superior, selecione o grupo de recursos e a região (Chinese Mainland ou Outside Chinese Mainland) para a instância do WAF.. No painel de navegação à esquerda, escolha . Acesse a aba App Protection e clique em Obtain and Copy AppKey no canto superior direito para recuperar a chave de autenticação do SDK. Essa chave é necessária para inicializar o SDK e deve ser incluída no código de integração.
NotaCada conta da Alibaba Cloud possui uma appkey exclusiva para todos os domain names protegidos pelo WAF. Essa appkey é utilizada na integração do SDK para aplicativos Android, iOS e HarmonyOS.
Exemplo de chave de autenticação:
****OpKLvM6zliu6KopyHIhmneb_****u4ekci2W8i6F9vrgpEezqAzEzj2ANrVUhvAXMwYzgY_****vc51aEQlRovkRoUhRlVsf4IzO9dZp6nN_****Wz8pk2TDLuMo4pVIQvGaxH3vrsnSQiK****.
Etapa 1: Criar um projeto
No Xcode, crie um projeto iOS utilizando o assistente de configuração. O exemplo a seguir mostra a estrutura de diretórios do projeto.
tigerdemo
tigerdemo
tool
AppDelegate.h
AppDelegate.m
ViewController.h
ViewController.m
main.m
Main.storyboard
LaunchScreen.storyboard
AliTigerTallyApp.entitlements
Info.plist
Etapa 2: Integrar o framework
Adicione o arquivo SDK, AliTigerTally_IDFA.framework ou AliTigerTally_NOIDFA.framework, ao seu projeto.
-
Versão IDFA
Após adicionar o arquivo, defina a opção Embed do AliTigerTally_IDFA.framework como Do Not Embed.
-
Versão sem IDFA
Adicione AliTigerTally_NOIDFA.framework à seção Frameworks, Libraries, and Embedded Content do seu projeto e defina Embed como Do Not Embed.
Adicione o arquivo SDK do módulo Captcha, AliCaptcha.framework, ao seu projeto e defina a opção Embed como Do Not Embed.
Adicione o arquivo de recursos AliCaptcha.bundle ao seu projeto incluindo-o em Build Phases > Copy Bundle Resources.
Etapa 3: Adicionar bibliotecas de dependência
Na seção Frameworks, Libraries, and Embedded Content do seu projeto Xcode, adicione as seguintes bibliotecas de dependência.
|
Biblioteca de dependência |
Obrigatória para IDFA |
Obrigatória para não-IDFA |
|
libc++.tbd |
Sim |
Sim |
|
libresolv.9.tbd |
Sim |
Sim |
|
CoreTelephony.framework |
Sim |
Sim |
|
AdSupport.framework |
Sim |
Não |
|
AppTrackingTransparency.framework |
Sim |
Não |
Etapa 4: Adicionar uma flag de linker
Em Build Settings, pesquise por Other Linker Flags e adicione a flag -ObjC.
Etapa 5: Adicionar o código de integração
1. Adicionar o arquivo de cabeçalho
-
Para a versão IDFA, adicione a seguinte instrução de importação:
#import <AliTigerTally_IDFA/AliTigerTally.h> -
Para a versão sem IDFA, adicione a seguinte instrução de importação:
#import <AliTigerTally_NOIDFA/AliTigerTally.h>
2. Configurar a assinatura de dados
-
Defina um identificador de usuário final personalizado para seu negócio. Isso permite configurar as políticas de proteção do WAF com maior flexibilidade.
/** * Sets the user account. * * @param account The account information. */ - (void)setAccount:(NSString *)account;-
Parâmetros:
account: Tipo: NSString. Uma string que identifica um usuário. Recomendamos utilizar um formato desensibilizado.
Valor de retorno: Nenhum.
-
Exemplo:
// For guest users, you can skip setAccount and initialize directly. After a user logs in, call setAccount and re-initialize. [[AliTigerTally sharedInstance] setAccount:@"testAccount"];
-
-
Inicialize o SDK para realizar a coleta de dados.
Cada inicialização coleta informações do dispositivo uma vez. Chame a função init novamente para reiniciar a coleta de dados em diferentes cenários de negócio.
A inicialização suporta três modos de coleta de dados: completo, privacidade personalizada e sem privacidade. O modo sem privacidade exclui campos relacionados à privacidade do usuário final, como IDFA e IDFV.
NotaPara atender aos seus requisitos internos, selecione um modo de coleta de dados adequado que garanta a integridade dos dados. Dados mais completos melhoram a detecção de ameaças.
// Initialization callback. Returns the status code of the interface call. typedef void (^TTInitListener)(int); /** * Initializes the SDK. * * @param appkey The key. * @param options Optional parameters. * @param onInitFinish The callback for when initialization is complete. * @return Indicates whether the initialization was successful. */ - (int)init:(NSString *)appkey collectType:(TTCollectType)type options:(NSMutableDictionary *_Nullable)options listener:(TTInitListener _Nullable)onInitFinish;-
Parâmetros:
appkey: Tipo: NSString. Sua chave de autenticação do SDK.
-
collectType: Tipo: TTCollectType. O modo de coleta de dados. Valores válidos:
Campo
Descrição
Exemplo
TT_DEFAULT
Coleta todos os dados.
TT_DEFAULT
TT_NO_BASIC_DATA
Não coleta dados básicos do dispositivo.
Inclui nome do dispositivo, versão do sistema operacional e resolução de tela.
TT_NO_X | TT_NO_Y
(onde X e Y representam os tipos de campo de dados a excluir)
TT_NO_UNIQUE_DATA
Não coleta dados de identificadores únicos.
Inclui IDFV e IDFA.
TT_NO_EXTRA_DATA
Não coleta dados estendidos do dispositivo.
Inclui informações de Wi-Fi conectado (SSID, BSSID) e a lista de redes Wi-Fi próximas.
TT_NOT_GRANTED
Não coleta nenhum dos dados relacionados à privacidade mencionados anteriormente.
TT_NOT_GRANTED
-
options: Tipo: NSMutableDictionary. Parâmetros opcionais para a coleta de dados. O valor padrão é nil. Os seguintes parâmetros estão disponíveis:
Campo
Descrição
Exemplo
IPv6
Especifica se deve usar um domain name IPv6 para reportar informações do dispositivo.
0 (padrão): Usa um domain name IPv4.
1: Usa um domain name IPv6.
1
Intl
Especifica se deve usar um domain name fora da Chinese mainland para reportar informações do dispositivo.
0 (padrão): Reporta para a Chinese mainland.
1: Reporta para regiões fora da Chinese mainland.
1
CustomUrl
Define o domain name do servidor de reporte de dados.
https://cloudauth-device.us-west-1.aliyuncs.com
CustomHost
Define o host do servidor de reporte de dados.
cloudauth-device.us-west-1.aliyuncs.com
NotaPara a maioria dos sites internacionais, configure apenas o parâmetro Intl. Para reportar dados a um site específico, defina os parâmetros CustomUrl e CustomHost. Os sites disponíveis são:
Se
Intlestiver definido como0, os dados são reportados ao site padrão em China (Shanghai): https://cloudauth-device.cn-shanghai.aliyuncs.com-
Se
Intlestiver definido como1:O site padrão é Singapore: https://cloudauth-device.ap-southeast-1.aliyuncs.com
Indonesia (Jakarta): https://cloudauth-device.ap-southeast-5.aliyuncs.com
US (Silicon Valley): https://cloudauth-device.us-west-1.aliyuncs.com
Germany (Frankfurt): https://cloudauth-device.eu-central-1.aliyuncs.com
China (Hong Kong): https://cloudauth-device.cn-hongkong.aliyuncs.com
-
listener: Tipo: TTInitListener. A interface de callback de inicialização do SDK. Use esse callback para verificar o status da inicialização. O valor padrão é nil.
TTCode
Código
Descrição
TT_SUCCESS
0
Inicialização bem-sucedida.
TT_NOT_INIT
-1
O SDK não está inicializado.
TT_NOT_PERMISSION
-2
As permissões iOS necessárias não foram concedidas.
TT_UNKNOWN_ERROR
-3
Ocorreu um erro de sistema desconhecido.
TT_NETWORK_ERROR
-4
Ocorreu um erro de rede.
TT_NETWORK_ERROR_EMPTY
-5
Ocorreu um erro de rede. O conteúdo retornado é uma string vazia.
TT_NETWORK_ERROR_INVALID
-6
O formato da resposta de rede é inválido.
TT_PARSE_SRV_CFG_ERROR
-7
Falha ao analisar a configuração do servidor.
TT_NETWORK_RET_CODE_ERROR
-8
O gateway retornou uma resposta de falha.
TT_APPKEY_EMPTY
-9
A appkey está vazia.
TT_PARAMS_ERROR
-10
Outros erros de parâmetro ocorreram.
TT_FGKEY_ERROR
-11
Ocorreu um erro no cálculo de chave.
TT_APPKEY_ERROR
-12
A versão do SDK não corresponde à versão da appkey.
Valor de retorno: Tipo: int. Um código de erro.
0indica sucesso e um número negativo indica falha.-
Exemplo:
// The appkey is the authentication key assigned to you on the Alibaba Cloud console. NSString *appKey = @"xxxxxxxxxxxxxxxxxxxxx"; // Optional parameters. You can configure IPv6 and reporting from outside the Chinese mainland. NSMutableDictionary *options = [[NSMutableDictionary alloc] init]; [options setValue:@"0" forKey:@"IPv6"]; // Use IPv4. [options setValue:@"0" forKey:@"Intl"]; // Report data from within the Chinese mainland. // [options setValue:@"1" forKey:@"Intl"]; // Report data from outside the Chinese mainland. // Report data to the US (West) region. // [options setValue:@"https://cloudauth-device.us-west-1.aliyuncs.com" forKey:@"CustomUrl"]; // [options setValue:@"cloudauth-device.us-west-1.aliyuncs.com" forKey:@"CustomHost"]; // An initialization call collects device information once. You can call the init function again to collect information for different business scenarios. // Full data collection. if (0 == [[AliTigerTally sharedInstance] init:appkey collectType:TT_DEFAULT options:options listener:nil]) { NSLog(@"Initialization successful"); } else { NSLog(@"Initialization failed"); } // To collect specific types of private data, use the "|" operator to specify multiple types. TTCollectType collectPrivacy = TT_NO_BASIC_DATA | TT_NO_EXTRA_DATA; int ret = [[AliTigerTally sharedInstance] init:appkey collectType:collectPrivacy options:options listener:nil]; // Do not collect private data. int ret = [[AliTigerTally sharedInstance] init:appkey collectType:TT_NOT_GRANTED options:options listener:nil];
-
-
Hashing de dados.
Esta interface de assinatura personalizada realiza o hash dos dados de entrada para gerar uma string
whash, que serve como assinatura personalizada. Para requisições POST, PUT e PATCH, utilize o request body como entrada. Para requisições GET e DELETE, utilize a URL completa. Adicione também a stringwhashgerada ao campo ali_sign_whash no cabeçalho da requisição HTTP.// Request type: typedef NS_ENUM(NSInteger, TTRequestType) { TT_GET=0, TT_POST, TT_PUT, TT_PATCH, TT_DELETE }; /** * Hashes the custom signature data. * @param type The data type. * @param input The data to be signed. * @return The whash string. */ - (NSString *)vmpHash:(TTRequestType)type input:(NSData *)input;-
Parâmetros:
-
type: Tipo: TTTypeRequest. O tipo de dado. Valores válidos:
GET: dados de requisição GET.
POST: dados de requisição POST.
PUT: dados de requisição PUT.
PATCH: dados de requisição PATCH.
DELETE: dados de requisição DELETE.
input: Tipo: NSData. Os dados a serem assinados. Passe o body ou a URL de acordo com o type.
-
Valor de retorno: Tipo: NSString. A string
whash.-
Exemplo:
// GET request NSString *url = @"https://tigertally.aliyun.com/apptest"; NSString *whash = [[AliTigerTally sharedInstance] vmpHash:TT_GET input:[url dataUsingEncoding:NSUTF8StringEncoding]]; NSLog(@"whash: %@", whash); // POST request NSString *body = @"hello world"; NSString *whash = [[AliTigerTally sharedInstance] vmpHash:TT_POST input:[body dataUsingEncoding:NSUTF8StringEncoding]]; NSLog(@"whash: %@", whash);
NotaChamar esta interface só é necessário se você habilitou a opção de assinatura personalizada no console do WAF. Se você utiliza a configuração padrão de assinatura, ignore esta etapa.
-
-
Assinatura de dados.
Este método usa tecnologia VMP para assinar os dados de entrada e retorna uma string
wtokenpara autenticação da requisição./** * Signs the data. * @param input The data to be signed. * @return The wtoken string. */ - (NSString *)vmpSign:(NSData *)input;-
Parâmetros:
input: Tipo: NSData. Os dados a serem assinados. Normalmente, corresponde ao request body completo ou ao
whashda assinatura personalizada.
Valor de retorno: Tipo: NSString. A string
wtoken.-
Exemplo:
// Default signature configured in the console (custom signing is not selected). NSString *body = @"hello world"; NSString *wtoken = [[AliTigerTally sharedInstance] vmpSign:[body dataUsingEncoding:NSUTF8StringEncoding]]; NSLog(@"wtoken: %@", wtoken); // Custom signing configured in the console. // Custom signing for a POST request. NSString *whash = [[AliTigerTally sharedInstance] vmpHash:TT_POST input:[body dataUsingEncoding:NSUTF8StringEncoding]]; NSString *wtoken = [[AliTigerTally sharedInstance] vmpSign:[whash dataUsingEncoding:NSUTF8StringEncoding]]; NSLog(@"whash: %@, wtoken: %@", whash, wtoken); // Custom signing for a GET request. NSString *url = @"https://tigertally.aliyun.com/apptest"; NSString *whash = [[AliTigerTally sharedInstance] vmpHash:TT_GET input:[url dataUsingEncoding:NSUTF8StringEncoding]]; NSString *wtoken = [[AliTigerTally sharedInstance] vmpSign:[whash dataUsingEncoding:NSUTF8StringEncoding]]; NSLog(@"whash: %@, wtoken: %@", whash, wtoken);NotaAo usar a assinatura personalizada, o input da interface vmpSign deve ser a string
whashgerada pelo vmpHash. Ao configurar uma política baseada em cenário para App Protection, defina o Custom Signing Field comoali_sign_whash.Ao chamar vmpHash para gerar um
whashem uma requisição GET, certifique-se de que a URL de entrada seja idêntica à URL final da requisição de rede. Preste atenção à codificação da URL, pois alguns frameworks codificam caracteres ou parâmetros automaticamente.O input da interface vmpHash não pode ser um array de bytes nem uma string vazia. Se a entrada for uma URL, ela deve incluir um path ou um parâmetro.
Ao chamar vmpSign, se o request body estiver vazio (por exemplo, em uma requisição GET ou em uma requisição POST sem body), passe
nilou a representação NSData de uma string vazia, como[@"" dataUsingEncoding:NSUTF8StringEncoding].-
Se
whashouwtokenretornar uma das strings a seguir, isso indica um erro:you must call init first: A função
initnão foi chamada.you must input correct data: Os dados de entrada são inválidos.
you must input correct type: O tipo de entrada é inválido.
-
3. Verificação secundária
-
Verifique o resultado.
Para determinar se a verificação secundária é necessária, verifique o cookie e o body da resposta. Se o header contiver múltiplos campos Set-Cookie, mescle-os em uma única string de cookie antes de chamar esta interface.
/** * Checks whether to perform secondary verification. * * @param cookie The response cookie. * @param body The response body. * @return 0: Pass, 1: Secondary verification required. */ - (int)cptCheck:(NSString *)cookie body:(NSData *)body;-
Parâmetros:
cookie: Tipo: NSString. Todos os cookies na resposta da requisição.
body: Tipo: NSData. O body completo da resposta da requisição.
Valor de retorno: Tipo: int. O resultado da decisão.
0indica que a requisição foi aprovada e1indica que a verificação secundária é necessária.-
Exemplo:
NSString *cookie = @"key1=value1;key2=value2;"; NSData *body = xxx; int recheck = [[AliTigerTally sharedInstance] cptCheck:cookie body:body]; NSLog(@"recheck: %d", recheck);
-
-
Crie um slider.
Se o resultado de cptCheck indicar a necessidade de verificação, crie um objeto slider. O objeto TTCaptcha fornece os métodos
showedismisspara controlar a janela do slider. Utilize TTOption para configurar os parâmetros e TTDelegate para tratar os callbacks de status. Para personalizar a janela do slider, forneça uma URL para uma página customizada, que pode ser um arquivo HTML local ou uma página remota./** * Displays the slider for verification. * * @param view The parent component. * @param option The parameters. * @param detegate The callback protocol. */ - (TTCaptcha *)cptCreate:(UIView *)view option:(TTOption *)option delegate:(id<TTDelegate>)detegate; @protocol TTDelegate <NSObject> @required // Slider verification is successful. - (void)success:(TTCaptcha *)captcha data:(NSString *)data; // Slider verification failed. - (void)failed:(TTCaptcha *)captcha code:(NSString *)code; @end @interface TTOption : NSObject // Tap to cancel. @property (nonatomic, assign) BOOL cancelable; // Custom page. @property (nonatomic, strong) NSString *customUri; // Language. @property (nonatomic, strong) NSString *language; @end @interface TTCaptcha : NSObject - (instancetype)init:(UIView *)view option:(TTOption *)option delegate:(id<TTDelegate>)delegate; // Obtains the slider traceId for data analytics. - (NSString *)getTraceId; // Displays the slider. - (void)show; // Dismisses the slider. - (void)dismiss; @end-
Parâmetros:
view: Tipo: View. A visualização da página atual.
option: Tipo: TTOption. Os parâmetros de configuração do slider.
delegate: Tipo: TTDelegate. O callback de status do slider.
Valor de retorno: Tipo: TTCaptcha. O objeto slider.
-
Exemplo:
#pragma mark - TTDelegate - (void)failed:(TTCaptcha *)captcha code:(nonnull NSString *)code { NSLog(@"captcha failed: %@", code); } - (void)success:(TTCaptcha *)captcha data:(nonnull NSString *)data { NSLog(@"captcha success: %@", data); } TTOption *option = [[TTOption alloc] init]; // option.customUri = @"ali-tt-captcha-demo-ios"; option.language = @"cn"; option.cancelable = true; TTCaptcha *captcha = [[AliTigerTally sharedInstance] cptCreate:[self view] option:option delegate:self]; [captcha show];NotaO erro "Verification failed" indica que uma exceção foi detectada durante ou após a interação do usuário com o slider.
A tabela a seguir descreve os códigos de erro.
1001: Falha no desafio de verificação.
1002: Ocorreu uma exceção de sistema.
1003: Um parâmetro inválido foi especificado.
1005: A verificação foi cancelada.
8001: Falha ao exibir o slider.
8002: Ocorreu uma exceção nos dados de verificação do slider.
8003: Ocorreu uma exceção interna durante a verificação do slider.
8004: Ocorreu um erro de rede.
-
Boas práticas
#import "DemoController.h"
#if __has_include(<AliTigerTally_NOIDFA/AliTigerTally_NOIDFA.h>)
#import <AliTigerTally_NOIDFA/AliTigerTally_NOIDFA.h>
#else
#import <AliTigerTally_IDFA/AliTigerTally_IDFA.h>
#endif
@interface DemoController () <TTDelegate>
@end
static NSString *kAppHost = @"******";
static NSString *kAppUrl = @"******";
static NSString *kAppkey = @"******";
@implementation DemoController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self doTest];
}
- (void)doTest {
NSThread *thread = [[NSThread alloc] initWithBlock:^{
// Initialize the SDK.
NSMutableDictionary *options = [[NSMutableDictionary alloc] init];
// [options setValue:@"1" forKey:@"Intl"]; // Configure for international reporting.
int code = [[AliTigerTally sharedInstance] init:kAppkey collectType:TT_DEFAULT options:options listener:nil];
NSLog(@"tigertally init: %d", code);
// Do not make a synchronous call immediately.
[NSThread sleepForTimeInterval:2.0];
// Generate the signature.
NSString *body = @"hello world";
NSString *whash = nil, *wtoken = nil;
// Custom signing.
whash = [[AliTigerTally sharedInstance] vmpHash:TT_Post input:[body dataUsingEncoding:NSUTF8StringEncoding]];
wtoken = [[AliTigerTally sharedInstance] vmpSign:[whash dataUsingEncoding:NSUTF8StringEncoding]];
NSLog(@"tigertally vmp: %@, %@", whash, wtoken);
// Default signing.
// wtoken = [[AliTigerTally sharedInstance] vmpSign:[body dataUsingEncoding:NSUTF8StringEncoding]];
// NSLog(@"tigertally vmp: %@", wtoken);
[self doPost:kAppUrl host:kAppHost whash:whash wtoken:wtoken body:[body dataUsingEncoding:NSUTF8StringEncoding] callback:^(NSInteger code, NSString * _Nonnull cookie, NSData * _Nonnull body) {
int check = [[AliTigerTally sharedInstance] cptCheck:cookie body:body];
NSLog(@"captcha result:%d", check);
if (check == 0) return;
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self doShow];
}];
}];
}];
[thread start];
}
- (void