NikiforovAll / keycloak-authorization-services-dotnet

Authentication and Authorization with Keycloak and ASP.NET Core šŸ”
https://nikiforovall.github.io/keycloak-authorization-services-dotnet/
MIT License
480 stars 113 forks source link

Configure multiple clients in single Realm #135

Open grcontin opened 2 months ago

grcontin commented 2 months ago

I can have multiple clients within a Realm, and these clients may or may not have access to certain resources. Using Keycloak.AuthServices.Authentication, I noticed that it is not possible to configure more than one client for the same realm via configuration. As a result, I couldn't perform the necessary validations for my API resources.

Is there a way to configure Keycloak in .NET for multiple clients so that I can authorize access to specific resources through authentication with these multiple clients? Below are my configurations:

appsettings.json:

{
  "realm": "sample-realm",
  "auth-server-url": "http://localhost:8080/",
  "ssl-required": "none",
  "resource": "backend-client",
  "verify-token-audience": true,
  "credentials": {
    "secret": "TXheAgfJirMzDb2Mnr06mKhTMUtu5ulm"
  },
  "confidential-port": 0,
  "policy-enforcer": {
    "credentials": {}
  }
}

Configurations for Keycloak.AuthServices.Authentication and Keycloak.AuthServices.Authorization:

public static IServiceCollection AddKeycloakAuthN(this IServiceCollection services, IConfiguration configuration)
{
    services.AddKeycloakWebApiAuthentication(configuration, options =>
    {
        options.IncludeErrorDetails = true;
    });

    return services;
}

public static IServiceCollection AddKeycloakAuthZ(this IServiceCollection services, IConfiguration configuration)
{
    services.AddAuthorization(configurations =>
    {
        configurations.FallbackPolicy = BuildDefaultPolicy();

        // client X has access to this resource
        configurations.AddPolicy(AuthorizationPolicyConstants.Sample, policyBuilder =>
        {
            policyBuilder.RequireRealmRoles(AuthorizationRoleConstants.User);
            policyBuilder.RequireProtectedResource(AuthorizationResourceConstants.Sample.Item1, AuthorizationResourceConstants.Sample.Item2);
        });

        // client X does NOT have access to this resource
        configurations.AddPolicy(AuthorizationPolicyConstants.SampleTwo, policyBuilder =>
        {
            policyBuilder.RequireRealmRoles(AuthorizationRoleConstants.Administrator, AuthorizationRoleConstants.User);
            policyBuilder.RequireProtectedResource(AuthorizationResourceConstants.SampleTwo.Item1, AuthorizationResourceConstants.SampleTwo.Item2);
        });

    })
    .AddKeycloakAuthorization(configuration)
    .AddAuthorizationServer(configuration);

    return services;
}

private static AuthorizationPolicy BuildDefaultPolicy() 
    => new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .Build();