微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

不良网络上的NEVPNManager身份验证弹出窗口

如何解决不良网络上的NEVPNManager身份验证弹出窗口

我正在使用一个VPN应用程序,其中所有服务器都使用IPSec协议。在iOS客户端上,我使用NEVPNManager建立我的VPN连接。它可以在适当的网络上正常运行。

但是有时用户在连接到VPN服务器时弹出,显示“输入您的用户身份验证” ,尽管我从钥匙串中设置了密码,但用户名字段已填写,但密码字段为空。

调查之后,我猜测用户的网络连接不良或不稳定时,会显示此弹出窗口。

为模拟这种情况,我从设置->开发人员中选择网络链接条件作为边缘网络质量很差在我的设备上。这将使弹出窗口的发生率几乎达到95%。

是否可以检测何时触发弹出窗口?另外,当我从钥匙串设置密码时,显示此消息的原因是什么?

private var manager: NEVPNManager {
    return NEVPNManager.shared()
}

fileprivate func loadPreferances(_ completion: @escaping () -> Void) {
    manager.loadFromPreferences { error in
        assert(error == nil,"Failed to load preferences: \(error!.localizedDescription)")
        completion()
    }
}


fileprivate func _save(_ vpn: VPN,completion: VPNConfigureCompletion?) {
    #if targetEnvironment(simulator)
        assert(false,"I'm afraid you can not connect VPN in simulators.")
    #endif
    
    let ipsec = NEVPNProtocolIPSec()
    ipsec.useExtendedAuthentication = true
    ipsec.authenticationMethod = .sharedSecret
    ipsec.sharedSecretReference = KeychainHelper.getVPNPSK(for: vpn.serverIP)
    
    ipsec.username = vpn.username
    ipsec.passwordReference = KeychainHelper.getVPNPassword(for: vpn.serverIP)
    
    ipsec.serverAddress = vpn.serverIP
    ipsec.disconnectOnSleep = false

    manager.localizedDescription = "VPN"
    manager.protocolConfiguration = ipsec
    manager.isEnabled = true
    
    
    manager.ondemandRules = [NEondemandRule]()
    manager.isondemandEnabled = false
    
    manager.savetoPreferences { error in
        if let err = error {
            print("Failed to save profile: \(err.localizedDescription)")
        } else {
            completion?()
        }
    }
}

public func save(_ vpn: VPN,completion: VPNConfigureCompletion?) {
    loadPreferances { [weak self] in
        self?._save(vpn,completion: completion)
    }
}

public func connect() {
    do {
        try self.manager.connection.startVPNTunnel()
    } catch NEVPNError.configurationInvalid {
        
    } catch NEVPNError.configurationdisabled {
        
    } catch let error as NSError {
        print(error.localizedDescription)
    }
}

public func saveAndConnect(vpn: VPN,complition: @escaping ()->()) {
    KeychainHelper.setVPN(password: vpn.password,for: vpn.serverIP)
    KeychainHelper.setVPN(psk: vpn.serverPSK,for: vpn.serverIP)
    
    save(vpn) { [weak self] in
        self?.connect()
        dispatchQueue.main.async {
            complition()
        }
    }
}

KeychainHelper.swift

import KeychainAccess

struct KeychainHelper {
    
    private static var keychain: Keychain {
        return Keychain(service: Bundle.main.bundleIdentifier ?? "BundleIDDummy")
    }
        
    public static func setVPN(password: String,for address: String) {
        _ = try? keychain.remove("\(address)pass")
        keychain["\(address)pass"] = password
    }
    
    public static func getVPNPassword(for address: String) -> Data? {
        return keychain[attributes: "\(address)pass"]?.persistentRef
    }
    
    public static func setVPN(psk: String,for address: String) {
        _ = try? keychain.remove("\(address)psk")
        keychain["\(address)psk"] = psk
    }
    
    public static func getVPNPSK(for address: String) -> Data? {
        return keychain[attributes: "\(address)psk"]?.persistentRef
    }
    
}

Here is an image of the popup

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。