Description
Description
We're using NegotiateStream to authenticate clients on our server application. This works on Windows clients, but we would like to get it working on Linux clients as well.
Reproduction Steps
The server application always runs on a Windows Server OS and uses .NET Framework 4.6.2.
In this case, the Windows Server is part of a local domain (I didn't test it on a server that is not in a domain).
The client application makes use of a library dll that gets build in both .NET Framework 4.6.2 and .NET Standard 2.0.
Clients using the .NET Framework 4.6.2 library dll on Windows works.
Clients using the .NET Standard 2.0 library on .NET 8 applications on Windows works.
Clients using the .NET Standard 2.0 library on .NET 8 applications on Linux does not work.
Linux clients are running:
- Ubuntu Server 22.04 LTS
- dotnet-runtime-8.0
- aspnetcore-runtime-8.0
Server implementation:
_authStream = new SSPIAuthStream();
_negotiateStream = new NegotiateStream(_authStream);
NegotiateStream stream = _negotiateStream;
stream.AuthenticateAsServer(
(NetworkCredential)CredentialCache.DefaultCredentials,
ProtectionLevel.None, // min. protectionlevel required
TokenImpersonationLevel.Identification // min. impersonationlevel required
);
if (stream.RemoteIdentity != null)
name = stream.RemoteIdentity.Name;
authenticated = stream.IsAuthenticated;
Client implementation:
_authStream = new SSPIAuthStream();
_negotiateStream = new NegotiateStream(_authStream);
// determine client credentials
NetworkCredential credentials = null;
if (String.IsNullOrEmpty(userName))
credentials = (NetworkCredential)CredentialCache.DefaultCredentials;
else
credentials = new NetworkCredential(userName, password, domainName);
// launch client authentication process asynchronously.
_arAuthenticateAsClient = _negotiateStream.BeginAuthenticateAsClient(
credentials,
String.Empty, // target name
ProtectionLevel.None, // we don't need sign or encrypt since we'll ditch the stream once authenticated
TokenImpersonationLevel.Identification, // we only need to identify ourselves
new AsyncCallback(callback_onAuthenticateComplete), // callback method when done
null
);
Expected behavior
I would expect when specifying a username/password that the authentication step works on Linux as well, just like on Windows.
Actual behavior
When a client running on Linux connects, the following error gets thrown on the server:
System.Security.Authentication.AuthenticationException: Authentication failed on the remote side (the stream might still be available for additional authentication attempts). ---> System.ComponentModel.Win32Exception: Unknown error (0xffffffff)
--- End of inner exception stack trace ---
at System.Net.Security.NegoState.ProcessReceivedBlob(Byte[] message, LazyAsyncResult lazyResult)
at System.Net.Security.NegoState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.NegotiateStream.AuthenticateAsServer(NetworkCredential credential, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel requiredImpersonationLevel)
Regression?
No response
Known Workarounds
No response
Configuration
No response
Other information
No response