web-dev-qa-db-fra.com

iOS KeyChain ne récupère pas les valeurs de l'arrière-plan

Je stocke actuellement le nom d'utilisateur (e-mail) et un hachage salé de l'e-mail et du mot de passe dans iOS KeyChain. J'utilise la version ARC'ified trouvée ici .

KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"MyCustomIdentifier" accessGroup:nil];
[wrapper setObject:APP_NAME forKey:(__bridge id)kSecAttrService];
[wrapper setObject:email forKey:(__bridge id)kSecAttrAccount];
[wrapper setObject:token forKey:(__bridge id)kSecValueData];

Tout cela fonctionne bien lorsque j'ai besoin de retirer le jeton pour mes appels réseau pendant que l'application est active. Il fonctionne pour se connecter à partir d'un démarrage propre, ainsi que pour tous les appels réseau. Le problème commence lorsque l'application est en arrière-plan.

Gardez à l'esprit que cela ne se produit que sporadiquement et que je ne l'ai pas encore identifié avec une version ou un appareil iOS spécifique.

L'utilisateur déclenche un emplacement (surveillance de la région) et je souhaite mettre à jour le serveur avec son état. J'essaie de retirer le jeton du trousseau, de la même manière que pour tous les autres appels réseau, et de mettre à jour l'état. Mais pour certains utilisateurs, la valeur est nulle. Sans cela, je ne peux pas mettre à jour les éléments du réseau. Pourquoi cela fonctionnerait-il pour la plupart, mais pas pour un petit pourcentage?

KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"MyCustomIdentifier" accessGroup:nil];
NSString *token = [wrapper objectForKey:(__bridge id)kSecValueData];

Je suis retourné à la version non-ARC du keychainwrapper, mais j'obtiens toujours les mêmes résultats. J'apprécierais tout commentaire à ce sujet. Ce n'est qu'une petite partie de mes utilisateurs, mais c'est un problème que je voudrais résoudre et ne pas m'inquiéter. Merci d'avance.

De plus, tout mon travail en arrière-plan est configuré dans une tâche en arrière-plan pour empêcher les choses de se terminer. Je n'ai aucun problème avec le travail entourant le trousseau, mais je ne laisse pas les choses avancer tant que mon jeton n'est pas rempli.

[~ # ~] modifier [~ # ~] J'ai résolu mon problème avec le trousseau qui ne récupérait pas les valeurs de l'arrière-plan. Je posterai la réponse ci-dessous et l'accepterai car je pense que cette question pourrait devenir utile à d'autres plus tard.

79
Bill Burgess

Ma question était proche de la marque pour la raison, mais pas tout à fait. Après avoir lu blog après blog, tutoriel après tutoriel, j'en ai finalement trouvé un qui donnait un aperçu de ce qui pourrait se passer.

Écrans d'accueil verrouillés. Les didacticiels sur le trousseau de clés laissaient toujours les paramètres d'accessibilité pour le trousseau vide, de sorte qu'il serait par défaut au niveau d'accès le plus bas/le plus sûr d'Apple. Ce niveau ne permet cependant pas l'accès au trousseau si l'utilisateur a un code d'accès sur l'écran de verrouillage. Bingo! Cela explique le comportement sporadique et pourquoi cela n'arrive qu'à un petit pourcentage d'utilisateurs.

Une ligne de code, résout tout le désordre.

[wrapper setObject:(__bridge id)kSecAttrAccessibleAlways forKey:(__bridge id)kSecAttrAccessible];

Ajoutez cette ligne où je définis les valeurs de nom d'utilisateur et de mot de passe. Fonctionne comme un charme. J'espère que cela aidera quelqu'un là-bas. Cela m'a dérouté pendant un bon moment jusqu'à ce que je sois capable de rassembler les pièces.

102
Bill Burgess

Utilisez kSecAttrAccessibleAfterFirstUnlock au lieu de kSecAttrAccessibleAlways.


De documentation d'Apple :

kSecAttrAccessibleAfterFirstUnlock
Les données de l'élément de trousseau ne sont pas accessibles après un redémarrage jusqu'à ce que l'appareil ait été déverrouillé une fois par l'utilisateur.

Après le premier déverrouillage, les données restent accessibles jusqu'au prochain redémarrage. Ceci est recommandé pour les éléments auxquels les applications d'arrière-plan doivent accéder. Les éléments avec cet attribut migrent vers un nouveau périphérique lors de l'utilisation de sauvegardes chiffrées.

54
woof

Dans mon cas, watchOS2 accède aux données du trousseau du côté iOS.

Au début, kSecAttrAccessibleWhenUnlockedThisDeviceOnly est utilisé. Je peux lire les données, que l'iPhone soit verrouillé ou non. Il est très déroutant pour moi que je reçoive une erreur lorsque la montre tente d'accéder au trousseau:: SecTrustEvaluate [leaf IssuerCommonName SubjectCommonName]

Et dans certains cas, il deviendra:: SecOSStatusWith error: [- 25308] Error Domain = NSOSStatusErrorDomain Code = -25308 "ks_crypt: e00002e2 n'a pas réussi à" oe "l'élément (classe 6, sac: 0) L'accès à l'élément a été tenté alors que le trousseau est verrouillé. " UserInfo = {NSDescription = ks_crypt: e00002e2 n'a pas réussi à "oe" l'élément (classe 6, sac: 0) L'accès à l'élément a été tenté alors que le trousseau est verrouillé.}

Je mettrai à jour ma réponse si j'obtiens plus d'informations.

1
skingtree