Search code examples
iosxamarinkeychaintouch-id

ios keychain query record without additional prompt


i've got a question regarding touch-id and how to use it with KeyChain. I am currently developing an app, where the user is able to retrieve a token from the keychain and login with said token (if it is valid ofc).

Currently, i'm doing it somewhat like this:

 var accessTokenRecord = new SecRecord(SecKind.GenericPassword)
                    {
                        Account = username,
                        Service = AccessTokenIdentifier,
                    };
                    var matchingAccessTokenRecord =
                    SecKeyChain.QueryAsRecord(accessTokenRecord, out SecStatusCode accessTokenStatusCode);
                    if (accessTokenStatusCode == SecStatusCode.Success)
                    {
                        var accessToken = new JwtSecurityToken(matchingAccessTokenRecord.ValueData.ToString());
                        var tokenString = matchingAccessTokenRecord.ValueData.ToString();
                        if (accessToken.ValidTo.CompareTo(DateTime.Now) < 0)
                        {
                            // accesstoken ran out/expired, neet to refresh
                            var refreshTokenRecord = new SecRecord(SecKind.GenericPassword)
                            {
                                Account = username,
                                Service = RefreshTokenIdentifier,
                            };
                            var matchingRefreshTokenRecord =
                                SecKeyChain.QueryAsRecord(refreshTokenRecord, out var refreshTokenStatusCodes);
                            if (refreshTokenStatusCodes == SecStatusCode.Success)
                            {
                                var newTokenInformation =
                                    await LoginWithRefreshToken(matchingAccessTokenRecord.ValueData.ToString(),
                                        matchingRefreshTokenRecord.ValueData.ToString());
                                var result =
                                    StoreAccessAndRefreshTokenForUser(newTokenInformation, username,
                                        ShowFailureInfo);
                                if (result)
                                {
                                    tokenString = newTokenInformation.TokenString;
                                }
                            }

                        }
                        // login with token
                        LoginWithToken(tokenString);                            
                    }

My Problem now is that the QueryAsRecord Method triggeres the touch-id prompt everytime it is used. I feel like it's not very user friendly to ask the user twice in case the accesstoken ran out and a new one needs to be requested with the refreshtoken.

I didn't find any way around this, does someone else may have a suggestion how the additional prompt can be averted?


Solution

  • Since there doesn't seem to be a way around it, I just placed both tokens in the same entry.