Ошибка выполнения запроса CredStore

Я сталкиваюсь с проблемой при выполнении API-вызовов к своему бэкэнду приложений, каждое соединение теперь запрашивает

CredStore - performQuery - Error copying matching creds.  Error=-25300, query={
    atyp = http;
    class = inet;
    "m_Limit" = "m_LimitAll";
    ptcl = http;
    "r_Attributes" = 1;
    srvr = "myappsurl.com";
    sync = syna;
}

Я немного растерялся, так как не уверен, что является причиной этого или что делает CredStore. Какую цель служит CredStore в iOS?

16 ответов

Решение

Эта ошибка возникает при попытке получить URLCredential от URLCredentialStorage для неизвестного URLProtectionSpace, например

let protectionSpace = URLProtectionSpace.init(host: host, 
                                              port: port, 
                                              protocol: "http", 
                                              realm: nil, 
                                              authenticationMethod: nil)

var credential: URLCredential? = URLCredentialStorage.shared.defaultCredential(for: protectionSpace)

производит

CredStore - performQuery - Error copying matching creds.  Error=-25300, query={
    class = inet;
    "m_Limit" = "m_LimitAll";
    ptcl = http;
    "r_Attributes" = 1;
    srvr = host;
    sync = syna;
}

Дайте ему учетные данные для защитного пространства:

let userCredential = URLCredential(user: user, 
                                   password: password, 
                                   persistence: .permanent)

URLCredentialStorage.shared.setDefaultCredential(userCredential, for: protectionSpace)

и ошибка исчезнет в следующий раз, когда вы попытаетесь получить учетные данные.

Я немного растерялся, так как не уверен, что является причиной этого или что делает CredStore. Какую цель служит CredStore в iOS?

Хранилище учетных данных в iOS позволяет пользователям безопасно или временно хранить в связке ключей учетные данные на основе сертификатов или паролей на устройстве.

Я подозреваю, что у вас есть какой-то тип аутентификации на вашем бэкэнд-сервере, и этот сервер запрашивает аутентификацию вашего приложения (для которого нет учетных данных).

Это, вероятно, может быть безопасно проигнорировано как возвращение ноль из URLCredentialStorage является действительным ответом

Я не уверен, почему мы получаем эту ошибку при выполнении запросов с Alamofire, но если вы делаете запросы API с некоторым токеном в заголовках HTTP, вам, возможно, вообще не понадобится хранилище учетных данных. Таким образом, мы можем отключить его для нашего запроса:

let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = ourHeaders
// disable default credential store
configuration.urlCredentialStorage = nil

let manager = Alamofire.SessionManager(configuration: configuration)
...

Никаких ошибок после такого изменения.

Это ошибка транспорта, давайте добавим разрешение для транспорта следующим образом:

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>

Будьте осторожны, так как это позволяет подключаться к любому серверу из вашего приложения. Узнайте больше о App Transport Security, прежде чем продолжить. Смотрите комментарий @kezi

Эта же проблема возникает со мной, и я обнаружил, что если ваш URL-адрес API не содержит "/" в конце URL-адреса, то iOS не отправляет серверу значение "Authorization". Из-за чего вы увидите сообщение типа опубликовано в вопросе в консоли.

Так что просто добавьте "/" в конце URL

https://example.com/api/devices/

В моем случае я не инициализировал Stripe SDK с ключом API.

        STPPaymentConfiguration.shared().publishableKey = publishableKey

В случае любой операции Stripe, если мы можем распечатать журнал ошибок, это легко понять.

        print(error.debugDescription)

Если вы получаете эту ошибку, при использовании AVPlayer, просто вызовите.play() в главном потоке

Я получил эту ошибку из-за того, что я случайно использовал два пробела между "Носителем" и маркером доступа в моем заголовке авторизации.

Неправильно:

request.setValue("Bearer  \(accessToken)", forHTTPHeaderField: "Authorization")

Правильный:

request.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")

