Skip to content

Linux: RBAC claims resolution fails if user has group with brackets in name #58062

Open
@teh13th

Description

@teh13th

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

Real-world AD deployments can have groups with brackets in name (example: Some resource access (rw)). In this case, when nested claims resolution is enabled, Linux clients will get LdapException: The search filter is invalid.

Expected Behavior

In case, when nested claims resolution is enabled, expected that each user's group will parse correctly, even if it contains brackets.

Steps To Reproduce

  1. Set up any AD server (contoso.com in the example).
  2. Add AD group with brackets in name (Some resource access (rw)).
  3. Add user to that group.
  4. Create a simple API project, set up RBAC claims resolution:
services.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate(options =>
{
    if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
    {
        return;
    }
    
    options.EnableLdap(settings =>
    {
        settings.Domain = "contoso.com";
        settings.MachineAccountName = "someuser";
        settings.MachineAccountPassword = "somepassword";
    });
});

services.AddAuthorization();
[ApiController]
[Route("api/[controller]")]
[Authorize(Roles = "GroupA")]
public class SomeController : Controller
{
    [HttpGet]
    [Route("someMethod")]
    public async Task<ActionResult<int>> SomeMethod()
    {
        return 1;
    }
 }

Exceptions (if any)

System.DirectoryServices.Protocols.LdapException: The search filter is invalid. 
   at System.DirectoryServices.Protocols.LdapConnection.SendRequest(DirectoryRequest request, TimeSpan requestTimeout) 
   at System.DirectoryServices.Protocols.LdapConnection.SendRequest(DirectoryRequest request) 
   at Microsoft.AspNetCore.Authentication.Negotiate.NegotiateEvents.RetrieveLdapClaims(LdapContext context) 
   at Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler.HandleAuthenticateAsync() 
   at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync() 
   at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme) 
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) 
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context) 

.NET Version

8.0.204

Anything else?

The problem is that class LdapAdapter does not escape group name when place it in query to LDAP here:

var filter = $"(&(objectClass=group)(sAMAccountName={groupCN}))"; // This is using ldap search query language, it is looking on the server for someUser

It seems that you can use one of existing tool here:

  1. System.DirectoryServices.ActiveDirectory.Utils.GetEscapedFilterValue()
  2. System.DirectoryServices.AccountManagement.ADUtils.EscapeRFC2254SpecialChars().

Also, you can use mentioned tools to get the common name (CN) from the distinguished name (DN) here:

var groupCN = DistinguishedNameSeparator().Split(groupDN)[0].Substring("CN=".Length);

Method: System.DirectoryServices.ActiveDirectory.Utils.GetDNComponents().

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-authIncludes: Authn, Authz, OAuth, OIDC, BearerbugThis issue describes a behavior which is not expected - a bug.untriaged

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions