Our application uses TSpinxLogin component to achieve an openid authentication with OneLogin.
However in the production environment the browser doesn't show up. I think some kind of restriction causes this behaviour.
There is no exception just nothing happens.
There is edge installed on the machine and it is running on a windows terminal server (Windows Server 2019) .
We don't have any information that the component is able to open a port or not, or the browser is started by the component or not. Do you have any solution to get detailed information what is happening in the background?
Do you have any idea what we should check?
What do you mean by "production environment"? You mean it works in your development machine but not in user's machine?
Since you mentioned "port" and "browser" it's not exactly clear what's not working. The user web browser is never launched? Or the redirect URL is never reached? Can you please be more specific?
If it's the web browser not being launched, this looks simply like a restriction in user machine. It has nothing to do with TCP ports.
To launch the browser, Sphinx just asks Windows to open URL, the code is as simple as this:
Thank you for your feedback.
It works on my development machine, and doesn't work in production environment.
The production environment is a terminal server with a lot of restriction applied.
When we call SphinxLogin.Login nothing happens. The browser is never launched.
I think two things happens when we call SphinxLogin.Login: It tries to open a port for getting back a response from the browser. Launch a browser.
I forward your feedback to the admin team for further investigation.
Have you created and run the test project I suggested? Just create an empty project that launches a browser at a generic address (Google URL, for example) and see if it opens.
Please provide a call stack if you have one.
I don't think a timeout is related to port opening. A timeout is a try to connect to some server which is not responding.
This is the exact code that launches a local server that will listen to a port:
procedure TSystemBrowser.StartListener(UrlCallback: TCallbackUrlProc);
var
BaseUrl: string;
Uri: IUri;
Port: Integer;
FinishedProc: TProc;
begin
Uri := TUri.Create(Options.EndUrl);
Port := Uri.Port;
BaseUrl := Format('http://127.0.0.1:%d%s', [Port, Uri.AbsolutePath]);
FinishedProc :=
procedure
begin
TThread.Queue(nil, procedure
begin
FHttpServer.Active := False;
end);
end;
FHttpServer.Free;
FHttpServer := TIndySparkleHTTPServer.Create(nil);
FHttpServer.Dispatcher.AddModule(TCallbackServerModule.Create(BaseUrl, UrlCallback, FinishedProc));
FHttpServer.Active := false;
FHttpServer.Bindings.Clear;
FHttpServer.Bindings.Add.SetBinding('127.0.0.1', Port);
FHttpServer.Active := true;
end;
Have you created and run the test project I suggested? Just create an empty project that launches a browser at a generic address (Google URL, for example) and see if it opens.
Yes I created a sample application. Afterall the browser is started. I need to mention that there is a force login before using the browser, but at the end the browser is started and get back the desired page.
Please provide a call stack if you have one.
I started to get the callstack. I need more time to get this. Let's get back here later.
Thank you for the code. We will create a sample application and check how it is working in the production environment.
Update:
During the login process in the component at the line: FHttpServer.Active := true; we got the following exception: Socket Error # 10013. Access denied.
We did some research and let me summarize what we have.
So the original problem is that the OpenID login process not working, the browser is not launching in production environment. In development environment it is working.
We created some debug software to check where is the problem.
We always get a command timeout exception as I showed you earlier.
It is raised in the Sparkle.Http.Client.pas, in the THttpClient.Send function at the line Result := FEngine.Send(Request);
It is trying to get the metadata from the server. However it is not matter what is the url.
We tried to get the same url with NetHttpClient and it is worked.
We came to the conclusion that the request is a bit different if we create it with the Sparkle.Http.Client.
I just shared our results maybe you can give us some ideas what to check.
Can you please create a totally separated test project, a minimal one, that performs the same request to the same URL, using Sparkle HTTP Client and then NetHttpCLient?
Then, can you please confirm the behavior in the production environment, that the request works for NetHttpClient and failed for Sparkle with timeout?
Then, with all confirmed, can you please send the project to us?
In any case, it looks like your production machine is very, very restrictive and maybe you could talk to your administrator to investigate WHAT is being restricted. A simple request to a URL is basic behavior and if your production environment restricts that, I'm not sure what we can do about it.
We made a test project which is attached to this comment. It has two buttons which simple send a "get" request. The first button uses original Embarcadero component. The second button uses Sparkle component. Both of them are working fine in our enviroment. But only at the production customer's enviroment (Windows Server 2012 -Terminal server) the Sparkle method fails. We get back the following error message shown error1.png.
After removing try-except blocks in "Sparkle.WinHttp.Engine.pas" the error message is changing to: error2.png:
What is the difference which can cause the error message in the production enviroment? SparkleVsEmbarcadero.zip (2.2 MB)
It seems to us the solution is the proxy mode is set to "THttpProxyMode.Auto" in the Sparkle.WinHttp.Engine.pas:
"... ProxyMode := THttpProxyMode.Auto; ... "
How can we prepare the ProxyMode in our appilcation without editing the compoent source code itself.
In our case we only have "TSphinxLogin" component and we call the "Login" method.
How can we configure the "TSphinxLogin" component to use the proxy "auto" mode.
There is no such feature for now. But if the native HTTP client component works out of the box without you setting any proxy properties, it means that it's simply using the proxy settings configured in the Windows system, which is what "Auto" option does.