MudraX.XAF.Keycloak.Blazor 24.2.8.2

dotnet add package MudraX.XAF.Keycloak.Blazor --version 24.2.8.2
                    
NuGet\Install-Package MudraX.XAF.Keycloak.Blazor -Version 24.2.8.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="MudraX.XAF.Keycloak.Blazor" Version="24.2.8.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="MudraX.XAF.Keycloak.Blazor" Version="24.2.8.2" />
                    
Directory.Packages.props
<PackageReference Include="MudraX.XAF.Keycloak.Blazor" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add MudraX.XAF.Keycloak.Blazor --version 24.2.8.2
                    
#r "nuget: MudraX.XAF.Keycloak.Blazor, 24.2.8.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package MudraX.XAF.Keycloak.Blazor@24.2.8.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=MudraX.XAF.Keycloak.Blazor&version=24.2.8.2
                    
Install as a Cake Addin
#tool nuget:?package=MudraX.XAF.Keycloak.Blazor&version=24.2.8.2
                    
Install as a Cake Tool

MudraX.XAF.Keycloak.Blazor

SSO.Keycloak.Blazor module for Devexpress XAF

  • make sure startup uri launchSetting.json is equate Keycloak Server

  • Upgrade the package System.IdentityModel.Tokens.Jwt referenced in the Module and Blazor projects from the original 6.* to 8.* https://github.com/openiddict/openiddict-core/issues/2033

  • Add reference to Keycloak.Blazor

  • Add Microsoft.AspNetCore.Authentication.OpenIdConnect Nuget

      <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.*" />
      <PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="8.*" />
    

Blazor.Server

  • Add in BlazorApplication.cs

    protected override List<Controller> CreateLogonWindowControllers()
    {
        var result = base.CreateLogonWindowControllers();
        result.Add(new AdditionalLogonActionsCustomizationController());
        return result;
    }
    
    public override void LogOff()
    {
        base.LogOff();
        var navigationManager = this.ServiceProvider.GetRequiredService<NavigationManager>();
        navigationManager.NavigateTo("Account/Logout", forceLoad: true);
    }
    
  • Set launchSettings.json with same Keycloak client settings. ex: https://localhost:7282

  • Add in appsettings.json

    "Keycloak": {
      "Authority": "http://localhost:8080/realms/{realm name}",
      "ClientId": "{client name}",
      "ClientSecret": "{client secret}"
    }
    
  • Set Startup.cs

    • Add the following in builder.Security section
    ....
    .AddPasswordAuthentication(options => {
        options.IsSupportChangePassword = true;
    })
    .AddAuthenticationProvider<KeycloakAuthenticationProvider>(); 
    
    • Add the following in authentication section
    authentication.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, "Keycloak", options =>
    {
        options.Authority = Configuration["Keycloak:Authority"];
        options.ClientId = Configuration["Keycloak:ClientId"];
        options.ClientSecret = Configuration["Keycloak:ClientSecret"];
        options.SaveTokens = true;
        options.RequireHttpsMetadata = false;
    
        //https://stackoverflow.com/questions/74052650
        options.SignOutScheme = OpenIdConnectDefaults.AuthenticationScheme;
    
        //https://stackoverflow.com/questions/74327614
        options.Scope.Add("openid");
    
        options.Events.OnRedirectToIdentityProvider = async context =>
        {
            context.ProtocolMessage.RedirectUri = context.ProtocolMessage.RedirectUri.Replace("http:", "https:");
            await Task.FromResult(0);
        };
    });
    
    • Add the following in app.UseEndpoints section
    ....
    endpoints.MapGet("/Account/Logout", async context =>
    {
        if (context.User.Identity.AuthenticationType == "AuthenticationTypes.Federation")
            await context.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
    
        await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme, new AuthenticationProperties
        {
            RedirectUri = "/"
        });
    }).RequireAuthorization();
    
    endpoints.MapControllers();
    

Web API

  • Set launchSettings.json with same Keycloak client settings. ex: https://localhost:7282

  • Add in appsettings.json

    "Keycloak": {
      "Authority": "http://localhost:8080/realms/{realm name}",
      "ClientId": "{client name}",
      "ClientSecret": "{client secret}"
    }
    
  • Modify API\AuthenticationController.cs

    public class AuthenticationController : ControllerBase
    {
        readonly IAuthenticationTokenProvider tokenProvider;
        readonly KeycloakAuthorizationService keycloakAuthorizationService;
        public AuthenticationController(IAuthenticationTokenProvider tokenProvider, KeycloakAuthorizationService keycloakAuthService = null)
        {
            this.tokenProvider = tokenProvider;
            this.keycloakAuthorizationService = keycloakAuthService;
        }
    
        [HttpPost("KeycloakAuthenticate")]
        [SwaggerOperation("Checks if the user with the specified logon parameters exists in the database. If it does, authenticates this user.", "Refer to the following help topic for more information on authentication methods in the XAF Security System: <a href='https://docs.devexpress.com/eXpressAppFramework/119064/data-security-and-safety/security-system/authentication'>Authentication</a>.")]
        public async Task<IActionResult> KeycloakAuthenticate(
            [FromBody]
            [SwaggerRequestBody(@"For example: <br /> { ""userName"": ""Admin"", ""password"": """" }")]
            AuthenticationStandardLogonParameters logonParameters
        )
        {
            try
            {
                var token = await keycloakAuthorizationService.LoginAsync(logonParameters.UserName, logonParameters.Password);
                return Ok(token.AccessToken);
            }
            catch (AuthenticationException ex)
            {
                return Unauthorized(ex.GetJson());
            }
        }
    }
    
  • Set Startup.cs

    • Add the following in builder.Security section

      ....
      .AddPasswordAuthentication(options => {
          options.IsSupportChangePassword = true;
      })
      .AddAuthenticationProvider<KeycloakAuthenticationProvider>(); 
      
    • Replace services.AddAuthentication section

      services.AddAuthentication(options =>
      {
          options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
          options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
      })
          .AddJwtBearer(options =>
          {
              options.TokenValidationParameters = new TokenValidationParameters
              {
                  ValidateIssuer = true,
                  ValidIssuer = Configuration["Keycloak:Authority"],
      
                  ValidateAudience = true,
                  ValidAudience = "account",
      
                  ValidateIssuerSigningKey = true,
                  ValidateLifetime = false,
      
                  IssuerSigningKeyResolver = (token, securityToken, kid, parameters) =>
                  {
                      var client = new HttpClient();
                      var keyUri = $"{parameters.ValidIssuer}/protocol/openid-connect/certs";
                      var response = client.GetAsync(keyUri).Result;
                      var keys = new JsonWebKeySet(response.Content.ReadAsStringAsync().Result);
      
                      return keys.GetSigningKeys();
                  }
              };
      
              options.RequireHttpsMetadata = false; // Only in develop environment
              options.SaveToken = false;
          });
      
    • Add in end of ConfigureServices

          services.AddHttpClient();
          services.AddScoped<KeycloakAuthorizationService>();
      
Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
24.2.8.2 153 9/10/2025
24.2.8.1 166 7/10/2025
24.2.7.2 248 5/13/2025
24.2.7.1 150 5/7/2025
24.2.5.1 157 5/6/2025