问题描述
我有一个通过 VPN 连接到网络应用的小型 Android 应用。
应用程序会显示一个向导,用于输入和保存网络应用程序的所有凭据(域、端口、http/s、用户和密码)。 当用户保存时,我会检查 URL 是否可以访问并显示警告或移动到包含 WebView 的下一个活动。
这是用户点击保存时发生的情况:
fun triggerSaveSettingsAction()
{
Log.i("MyApp","ServerWizardActivity > triggerSaveSettingsAction")
if(checkInputData() == false)
{
displayDialogBox("WARNING",message = "Please fill in all the fields in order to continue!")
}
else
{
val serverAddress: String = tvServerAddress?.text?.replace("\\s".toRegex(),"").toString()
val serverPort: String = tvServerPort?.text?.replace("\\s".toRegex(),"").toString()
val serverUser: String = tvServerUser?.text?.replace("\\s".toRegex(),"").toString()
val serverPassword: String = tvServerPassword?.text?.replace("\\s".toRegex(),"").toString()
val isSecureServer: String = (cbSecureServer?.isChecked == true).toString()
setProgressBarVisible()
checkURLResponse(serverAddress,serverPort,isSecureServer)
Timer("SettingUp",false).schedule(3000) // Nasty workaround to prevent setProgressBarInvisible to early
{
if(isReachable!!)
{
sharedPref!!.saveDataToSharedPreferences("serverAddress",serverAddress)
sharedPref!!.saveDataToSharedPreferences("serverPort",serverPort)
sharedPref!!.saveDataToSharedPreferences("serverUser",serverUser)
sharedPref!!.saveDataToSharedPreferences("serverPassword",serverPassword)
sharedPref!!.saveDataToSharedPreferences("isSecureServer",isSecureServer)
runOnUiThread{
setProgressBarInvisible()
displayDialogBox("NOTIFICATION","The new settings will become availiable the next time you start the application!")
}
}
else
{
runOnUiThread{
setProgressBarInvisible()
displayDialogBox("WARNING","The server address or port are not valid or there is a problem with your Internet connection!")
}
}
}
}
}
这里是checkURLResponse(serverAddress,isSecureServer)
:
fun checkURLResponse(serverAddress: String,serverPort: String,isSecureServer: String)
{
Log.i("MyApp","ServerWizardActivity > checkURLResponse")
var fullURL: String? = null
val partialURL: String? = "/main.html"
if(isSecureServer.toBoolean()) { fullURL = "https://$serverAddress:$serverPort${partialURL}" }
else { fullURL = "http://$serverAddress:$serverPort${partialURL}" }
Thread{
Log.i("MyApp","ServerWizardActivity > Thread")
try
{
val url = URL(getPartialURL())
val urlc = url.openConnection() as HttpURLConnection
urlc.connectTimeout = 3 * 1000
urlc.connect()
if ((urlc.responseCode >= 200) && (urlc.responseCode <= 299))
{
Log.i("Connection","Try > Success!")
isReachable = true
}
else
{
Log.i("Connection","Try > Failed!")
}
}
catch (e: Exception)
{
Log.i("Connection","Catch > Failed!")
}
}.start()
}
撇开讨厌的解决方法不谈,这适用于不需要 VPN 连接的其他域。
在这种情况下,我明白了:
I/System.out: (HTTPLog)-Static: isSBSettingEnabled false
I/System.out: (HTTPLog)-Static: isSBSettingEnabled false
E/Conscrypt: ------------------Untrusted chain: ----------------------
== Chain0 ==
Version: 3
Serial Number: [Serial Number Here]
E/Conscrypt: SubjectDN: CN=,OU=,O=,C=
E/Conscrypt: IssuerDN: CN=,C=
E/Conscrypt: Get not before: Fri Mar 19 15:46:56 GMT+02:00 2021
E/Conscrypt: Get not after: Sat Mar 19 15:46:56 GMT+02:00 2022
Sig ALG name: [Serial Number Here]
E/Conscrypt: Signature: [Sig ALG Name Here]
E/Conscrypt: Public key: [Public Key Here]
== Chain1 ==
Version: 3
Serial Number: 9
E/Conscrypt: SubjectDN: CN=,C=
E/Conscrypt: Get not before: Wed Mar 23 17:45:49 GMT+02:00 2016
Get not after: Mon Mar 23 17:45:49 GMT+02:00 2026
E/Conscrypt: Sig ALG name: [Sig ALG Name Here]
E/Conscrypt: Signature: [Signature Here]
E/Conscrypt: Public key: [Public Key Here]
I/Connection: Catch > Failed!
Catch > javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.!
I/MyApp: ServerWizardActivity > setProgressBarInvisible
I/MyApp: ServerWizardActivity > displayDialogBox
D/ScrollView: initGoToTop
D/ViewRootImpl@64e7312[ServerWizardActivity]: setView = DecorView@862aae3[] TM=true MM=false
D/ViewRootImpl@64e7312[ServerWizardActivity]: dispatchAttachedToWindow
V/Surface: sf_framedrop debug : 0x4f4c,game : false,logging : 0
D/ViewRootImpl@64e7312[ServerWizardActivity]: Relayout returned: old=[0,0][0,0] new=[27,659][1053,1261] result=0x7 surface={valid=true 530991779840} changed=true
D/mali_winsys: EGLint new_window_surface(egl_winsys_display *,void *,EGLSurface,EGLConfig,egl_winsys_surface **,egl_color_buffer_format *,EGLBoolean) returns 0x3000,[1218x794]-format:1
D/Openglrenderer: eglCreateWindowSurface = 0x7bbabaf0b0
D/ScrollView: onsize change changed
D/ViewRootImpl@64e7312[ServerWizardActivity]: MSG_WINDOW_FOCUS_CHANGED 1
D/ViewRootImpl@64e7312[ServerWizardActivity]: MSG_RESIZED_REPORT: frame=Rect(27,659 - 1053,1261) ci=Rect(0,0 - 0,0) vi=Rect(0,0) or=1
D/ViewRootImpl@9d719a3[ServerWizardActivity]: MSG_WINDOW_FOCUS_CHANGED 0
iOS 版本使用相同的凭据和 VPN 运行良好。 此外,该 URL 可在任何浏览器中访问。
不确定这是手机相关问题还是连接问题,因为我只有一部手机要测试(三星 galaxy S7,Android 8.0)。
我找到了几个 threads claiming this is a Samsung-only issue,但无法验证。此外,对我来说,它看起来更像是证书问题。但这并不能解释为什么它可以在浏览器和 iOS 应用中运行。
有什么想法吗?
乐:
看来毕竟是证书错误 - SEC_ERROR_UNKNowN_ISSUER。
我设法使用 handler.proceed()
绕过它:
override fun onPageStarted(view: WebView?,url: String,favicon: Bitmap?)
{
Log.i("MyApp","MainActivity > onPageStarted")
super.onPageStarted(view,url,favicon)
val currentURL: String? = wvMainView!!.url
Log.i("MyApp","MainActivity > onPageStarted > ${currentURL}")
view?.setWebViewClient(object : WebViewClient()
{
override fun onReceivedSslError(view: WebView,handler: SslErrorHandler,error: SslError)
{
Log.i("MyApp","MainActivity > shouldOverrideUrlLoading > ${error}")
Log.i("MyApp","MainActivity > onReceivedSslError > currentURL > ${currentURL!!}")
handler.proceed()
}
})
}
问题是,在 onPageStarted
和 onPageFinished
中,我正在根据当前 URL 执行一些操作。
基本上,我有很多这样的 if:if(currentURL!!.contains("main.html"))
.
不幸的是,现在似乎 currentURL 总是返回相同的 URL,即初始 URL。无论我在网络应用程序中做什么,它都会返回初始 URL。
此外,如果我尝试将它与没有证书错误的网络应用程序一起使用,它会无法加载。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)