Amebis / eduVPN

Windows eduVPN Client
GNU General Public License v3.0
40 stars 16 forks source link

App does not support redirects #161

Closed jornane closed 2 years ago

jornane commented 3 years ago

I've changed some of the endpoints on my controller, and set up permanent redirects, and made sure the correct endpoints are listed in info.json.

When a user tries to refresh, the following error is logged:

System.Net.WebException: Den eksterne serveren returnerte feilen (308) Permanent Redirect.
Full log System.AggregateException: Det oppsto én eller flere feil. ---> System.Net.WebException: Den eksterne serveren returnerte feilen (308) Permanent Redirect. ved eduOAuth.AccessToken.RefreshToken(WebRequest request, NetworkCredential client_cred, CancellationToken ct) ved eduVPN.ViewModels.Windows.ConnectWizard.Instance_RequestAuthorization(Object sender, RequestAuthorizationEventArgs e) ved eduVPN.Models.Instance.GetUserInfo(Instance authenticating_instance, CancellationToken ct) ved eduVPN.ViewModels.VPN.VPNSession.<.ctor>b__62_1() ved eduVPN.ViewModels.VPN.VPNSession.b__63_0(Action action) ved System.Threading.Tasks.Parallel.<>c__DisplayClass17_0`1.b__1() ved System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask) ved System.Threading.Tasks.Task.<>c__DisplayClass176_0.b__0(Object ) --- Slutten på sporingen av intern unntaksstakk --- ved eduVPN.ViewModels.VPN.VPNSession.Run() ved eduVPN.ViewModels.Windows.ConnectWizard.<>c__DisplayClass24_0.b__2() ---> (indre unntak nummer 0) System.Net.WebException: Den eksterne serveren returnerte feilen (308) Permanent Redirect. ved eduOAuth.AccessToken.RefreshToken(WebRequest request, NetworkCredential client_cred, CancellationToken ct) ved eduVPN.ViewModels.Windows.ConnectWizard.Instance_RequestAuthorization(Object sender, RequestAuthorizationEventArgs e) ved eduVPN.Models.Instance.GetUserInfo(Instance authenticating_instance, CancellationToken ct) ved eduVPN.ViewModels.VPN.VPNSession.<.ctor>b__62_1() ved eduVPN.ViewModels.VPN.VPNSession.b__63_0(Action action) ved System.Threading.Tasks.Parallel.<>c__DisplayClass17_0`1.b__1() ved System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask) ved System.Threading.Tasks.Task.<>c__DisplayClass176_0.b__0(Object )<--- ---> (indre unntak nummer 1) System.Net.WebException: Den eksterne serveren returnerte feilen (308) Permanent Redirect. ved eduOAuth.AccessToken.RefreshToken(WebRequest request, NetworkCredential client_cred, CancellationToken ct) ved eduVPN.ViewModels.Windows.ConnectWizard.Instance_RequestAuthorization(Object sender, RequestAuthorizationEventArgs e) ved eduVPN.ViewModels.VPN.VPNSession.<.ctor>b__62_2() ved eduVPN.ViewModels.VPN.VPNSession.b__63_0(Action action) ved System.Threading.Tasks.Parallel.<>c__DisplayClass17_0`1.b__1() ved System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask) ved System.Threading.Tasks.Task.<>c__DisplayClass176_0.b__0(Object )<--- ---> (indre unntak nummer 2) System.Net.WebException: Den eksterne serveren returnerte feilen (308) Permanent Redirect. ved eduOAuth.AccessToken.RefreshToken(WebRequest request, NetworkCredential client_cred, CancellationToken ct) ved eduVPN.ViewModels.Windows.ConnectWizard.Instance_RequestAuthorization(Object sender, RequestAuthorizationEventArgs e) ved eduVPN.Models.Profile.GetOpenVPNConfig(CancellationToken ct) ved eduVPN.ViewModels.VPN.OpenVPNSession.<.ctor>b__10_1() ved eduVPN.ViewModels.VPN.VPNSession.b__63_0(Action action) ved System.Threading.Tasks.Parallel.<>c__DisplayClass17_0`1.b__1() ved System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask) ved System.Threading.Tasks.Task.<>c__DisplayClass176_0.b__0(Object )<--- ---> (indre unntak nummer 3) System.Net.WebException: Den eksterne serveren returnerte feilen (308) Permanent Redirect. ved eduOAuth.AccessToken.RefreshToken(WebRequest request, NetworkCredential client_cred, CancellationToken ct) ved eduVPN.ViewModels.Windows.ConnectWizard.Instance_RequestAuthorization(Object sender, RequestAuthorizationEventArgs e) ved eduVPN.Models.Instance.GetClientCertificate(Instance authenticating_instance, CancellationToken ct) ved eduVPN.ViewModels.VPN.OpenVPNSession.<.ctor>b__10_2() ved eduVPN.ViewModels.VPN.VPNSession.b__63_0(Action action) ved System.Threading.Tasks.Parallel.<>c__DisplayClass17_0`1.b__1() ved System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask) ved System.Threading.Tasks.Task.<>c__DisplayClass176_0.b__0(Object )<---
jornane commented 3 years ago

The plot thickens; restarting eduVPN caused the profile to be removed. User did not remove it themselves.

Might that be an effect of the URLs in info.json changing?

rozmansi commented 3 years ago

Thank you for your report.

The System.Net.WebRequest support for HTTP redirects is an opt-in. Will enable it.

The plot thickens; restarting eduVPN caused the profile to be removed. User did not remove it themselves.

You mean "server", not "profile", right? When there is something wrong with a particular server, the v2.0 client won't display it. So, this is temporary and expected behaviour. I expect fixing the initial problem should show the server back on the list.

Stay tuned...

jornane commented 3 years ago

You mean "server", not "profile", right?

In geteduroam we call this "profile" but I think eduVPN has more shared state within a server? I suppose I meant "server" then.

When there is something wrong with a particular server, the v2.0 client won't display it. So, this is temporary and expected behaviour.

Ah, that's a bit confusing. The user adds the server back, which works, but after restarting the client it's gone again. Adding it back manually after it's hidden should probably remove the old server?

rozmansi commented 3 years ago

The System.Net.WebRequest support for HTTP redirects is an opt-in. Will enable it.

Looks like, the HTTP redirection in WebRequest is enabled by default. Thou, it clears Authorization header. But OAuth token refresh request doesn't use this header. OAuth token refresh request is POST. Maybe WebRequest has issues with POST redirects. I assume it doesn't handle 308 Permanent Redirect case (correctly). I might code it myself.

You mean "server", not "profile", right?

In geteduroam we call this "profile" but I think eduVPN has more shared state within a server? I suppose I meant "server" then.

Chasing the issue, I see you are using 1.x client, sorry. We were not on the same page here.

Would it be possible to arrange me a test account on this server, so I can debug the client on this particular eduVPN instance and see why 308 redirects fail? My e-mail is simon@rozman.si.

If this is not such a big-scale problem (only one or a few users affected), maybe just ask users to do the rd /s "%LOCALAPPDATA%\SURF" and make a fresh start. The info.json file is cached locally and updated on If-Modified-Since basis. 1.0.28 discontinued info.json seq checking. So, it's only up to file modification timestamp to make clients refresh it and avoid the 308 redirect. Or, nuking the client settings in %LOCALAPPDATA%\SURF.

ghost commented 3 years ago

Why would you follow redirects on POSTS? From what I gather here, only requests for info.json point to another server?

rozmansi commented 3 years ago

The stack trace in the original post indicates that requests to https://<server>/vpn-user-portal/oauth.php/token are 308-redirected. Maybe the client has stale info.json and tries to contact the old endpoint at which Jørn arranged a redirect.

I agree: updating endpoints in info.json should be enough.

Maybe the new endpoint/server uses a redirection?

ghost commented 3 years ago

I agree: updating endpoints in info.json should be enough.

Only redirecting info.json would not be enough? Due to caching, right?

The info.json response includes this header:

Cache-Control: no-store

So this means that clients should never cache it and always refetch if I am correct?


Maybe for the future we can think of how to handle renaming servers? Nobody made a proposal for that yet, but it could also be nice to have this option when we release eduVPN/Let's Connect! 3.x so one could setup a 3.x server and at some point "switch" to the new one in a supported (and tested) way.

jornane commented 3 years ago

It seems that HttpClient does not follow the HTTP specification for redirects then.

I agree with @fkooman, the best solution seems to me to reload the URLs from info.json, so that the old URL is never tried and thus the redirect isn't needed.

jornane commented 3 years ago

@fkooman the following user agents have tried to GET ${VPN_APP_ROOT}/oauth.php/token

So I suppose the bug is present in at least the Windows and Apple versions of the eduVPN app.