I noticed that I need not set the NEVPNProtocolIKEv2's passwordReference
if I supplied the userName
and password
via the options
argument in startVPNTunnel
.
Supply password using passwordReference
(requires use of Keychain):
func connect(userName: String, password: String, serverAddress: String) async throws {
saveToKeychain(key: "VPN_Password", value: password)
let passwordReference = keychainReference(key: "VPN_Password")
let vpn = NEVPNManager.shared()
try await vpn.loadFromPreferences()
let pc = NEVPNProtocolIKEv2()
pc.serverAddress = serverAddress
pc.authenticationMethod = .none
pc.username = userName
pc.passwordReference = passwordReference
pc.useExtendedAuthentication = true
vpn.protocolConfiguration = pc
vpn.isEnabled = true
try await vpn.saveToPreferences()
try await vpn.loadFromPreferences()
try vpn.connection.startVPNTunnel()
}
Supply password using options
parameter in startVPNTunnel
:
func connect(userName: String, password: String, serverAddress: String) async throws {
let vpn = NEVPNManager.shared()
try await vpn.loadFromPreferences()
let pc = NEVPNProtocolIKEv2()
pc.serverAddress = serverAddress
pc.authenticationMethod = .none
pc.useExtendedAuthentication = true
vpn.protocolConfiguration = pc
vpn.isEnabled = true
try await vpn.saveToPreferences()
try await vpn.loadFromPreferences()
try vpn.connection.startVPNTunnel(options: [NEVPNConnectionStartOptionUsername: userName, NEVPNConnectionStartOptionPassword: password])
}
Is one preferred over the other? I'm inclined to use the second one as it doesn't require the (additional) use of the Keychain. Are there any drawbacks in doing do?
When is it appropriate to use the second approach?
Honestly, not very often. Most users don’t launch your app to start the VPN connection. Rather, they start it from a system UI or using VPN On Demand. In that case the password has to be available in the keychain because your main app is not running at the time that the system starts the connection.
The second approach only makes sense if your VPN is structured such that the user has to start it from your app. That’s a pretty clunky user experience IMO.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"