DigiCypress.XAF.SingleSignOn.Keycloak.Blazor
24.1.5.1
dotnet add package DigiCypress.XAF.SingleSignOn.Keycloak.Blazor --version 24.1.5.1
NuGet\Install-Package DigiCypress.XAF.SingleSignOn.Keycloak.Blazor -Version 24.1.5.1
<PackageReference Include="DigiCypress.XAF.SingleSignOn.Keycloak.Blazor" Version="24.1.5.1" />
paket add DigiCypress.XAF.SingleSignOn.Keycloak.Blazor --version 24.1.5.1
#r "nuget: DigiCypress.XAF.SingleSignOn.Keycloak.Blazor, 24.1.5.1"
// Install DigiCypress.XAF.SingleSignOn.Keycloak.Blazor as a Cake Addin #addin nuget:?package=DigiCypress.XAF.SingleSignOn.Keycloak.Blazor&version=24.1.5.1 // Install DigiCypress.XAF.SingleSignOn.Keycloak.Blazor as a Cake Tool #tool nuget:?package=DigiCypress.XAF.SingleSignOn.Keycloak.Blazor&version=24.1.5.1
DigiCypress.XAF.SingleSignOn.Keycloak.Blazor
SingleSignOn.Keycloak.Blazor module for Devexpress XAF
Blazor Server
-- 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 in BlazorApplication
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);
}
-- appsettings.json
"Keycloak": {
"Authority": "http://localhost:8080/realms/my-realm",
"ClientId": "my-client",
"ClientSecret": "rr7Fzu0KgVoutojhOUPd3qQWvTG7iTXE"
}
-- 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
-- appsettings.json
"Keycloak": {
"Authority": "http://localhost:8080/realms/my-realm",
"ClientId": "my-client",
"ClientSecret": "rr7Fzu0KgVoutojhOUPd3qQWvTG7iTXE"
}
-- 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("Authenticate")]
//[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 IActionResult Authenticate(
// [FromBody]
// [SwaggerRequestBody(@"For example: <br /> { ""userName"": ""Admin"", ""password"": """" }")]
// AuthenticationStandardLogonParameters logonParameters
//) {
// try {
// return Ok(tokenProvider.Authenticate(logonParameters));
// }
// catch(AuthenticationException ex) {
// return Unauthorized(ex.GetJson());
// }
//}
[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;
});
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net8.0
- DevExpress.ExpressApp (>= 24.1.5)
- DevExpress.ExpressApp.Blazor (>= 24.1.5)
- DevExpress.ExpressApp.CodeAnalysis (>= 24.1.5)
- DevExpress.ExpressApp.Xpo (>= 24.1.5)
- DevExpress.Persistent.Base (>= 24.1.5)
- DevExpress.Persistent.BaseImpl.Xpo (>= 24.1.5)
- DigiCypress.XAF.SingleSignOn.Keycloak (>= 24.1.5.1)
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 8.0.11)
- Microsoft.AspNetCore.Authentication.OpenIdConnect (>= 8.0.11)
- Microsoft.IdentityModel.Protocols.OpenIdConnect (>= 8.3.0)
- System.IdentityModel.Tokens.Jwt (>= 8.3.0)
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.1.5.1 | 84 | 12/9/2024 |