Moblile "rejected credentials"

Hi!

Version: 6.12.1
Licensing: Starter
Self-managed hosting

I am experiencing an issue with logging into the Rocket.Chat mobile app. My setup involves IIS on Windows Server acting as a reverse proxy to Rocket.Chat, which is running in Docker on a Linux instance hosted on Hyper-V.

My Setup:

  • Windows Server with IIS and URL Rewrite enabled
  • Hyper-V hosting a Linux instance running Docker with Rocket.Chat on port 3000
  • IIS is configured to forward connections from https://example.com to Rocket.Chat.
  • SLL is generated by Let’s encrypt and added to IIS binding

The web client works perfectly fine, and WebSocket connections are functioning correctly. However, the Rocket.Chat mobile app throws an error saying “credentials rejected” when trying to log in. I have verified that the credentials are correct.

Here is my current web.config:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>	
				<rule name="RedirectHTTPtoHTTPS" enabled="true" stopProcessing="true">
                    <match url=".*" />
                    <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                        <add input="{HTTPS}" pattern="^OFF$" />
                        <add input="{HTTP_HOST}" pattern="localhost" negate="true" />
                    </conditions>
                    <action type="Redirect" url="https://{HTTP_HOST}/{R:0}" appendQueryString="true" redirectType="Permanent" />
                </rule>
                <rule name="ReverseProxyToRocketChat" stopProcessing="true">
					<match url=".*" />
					<action type="Rewrite" url="http://10.10.0.3:3000/{R:0}" />
				</rule>				
            </rules>
        </rewrite>
		<handlers>
          <clear />
          <add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
        </handlers>
    </system.webServer>
</configuration>

What I’ve Tried:

  • WebSockets are working fine, both in the browser client and in tests.
  • I’ve confirmed that IIS forwards requests correctly to Rocket.Chat via the reverse proxy.
  • Verified the mobile app credentials work fine when logging in through the web client.

My Questions:

  • Has anyone else encountered the “credentials rejected” issue with the Rocket.Chat mobile app when using IIS as a reverse proxy?
  • Could there be something in the web.config or IIS setup that is interfering with how the mobile app authenticates?
  • Are there additional IIS configurations or Rocket.Chat settings that need to be checked for mobile login?

Hmmm. Normally webserver/websockets.

Windows/IIS is not the friendliest of systems for servers :slight_smile:

I can only suggest you check through the IIS sections at the end here first.

https://docs.rocket.chat/docs/windows-server#mobile-support

There are some notes on logging.

However, what about authentication systems? Are you using LDAP or something else?

This indicates your error is caused by a failed login?

Thank You for response! I have seen this article before but anything written there I already have applied to my server.

Yes, this is the prompt I’m getting that you have pointed out in the git repo. I have also checked my rocket chat logs and I can confirm that login http request is getting there.

{"level":20,"time":"2024-09-30T17:25:26.169Z","pid":1,"hostname":"088dd5eb51ff","name":"Callbacks","msg":"Executing callback with id 2fa for hook onValidateLogin"} 
{"level":20,"time":"2024-09-30T17:25:26.175Z","pid":1,"hostname":"088dd5eb51ff","name":"Callbacks","msg":"Executing callback with id PueX99vGBzYTntYnq for hook afterValidateLogin"} 
{"level":35,"time":"2024-09-30T17:25:26.195Z","pid":1,"hostname":"088dd5eb51ff","name":"API","method":"POST","url":"/api/v1/login","userId":"Ku3eJWC6ew398KwPf","userAgent":"RC Mobile; android 14; v4.52.0 (65591)","length":"45","host":"10.10.0.3:3000","remoteIP":"109.243.65.224:10943","responseTime":102} 

I wish there is some way to log what is happening on the application side… This prompt “Your credentials were rejected!” happens almost immediately, so I don’t this there is some kind of time out. App is getting response back, but it doesn’t like it for some reason.

I managed to figure it out. I downloaded the mobile app’s source code and debugged the connection. It turned out that the server was terminating the connection right after it was established, which seemed very strange to me. So, I tried forcing a local connection to the server without SSL, and there it was—it connected!

At this stage, I knew the issue was related to IIS, the rewrite rule, or the certificate, but SSL Labs ruled out a certificate issue. So, I focused on something I had never checked: WebSockets. In Chrome, I intercepted the WebSocket URL and tried to call it using Postman. It turned out that the magic green dot I saw in Chrome, indicating that the WebSocket protocol was correctly upgraded, was misleading. Although the protocol was indeed being upgraded, no WS frames were being transmitted afterward. I tried the same request in Postman, bypassing IIS, and connecting directly to the local server, and I successfully established a connection.

At that point, I knew that the issue was with IIS rewrite and WebSockets not being properly handled. After many trials and errors, I finally managed to construct a web.config file that works. Here it is:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>	
				<rule name="RedirectHTTPtoHTTPS" enabled="true" stopProcessing="true">
                    <match url=".*" />
                    <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                        <add input="{HTTPS}" pattern="^OFF$" />
                        <add input="{HTTP_HOST}" pattern="localhost" negate="true" />
                    </conditions>
                    <action type="Redirect" url="https://{HTTP_HOST}/{R:0}" appendQueryString="true" redirectType="Permanent" />
                </rule>
                <rule name="ReverseProxyToRocketChat" stopProcessing="true">
					<match url=".*" />
					<action type="Rewrite" url="http://10.10.0.3:3000/{R:0}" /> 
					<!-- magical websocket requirement --> 
                    <serverVariables> 
						<set name="HTTP_SEC_WEBSOCKET_EXTENSIONS" value="" />
					</serverVariables>
				</rule>		
            </rules>
			<outboundRules>
				 <rule name="Force Download for CS Files">
					<match serverVariable="RESPONSE_Content-Disposition" pattern=".*" />
					<conditions>
					   <add input="{REQUEST_FILENAME}" pattern="\.cs$" />
					</conditions>
					<action type="Rewrite" value="attachment; filename={URL_FILENAME}" />
				 </rule>
			  </outboundRules>
        </rewrite>
		<handlers>
          <clear />
          <add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
        </handlers>
        <security>
            <requestFiltering>
                <fileExtensions>
                    <remove fileExtension=".cs" />
                </fileExtensions>
            </requestFiltering>
        </security>
		 <staticContent>
		  <mimeMap fileExtension=".cs" mimeType="application/octet-stream" />
	   </staticContent>
    </system.webServer>
</configuration>

You need to add “HTTP_SEC_WEBSOCKET_EXTENSIONS” to the allowed server variables for this to work. I don’t know if it is needed, but I also have added to allowed server variables “HTTP_UPGRADE”.

Leaving this here for future reference, in case it saves someone some time.

1 Like

Well done, and thanks for posting your solution…

It’s far easier with Linux and say Nginx :wink: