diff --git a/docs/keycloak.md b/docs/keycloak.md
index 29fcf71f3..1b691782e 100644
--- a/docs/keycloak.md
+++ b/docs/keycloak.md
@@ -15,6 +15,19 @@ services.AddAuthentication(options => /* Auth configuration */)
});
```
+### Production with Public Access Type
+
+```csharp
+services.AddAuthentication(options => /* Auth configuration */)
+ .AddKeycloak(options =>
+ {
+ options.AccessType = KeycloakAuthenticationAccessType.Public;
+ options.ClientId = "my-client-id";
+ options.Domain = "mydomain.local";
+ options.Realm = "myrealm";
+ });
+```
+
### Local Development with Docker
```csharp
@@ -40,4 +53,6 @@ Only one of either `BaseAddress` or `Domain` is required to be set. If both are
## Optional Settings
-_None._
+| Property Name | Property Type | Description | Default Value |
+| :------------ | :--------------------------------- | :--------------------------------------- | :---------------------------------------------- |
+| `AccessType` | `KeycloakAuthenticationAccessType` | The Keycloak client's access token type. | `KeycloakAuthenticationAccessType.Confidential` |
diff --git a/src/AspNet.Security.OAuth.Keycloak/KeycloakAuthenticationAccessType.cs b/src/AspNet.Security.OAuth.Keycloak/KeycloakAuthenticationAccessType.cs
new file mode 100644
index 000000000..4b0873ae9
--- /dev/null
+++ b/src/AspNet.Security.OAuth.Keycloak/KeycloakAuthenticationAccessType.cs
@@ -0,0 +1,13 @@
+// Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+// See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
+// for more information concerning the license and the contributors participating to this project.
+
+namespace AspNet.Security.OAuth.Keycloak
+{
+ public enum KeycloakAuthenticationAccessType
+ {
+ Confidential,
+ Public,
+ BearerOnly,
+ }
+}
diff --git a/src/AspNet.Security.OAuth.Keycloak/KeycloakAuthenticationOptions.cs b/src/AspNet.Security.OAuth.Keycloak/KeycloakAuthenticationOptions.cs
index 1b39e646b..89880b1b8 100644
--- a/src/AspNet.Security.OAuth.Keycloak/KeycloakAuthenticationOptions.cs
+++ b/src/AspNet.Security.OAuth.Keycloak/KeycloakAuthenticationOptions.cs
@@ -37,6 +37,11 @@ public KeycloakAuthenticationOptions()
ClaimActions.MapJsonKey(ClaimTypes.Role, "roles");
}
+ ///
+ /// Gets or sets the value for the Keycloak client's access type.
+ ///
+ public KeycloakAuthenticationAccessType AccessType { get; set; }
+
///
/// Gets or sets the base address of the Keycloak server.
///
@@ -51,5 +56,39 @@ public KeycloakAuthenticationOptions()
/// Gets or sets the Keycloak realm to use for authentication.
///
public string? Realm { get; set; }
+
+ ///
+ public override void Validate()
+ {
+ try
+ {
+ // HACK We want all of the base validation except for ClientSecret,
+ // so rather than re-implement it all, catch the exception thrown
+ // for that being null and only throw if we aren't using public access type.
+ // This does mean that three checks have to be re-implemented
+ // because the won't be validated if the ClientSecret validation fails.
+ base.Validate();
+ }
+ catch (ArgumentException ex) when (ex.ParamName == nameof(ClientSecret) && AccessType == KeycloakAuthenticationAccessType.Public)
+ {
+ // No client secret is required for a public key.
+ // See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers/issues/610.
+ }
+
+ if (string.IsNullOrEmpty(AuthorizationEndpoint))
+ {
+ throw new ArgumentException($"The '{nameof(AuthorizationEndpoint)}' option must be provided.", nameof(AuthorizationEndpoint));
+ }
+
+ if (string.IsNullOrEmpty(TokenEndpoint))
+ {
+ throw new ArgumentException($"The '{nameof(TokenEndpoint)}' option must be provided.", nameof(TokenEndpoint));
+ }
+
+ if (!CallbackPath.HasValue)
+ {
+ throw new ArgumentException($"The '{nameof(CallbackPath)}' option must be provided.", nameof(CallbackPath));
+ }
+ }
}
}
diff --git a/test/AspNet.Security.OAuth.Providers.Tests/Keycloak/KeycloakAuthenticationOptionsTests.cs b/test/AspNet.Security.OAuth.Providers.Tests/Keycloak/KeycloakAuthenticationOptionsTests.cs
new file mode 100644
index 000000000..507316924
--- /dev/null
+++ b/test/AspNet.Security.OAuth.Providers.Tests/Keycloak/KeycloakAuthenticationOptionsTests.cs
@@ -0,0 +1,107 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ * See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
+ * for more information concerning the license and the contributors participating to this project.
+ */
+
+using System;
+using System.Collections.Generic;
+using Xunit;
+
+namespace AspNet.Security.OAuth.Keycloak
+{
+ public static class KeycloakAuthenticationOptionsTests
+ {
+ public static IEnumerable