Простая ошибка, но потребовалось время, чтобы найти ее.

Я отредактировал строку, содержащую URL, чтобы исправить эту проблему:

var myUrl = "http://myurl.com"
myUrl = myUrl.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed)!

let url = URL(string: myUrl)

Хорошо, у меня была эта ошибка, и я боролся с ней долгое время (годы) при взаимодействии с моим приложением Ruby on Rails.

У меня были учетные данные по умолчанию, настроенные, как описано в принятом ответе, но я все еще получил ошибку, и полагался на ответ didReceiveChallenge для предоставления учетных данных - к счастью, это работало как обходной путь.

Но! Я только что нашел решение!

Я работал над догадкой, что поля protectedSpace не соответствуют задаче авторизации с сервера Ruby on Rails, и я посмотрел на поле области, которое, похоже, было единственным, которое осталось неопределенным.

Я начал с распечатки заголовков ответа сервера, и, хотя я был в состоянии проверить их, они не включали поле WWW-авторизации, которое включало бы поле области.

Я подумал, что это может быть из-за того, что в моем приложении на Rails не указана сфера, поэтому я начал смотреть на вещи Rails.

Я обнаружил, что могу указать область в вызове,

authenticate_or_request_with_http_basic

... который я использую для проверки подлинности HTTP Basic.

Я не указывал область уже, поэтому добавил,

authenticate_or_request_with_http_basic("My Rails App")

Затем я добавил соответствующую строку в ProtectionSpace,

NSURLProtectionSpace *protectionSpace =
    [[NSURLProtectionSpace alloc] initWithHost:@"myrailsapp.com"
        port:443
        protocol:NSURLProtectionSpaceHTTPS
        realm:@"My Rails App"
        authenticationMethod:NSURLAuthenticationMethodHTTPBasic];

Вуаля! Это сработало, и я больше не понимаю,

CredStore - performQuery - Error copying matching creds.  Error=-25300

Даже после указания области в приложении Rails, я все еще не вижу его переданным в заголовке HTTP, я не знаю почему, но по крайней мере это работает.

Ошибка также может быть вызвана политикой безопасности контента (CSP), которая может быть слишком строгой. В нашем случае нам был нужен CSP, который более или менее полностью открыт и позволяет все. Имейте в виду, что открытие CSP может быть серьезной проблемой безопасности (в зависимости от того, что именно вы делаете в приложении).

Я получил эту проблему, когда пытался открыть http-страницу внутри веб-просмотра. Но эта страница содержала всплывающее окно, которое открывалось первым.

Когда бэкэнд-команда удалила это всплывающее окно, все стало хорошо.

При работе с Stripe IOS SDK я обнаружил, что мне следовало добавить публикуемый ключ из stripe.

Это устанавливается в AppDelegate, как указано в https://stripe.com/docs/development/quickstart, шаг 2.

      func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        StripeAPI.defaultPublishableKey = "pk_test_....."
        return true
    }

Моя проблема заключалась в кодировке base64 изображения, которое отправлялось с вызовом отдыха

Я ранее использовал

      let strBase64 = imageData.base64EncodedString(options: .lineLength64Characters)

Но в 50% случаев я получал ошибку, указанную выше.

Вместо этого я использовал следующее, что решило мою проблему ...

       let strBase64 = imageData.base64EncodedString()

Была такая же проблема со входом в Twitter. Оказалось, что я использовал неправильный ключ API.

Я удаляю .cURLDescription на

      AF.request(url)

и этот журнал исчез

    let credentialData = "\(user):\(password)".data(using: String.Encoding.utf8)!
    let base64Credentials = credentialData.base64EncodedString(options: [])
    let headers = ["Authorization": "Basic \(base64Credentials)"]
    Alamofire.request(url, method: .get, parameters: params,encoding: URLEncoding.default,headers: headers)
                .responseJSON{
            response in
            guard let value =  response.result.value else {return}
                    print(value)
     }
Другие вопросы по тегам