Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
3ff0476
Allow customization of aud claim with JWT Authentication
justin-tay Aug 14, 2023
75440ab
Fix compilation error on springboot (#24437)
Aboullos Oct 31, 2023
6f99291
Move some UserProfile and Validation classes into keycloak-server-spi
mposolda Oct 30, 2023
0bd2b34
Update per review
mposolda Oct 31, 2023
7b06838
Updated documentations to mention Resteasy reactive migration
rh-iatanaso Oct 27, 2023
aa75fef
Downgrade transient users to experimental
hmlnarik Oct 31, 2023
412c8bc
Bump rollup from 4.1.5 to 4.2.0 in /js (#24447)
dependabot[bot] Nov 1, 2023
17135a0
Bump @types/node from 20.8.9 to 20.8.10 in /js (#24446)
dependabot[bot] Nov 1, 2023
b0c22ce
Improve error handling for Fetch calls (#24460)
jonkoops Nov 1, 2023
e96d6b3
Correct the value of option --cache-stack (#24338)
k-tamura Nov 1, 2023
be65ba8
Make sure optional default attributes are removed when decorating the…
pedroigor Oct 31, 2023
222db65
Add 'Email Verified' checkbox if user profile is enabled (#24463)
jonkoops Nov 1, 2023
e173513
clean util * (#24174)
rokkiter Nov 1, 2023
70e8204
Updating release notes for Keycloak 23 with some 'core features' impr…
mposolda Nov 1, 2023
d7bb594
Escape $ sign when replacing clientId in the role mappers
rmartinc Oct 5, 2023
fe0a945
Remove UTF-8 encoding header from property files (#24471)
jonkoops Nov 1, 2023
9ef9c94
Minor changes to documentation
andymunro Nov 1, 2023
a6f6a52
fix: exceptions should be ignored in until the condition is met (#24478)
shawkins Nov 2, 2023
8867dd6
Force reporters of bugs to agree to test against the latest Keycloak …
jonkoops Nov 2, 2023
e05effe
Map Store Removal: Delete map profiles and scopes from model tests
martin-kanis Oct 24, 2023
563ae10
[issue-14134] test partial import user with id
antikalk Aug 21, 2023
c91e084
Fix Cypress tests for User Profile (#24502)
jonkoops Nov 2, 2023
bd80f20
Remove leftover namespaces from translation keys (#24486)
jonkoops Nov 2, 2023
a3a2f78
Properly handle array query arguments in Admin Client (#24483)
jonkoops Nov 2, 2023
7d7880b
Enable `html` reporter for Playwright on CI (#24488)
jonkoops Nov 2, 2023
1596d87
Remove hidden inputs from update password form (#24489)
jonkoops Nov 2, 2023
593c14c
Data too long for column 'DETAILS_JSON'
vramik Oct 23, 2023
b8fd46a
Added KeyStore SPI
tsaarni Sep 28, 2023
2417350
Use CryptoIntegration for Keystore SPI
tsaarni Oct 9, 2023
4241521
LDAP SASL EXTERNAL with KeyStore SPI
tsaarni Sep 28, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions .github/ISSUE_TEMPLATE/bug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ body:
- type: checkboxes
attributes:
label: Before reporting an issue
description: Please search to see if the issue is already reported, and try to reproduce the issue on the latest release.
description: |
Please search to see if the issue is already reported, and try to reproduce the issue on the latest release.

Any reported issues must be reproducible in the [latest](https://github.com/keycloak/keycloak/releases/latest) or [nightly](https://github.com/keycloak/keycloak/releases/nightly) version of Keycloak.

**⚠️ Failing to follow these guidelines may result in your issue being closed without action. ⚠️**
options:
- label: I have searched existing issues
required: true
- label: I have reproduced the issue with the [latest nightly release](https://github.com/keycloak/keycloak/releases/tag/nightly)
- label: I have read and understood the above terms for submitting issues, and I understand that my issue may be closed without action if I do not follow them.
required: true
- type: dropdown
id: area
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import org.keycloak.adapters.spi.SessionIdMapper;
import org.keycloak.adapters.spi.SessionIdMapperUpdater;

import java.util.*;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletContext;
Expand All @@ -32,6 +31,8 @@
import org.infinispan.persistence.remote.RemoteStore;
import org.jboss.logging.Logger;

import java.util.Set;

/**
*
* @author hmlnarik
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import org.keycloak.adapters.spi.SessionIdMapper;

import java.util.*;
import java.util.Queue;
import java.util.concurrent.*;
import org.infinispan.Cache;
import org.infinispan.client.hotrod.annotation.ClientCacheEntryCreated;
Expand Down
2 changes: 1 addition & 1 deletion common/src/main/java/org/keycloak/common/Profile.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public enum Feature {

DEVICE_FLOW("OAuth 2.0 Device Authorization Grant", Type.DEFAULT),

TRANSIENT_USERS("Transient users for brokering", Type.PREVIEW),
TRANSIENT_USERS("Transient users for brokering", Type.EXPERIMENTAL),
;

private final Type type;
Expand Down
18 changes: 11 additions & 7 deletions common/src/main/java/org/keycloak/common/util/DerUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,15 @@ public static PrivateKey decodePrivateKey(InputStream is)
dis.readFully(keyBytes);
dis.close();

PKCS8EncodedKeySpec spec =
new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf =CryptoIntegration.getProvider().getKeyFactory("RSA");
return kf.generatePrivate(spec);
return decodePrivateKey(keyBytes);
}

public static PublicKey decodePublicKey(byte[] der) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException {
return decodePublicKey(der, "RSA");
try {
return decodePublicKey(der, "RSA");
} catch (InvalidKeySpecException e) {
return decodePublicKey(der, "EC");
}
}

public static PublicKey decodePublicKey(byte[] der, String type) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException {
Expand All @@ -79,7 +80,10 @@ public static X509Certificate decodeCertificate(InputStream is) throws Exception
public static PrivateKey decodePrivateKey(byte[] der) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException {
PKCS8EncodedKeySpec spec =
new PKCS8EncodedKeySpec(der);
KeyFactory kf = CryptoIntegration.getProvider().getKeyFactory("RSA");
return kf.generatePrivate(spec);
try {
return CryptoIntegration.getProvider().getKeyFactory("RSA").generatePrivate(spec);
} catch (InvalidKeySpecException e) {
return CryptoIntegration.getProvider().getKeyFactory("EC").generatePrivate(spec);
}
}
}
21 changes: 21 additions & 0 deletions common/src/main/java/org/keycloak/common/util/PemUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import org.keycloak.common.crypto.CryptoIntegration;

Expand Down Expand Up @@ -53,6 +57,23 @@ public static X509Certificate decodeCertificate(String cert) {
return CryptoIntegration.getProvider().getPemUtils().decodeCertificate(cert);
}

/**
* Decode one or more X509 Certificates from a PEM string (certificate bundle)
*
* @param certs
* @return
* @throws Exception
*/
public static X509Certificate[] decodeCertificates(String certs) {
String[] pemBlocks = certs.split(END_CERT);

List<X509Certificate> x509Certificates = Arrays.stream(pemBlocks)
.filter(pemBlock -> pemBlock != null && !pemBlock.trim().isEmpty())
.map(pemBlock -> PemUtils.decodeCertificate(pemBlock + END_CERT))
.collect(Collectors.toList());

return x509Certificates.toArray(new X509Certificate[x509Certificates.size()]);
}

/**
* Decode a Public Key from a PEM string
Expand Down
2 changes: 1 addition & 1 deletion common/src/test/java/org/keycloak/common/ProfileTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public void checkDefaults() {
disabledFeatures.add(Profile.Feature.KERBEROS);
}
assertEquals(profile.getDisabledFeatures(), disabledFeatures);
assertEquals(profile.getPreviewFeatures(), Profile.Feature.ACCOUNT3, Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ, Profile.Feature.RECOVERY_CODES, Profile.Feature.SCRIPTS, Profile.Feature.TOKEN_EXCHANGE, Profile.Feature.DECLARATIVE_USER_PROFILE, Profile.Feature.CLIENT_SECRET_ROTATION, Profile.Feature.UPDATE_EMAIL, Profile.Feature.DPOP, Profile.Feature.TRANSIENT_USERS);
assertEquals(profile.getPreviewFeatures(), Profile.Feature.ACCOUNT3, Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ, Profile.Feature.RECOVERY_CODES, Profile.Feature.SCRIPTS, Profile.Feature.TOKEN_EXCHANGE, Profile.Feature.DECLARATIVE_USER_PROFILE, Profile.Feature.CLIENT_SECRET_ROTATION, Profile.Feature.UPDATE_EMAIL, Profile.Feature.DPOP);
}

@Test
Expand Down
5 changes: 4 additions & 1 deletion core/src/main/java/org/keycloak/TokenVerifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@
import javax.crypto.SecretKey;

import java.security.PublicKey;
import java.util.*;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

Expand Down
40 changes: 38 additions & 2 deletions docs/documentation/release_notes/topics/23_0_0.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,43 @@ https://github.com/tnorimat[Takashi Norimatsu] and https://github.com/dteleguin[
Keycloak has preview support for https://fidoalliance.org/passkeys/[Passkeys].

Passkey registration and authentication are realized by the features of WebAuthn.
Therefore, users of Keycloak can do passkey registration and authentication by existing WebAuthn registraton and authentication.
Therefore, users of Keycloak can do passkey registration and authentication by existing WebAuthn registration and authentication.

Both synced passkeys and device-bound passkeys can be used for both Same-Device and Cross-Device Authentication.
However, passkeys operations success depends on the user's environment. Make sure which operations can succeed in https://passkeys.dev/device-support/[the environment].
However, passkeys operations success depends on the user's environment. Make sure which operations can succeed in https://passkeys.dev/device-support/[the environment].
Thanks to https://github.com/tnorimat[Takashi Norimatsu] for the contribution and thanks to https://github.com/thomasdarimont[Thomas Darimont] for the help with the
ideas and testing of this feature.

= WebAuthn improvements

WebAuthn policy now includes a new field: `Extra Origins`. It provides better interoperability with non-Web platforms (for example, native mobile applications).
Thanks to https://github.com/akunzai[Charley Wu] for the contribution.

= RESTEasy Reactive

Keycloak has switched to RESTEasy Reactive. Applications using `quarkus-resteasy-reactive` should still benefit from a better startup time, runtime performance, and memory footprint, even though not using reactive style/semantics. SPI's that depend directly on JAX-RS API should be compatible with this change. SPI's that depend on RESTEasy Classic including `ResteasyClientBuilder` will not be compatible and will require update, this will also be true for other implementation of the JAX-RS API like Jersey.

= More flexibility for introspection endpoint

In previous versions, introspection endpoint automatically returned most claims, which were available in the access token. Now there is new
switch `Add to token introspection` on most of protocol mappers. This addition allows more flexibility as introspection endpoint can return different
claims than access token. This is first step towards "Lightweight access tokens" support as access tokens can omit lots of the claims, which would be still returned
by the introspection endpoint. When migrating from previous versions, the introspection endpoint should return same claims, which are returned from access token,
so the behavior should be effectively the same by default after the migration. Thanks to https://github.com/skabano[Shigeyuki Kabano] for the contribution.

= Feature flag for OAuth 2.0 device authorization grant flow

The OAuth 2.0 device authorization grant flow now includes a feature flag, so you can easily disable this feature. This feature is still enabled by default.
Thanks to https://github.com/thomasdarimont[Thomas Darimont] for the contribution.

= Group scalability improvements

Performance around searching of groups is improved for the use-cases with many groups and subgroups. There are improvements, which allow
paginated lookup of subgroups. Thanks to https://github.com/alice-wondered[Alice] for the contribution.

= User profile improvements

Declarative user profile is still a preview feature in this release, but we are working hard on promoting it to a supported feature. Feedback is welcome.
If you find any issues or have any improvements in mind, you are welcome to create https://github.com/keycloak/keycloak/issues/new/choose[Github issue],
ideally with label `area/user-profile`.

Binary file removed docs/documentation/server_admin/images/cache-tab.png
Binary file not shown.
3 changes: 0 additions & 3 deletions docs/documentation/server_admin/topics/admin-console.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ include::realms/proc-using-admin-console.adoc[leveloffset=1]
include::realms/master.adoc[leveloffset=2]
include::realms/proc-creating-a-realm.adoc[leveloffset=2]
include::realms/ssl.adoc[leveloffset=2][]
ifeval::[{project_product}==true]
include::realms/cache.adoc[leveloffset=2][]
endif::[]
include::realms/email.adoc[leveloffset=2]
include::realms/themes.adoc[leveloffset=2]
include::realms/proc-configuring-internationalization.adoc[leveloffset=2]
Expand Down
14 changes: 0 additions & 14 deletions docs/documentation/server_admin/topics/events/login.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -171,17 +171,3 @@ You can exclude events by using the `--spi-events-listener-email-exclude-events`
kc.[sh|bat] --spi-events-listener-email-exclude-events=UPDATE_TOTP,REMOVE_TOTP
----

You can set a maximum length of each Event detail in the database by using the `--spi-events-store-jpa-max-detail-length` argument. This setting is useful if a detail (for example, redirect_uri) is long. For example:

[source,bash]
----
kc.[sh|bat] --spi-events-store-jpa-max-detail-length=1000
----

Also you can set a maximum length of all Event's details by using the `--spi-events-store-jpa-max-field-length` argument. This setting is useful if you want to adhere to the underlying storage limitation. For example:

[source,bash]
----
kc.[sh|bat] --spi-events-store-jpa-max-field-length=2500
----

Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ image:images/oidc-add-identity-provider.png[Add Identity Provider]
|Signature algorithm to create JWT assertion as client authentication.
In the case of JWT signed with private key or Client secret as jwt, it is required. If no algorithm is specified, the following algorithm is adapted. `RS256` is adapted in the case of JWT signed with private key. `HS256` is adapted in the case of Client secret as jwt.

|Client Assertion Audience
|The audience to use for the client assertion. The default value is the IDP's token endpoint URL.

|Issuer
|{project_name} validates issuer claims, in responses from the IDP, against this value.

Expand Down
16 changes: 0 additions & 16 deletions docs/documentation/server_admin/topics/realms/cache.adoc

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.*;
import java.util.Map;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.HashMap;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,13 @@ Stream<GroupModel> getTopLevelGroupsStream(RealmModel realm,

Endpoint `GET {keycloak server}/realms/{realm}/groups/{group_id}/children` added as a way to get subgroups of specific groups that support pagination

= RESTEeasy Reactive
Relying on RESTEasy Classic is not longer an option because it is not available anymore. Migration will be needed for SPI's and code that is relying on RESTEasy Classic and related packages part of `org.jboss.resteasy.spi.*`.

= Partial export requires manage-realm permission

The endpoint `POST {keycloak server}/realms/{realm}/partial-export` and the corresponding action in the admin console now require `manage-realm` permission for execution instead of `view-realm`. This endpoint exports the realm configuration into a JSON file and the new permission is more appropriate. The parameters `exportGroupsAndRoles` and `exportClients`, which include the realm groups/roles and clients in the export respectively, continue managing the same permissions (`query-groups` and `view-clients`).
The endpoint `POST {keycloak server}/realms/{realm}/partial-export` and the corresponding action in the admin console now require `manage-realm` permission for execution instead of `view-realm`. This endpoint exports the realm configuration into a JSON file and the new permission is more appropriate. The parameters `exportGroupsAndRoles` and `exportClients`, which include the realm groups/roles and clients in the export respectively, continue managing the same permissions (`query-groups` and `view-clients`).

= Removal of the options to trim the event's details length

Since this release, Keycloak supports long value for `EventEntity` details column. Therefore, it no longer supports options for trimming event detail length `--spi-events-store-jpa-max-detail-length` and `--spi-events-store-jpa-max-field-length`.
5 changes: 2 additions & 3 deletions docs/guides/getting-started/templates/first-app.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@ To secure the first application, you start by registering the application with y
. Fill in the form with the following values:
** *Client type*: `OpenID Connect`
** *Client ID*: `myclient`
+
image::add-client-1.png[Add Client]
. Click *Next*
. Confirm that *Standard flow* is enabled.
. Click *Next*.
+
image::add-client-1.png[Add Client]

. Make these changes under *Login settings*.
* Set *Valid redirect URIs* to `+https://www.keycloak.org/app/*+`
* Set *Web origins* to `+https://www.keycloak.org+`
Expand Down
10 changes: 5 additions & 5 deletions docs/guides/server/caching.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The current distributed cache implementation is built on top of https://infinisp
== Enable distributed caching
When you start Keycloak in production mode, by using the `start` command, caching is enabled and all Keycloak nodes in your network are discovered.

By default, caches are using a `UDP` transport stack so that nodes are discovered using IP multicast transport based on UDP. For most production environments, there are better discovery alternatives to UDP available. Keycloak allows you to either choose from a set of pre-defined default transport stacks, or to define your own custom stack, as you will see later in this {section}.
By default, caches are using a UDP transport stack so that nodes are discovered using IP multicast transport based on UDP. For most production environments, there are better discovery alternatives to UDP available. Keycloak allows you to either choose from a set of pre-defined default transport stacks, or to define your own custom stack, as you will see later in this {section}.

To explicitly enable distributed infinispan caching, enter this command:

Expand Down Expand Up @@ -156,7 +156,7 @@ To apply a specific cache stack, enter this command:

<@kc.build parameters="--cache-stack=<stack>"/>

The default stack is set to `UDP` when distributed caches are enabled.
The default stack is set to `udp` when distributed caches are enabled.

=== Available transport stacks

Expand All @@ -181,9 +181,9 @@ The following table shows transport stacks that are available using the `--cache

=== Additional transport stacks
The following table shows transport stacks that are supported by Keycloak, but need some extra steps to work.
Note that _none_ of these stacks are Kubernetes / OpenShift stacks, so no need exists to enable the "google" stack if you want to run Keycloak on top of the Google Kubernetes engine.
Note that _none_ of these stacks are Kubernetes / OpenShift stacks, so no need exists to enable the `google` stack if you want to run Keycloak on top of the Google Kubernetes engine.
In that case, use the `kubernetes` stack.
Instead, when you have a distributed cache setup running on AWS EC2 instances, you would need to set the stack to `ec2`, because ec2 does not support a default discovery mechanism such as `UDP`.
Instead, when you have a distributed cache setup running on AWS EC2 instances, you would need to set the stack to `ec2`, because ec2 does not support a default discovery mechanism such as UDP.

[%autowidth]
|===
Expand All @@ -197,7 +197,7 @@ Instead, when you have a distributed cache setup running on AWS EC2 instances, y
Cloud vendor specific stacks have additional dependencies for Keycloak.
For more information and links to repositories with these dependencies, see the https://infinispan.org/docs/dev/titles/embedding/embedding.html#jgroups-cloud-discovery-protocols_cluster-transport[Infinispan documentation].

To provide the dependencies to Keycloak, put the respective JAR in the `providers` directory and `build` Keycloak by entering this command:
To provide the dependencies to Keycloak, put the respective JAR in the `providers` directory and build Keycloak by entering this command:

<@kc.build parameters="--cache-stack=<ec2|google|azure>"/>

Expand Down
Loading