admin管理员组文章数量:1405510
Summary of this question: does someone know how to use a client certificate to authenticate over LDAP to Active Directory without using a password from a dotnet application? Or at least can someone shed some light on how this is supposed to work?
What we are trying to accomplish:
- From a dotnet application using LdapConnection create a LDAP connection to Active Directory outside of my current domain
- Using only a username and a certificate for authentication
- Verifying if the user is in the correct group We are using System.DirectoryServices.Protocols 6.0.2 on 8.0 on Windows 11
The documentation seems to contradict each other, because this document () seems to suggest a bind on an client certificate authenticated TLS connection is not allowed, in contrast the RFC seems to suggest its mandatory to send a bind: .
We hit a bug in the library initially which was picked up, but I'm not sure if it was the only one (see ).
Our attempts: Connecting with TLS on port 636 results in Bind failing on "Authentication method not supported".
string ldapPath = "dc";
int LDAPPort = 636;
var username = "user";
using LdapConnection ldapConnection = new LdapConnection(new LdapDirectoryIdentifier(ldapPath, LDAPPort));
ldapConnection.AuthType = AuthType.External;
LdapSessionOptions options = ldapConnection.SessionOptions;
options.SecureSocketLayer = true;
options.ProtocolVersion = 3;
ldapConnection.ClientCertificates.Add(cert);
ldapConnection.Bind();
// Perform further actions after this
Connecting without TLS on port 389 and starting TLS afterwards results in Bind failing on "Authentication method not supported".
string ldapPath = "dc";
int LDAPPort = 389;
var username = "user";
using LdapConnection ldapConnection = new LdapConnection(new LdapDirectoryIdentifier(ldapPath, LDAPPort));
ldapConnection.AuthType = AuthType.External;
ldapConnection.SessionOptions.ProtocolVersion = 3;
ldapConnection.ClientCertificates.Add(cert);
ldapConnection.SessionOptions.StartTransportLayerSecurity(null);
ldapConnection.Bind();
// Perform further actions after this
Connecting with TLS on port 636, skipping the bind and turning autobind off results in search failing with "In order to perform this operation a successful bind must be completed on the connection".
string ldapPath = "dc";
int LDAPPort = 636;
var username = "user";
using LdapConnection ldapConnection = new LdapConnection(new LdapDirectoryIdentifier(ldapPath, LDAPPort));
ldapConnection.AuthType = AuthType.External;
ldapConnection.SessionOptions.SecureSocketLayer = true;
ldapConnection.SessionOptions.ProtocolVersion = 3;
ldapConnection.AutoBind = false;
ldapConnection.ClientCertificates.Add(cert);
ldapConnection.SendRequest(...)
Summary of this question: does someone know how to use a client certificate to authenticate over LDAP to Active Directory without using a password from a dotnet application? Or at least can someone shed some light on how this is supposed to work?
What we are trying to accomplish:
- From a dotnet application using LdapConnection create a LDAP connection to Active Directory outside of my current domain
- Using only a username and a certificate for authentication
- Verifying if the user is in the correct group We are using System.DirectoryServices.Protocols 6.0.2 on 8.0 on Windows 11
The documentation seems to contradict each other, because this document (https://learn.microsoft/en-us/openspecs/windows_protocols/ms-adts/8e73932f-70cf-46d6-88b1-8d9f86235e81) seems to suggest a bind on an client certificate authenticated TLS connection is not allowed, in contrast the RFC seems to suggest its mandatory to send a bind: https://datatracker.ietf./doc/html/rfc2830#ref-AuthMeth.
We hit a bug in the library initially which was picked up, but I'm not sure if it was the only one (see https://github/dotnet/runtime/issues/113154#issuecomment-2705206987).
Our attempts: Connecting with TLS on port 636 results in Bind failing on "Authentication method not supported".
string ldapPath = "dc";
int LDAPPort = 636;
var username = "user";
using LdapConnection ldapConnection = new LdapConnection(new LdapDirectoryIdentifier(ldapPath, LDAPPort));
ldapConnection.AuthType = AuthType.External;
LdapSessionOptions options = ldapConnection.SessionOptions;
options.SecureSocketLayer = true;
options.ProtocolVersion = 3;
ldapConnection.ClientCertificates.Add(cert);
ldapConnection.Bind();
// Perform further actions after this
Connecting without TLS on port 389 and starting TLS afterwards results in Bind failing on "Authentication method not supported".
string ldapPath = "dc";
int LDAPPort = 389;
var username = "user";
using LdapConnection ldapConnection = new LdapConnection(new LdapDirectoryIdentifier(ldapPath, LDAPPort));
ldapConnection.AuthType = AuthType.External;
ldapConnection.SessionOptions.ProtocolVersion = 3;
ldapConnection.ClientCertificates.Add(cert);
ldapConnection.SessionOptions.StartTransportLayerSecurity(null);
ldapConnection.Bind();
// Perform further actions after this
Connecting with TLS on port 636, skipping the bind and turning autobind off results in search failing with "In order to perform this operation a successful bind must be completed on the connection".
string ldapPath = "dc";
int LDAPPort = 636;
var username = "user";
using LdapConnection ldapConnection = new LdapConnection(new LdapDirectoryIdentifier(ldapPath, LDAPPort));
ldapConnection.AuthType = AuthType.External;
ldapConnection.SessionOptions.SecureSocketLayer = true;
ldapConnection.SessionOptions.ProtocolVersion = 3;
ldapConnection.AutoBind = false;
ldapConnection.ClientCertificates.Add(cert);
ldapConnection.SendRequest(...)
Share
Improve this question
asked Mar 7 at 15:00
David van LuijkDavid van Luijk
11 bronze badge
2
- That sounds like one of those odd AD-specific behaviors, a bit like its handling of GSSAPI sign/seal when used over TLS. Note though that both pages talk about a SASL bind using the 'EXTERNAL' SASL mechanism – not about a credential-less 'Simple' bind like you're doing. (Although on that note, I wonder why you don't want to use Kerberos, i.e. SASL 'GSSAPI' or 'GSS-SPNEGO' bind?) – grawity_u1686 Commented Mar 8 at 14:18
- @grawity_u1686 We tried to put the AuthType to Kerberos/Negotiate but we couldn't get that to work. We are not bound to the AuthType External, we thought this was the appropriate value given the documentation. Maybe it's due to the fact where are trying to connect from outside the domain? If this is "Simple" bind, can we get SASL bind to work using LdapConnection? – David van Luijk Commented Mar 10 at 15:45
1 Answer
Reset to default 0For anyone stumbling across this same issue: the option "ReferralChasing" needed to be set to "None" after which the beneath code worked.
using System.DirectoryServices.Protocols;
using System.Net;
using System.Security.Cryptography.X509Certificates;
namespace AuthTest;
public class SystemLdap
{
public static void Run(X509Certificate2 smartCardCert)
{
Console.WriteLine($"Running SystemLdap...{smartCardCert.Subject}");
string ldapPath = "dc";
int LDAPPort = 636;
using LdapConnection ldapConnection = new LdapConnection(new LdapDirectoryIdentifier(ldapPath, LDAPPort));
ldapConnection.AuthType = AuthType.External;
ldapConnection.SessionOptions.ReferralChasing = ReferralChasingOptions.None;
ldapConnection.SessionOptions.SecureSocketLayer = true;
ldapConnection.SessionOptions.ProtocolVersion = 3;
ldapConnection.ClientCertificates.Add(smartCardCert);
try
{
var username = "user";
// Perform a search
var searchRequest = new SearchRequest(
$"DC=dc,DC=nl",
$"(&(objectClass=user)(|(cn={username})(sAMAccountName={username})))",
SearchScope.Subtree
);
var response = (SearchResponse)ldapConnection.SendRequest(searchRequest);
foreach (SearchResultEntry entry in response.Entries)
{
Console.WriteLine($"User found: {entry.DistinguishedName}");
}
}
catch (Exception ex)
{
Console.WriteLine($"LDAP Authentication failed: {ex}");
}
}
}
本文标签: netDotNet LdapConnection with authentication method external and client certificateStack Overflow
版权声明:本文标题:.net - DotNet LdapConnection with authentication method external and client certificate - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744921936a2632347.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论