Had an idea with regards to clustering and user sessions. Instead of sending messages to the cluster when a individual user session is refreshed all nodes send a periodic update message. Obviously that's only for user sessions and not for admin updates, where we should still send invalidation messages for each update.
Each node would keep a note of all user sessions where it has updated LastSessionRefresh, and once every period it would send this list to all nodes. This should mean that instead of sending a message every time a single session is updated, we send a single message per node every 60 seconds or so (should be configurable). When receiving a message from the cluster the node would go through the list and update the user sessions where the received LastSessionRefresh is higher than the one it has itself. Nodes still use the mem user sessions store, but with the cache on top.
I have a prototype working and I think I've got the lay of the land.
Now I need help to make design decisions. (BTW, every time I say
WildFly I mean WildFly or EAP)
Deployment to the /deployments directory is generally discouraged,
especially in production environments. In a domain configuration, it is
impossible because there is no deployment scanner and no /deployments
directory. Today, if you want to use the Keycloak Auth Server in a
domain, you must upload the WAR to the content repository and assign it
to one or more server groups.
This not only adds extra installation steps, it complicates management
of the auth server. The auth server could be assigned to WildFly
instances where Keycloak modules are not installed. Furthermore, WildFly
administrators with highly restricted roles in the web console and CLI
would have too much control over the auth server deployment. IMO, only
Administrator or higher should be able to control the auth server
The Keycloak Auth Server can instead be deployed as part of the Keycloak
Subsystem. The plan is to make subsystem deployment an option on
both standalone and domain installations. This makes the Auth Server
into more of a service instead of an end-user application.
*Questions and Design Decisions*
The Auth Server WAR will live in its own module. Is there any reason
for it to be in exploded form?
The Keycloak Subsystem will get a new resource called "auth-server".
Right now I only plan to have one attribute called "enabled". By
default, this will be false in a domain environment. You don't want an
auth server to boot everywhere you install the keycloak subsystem. Do
we want this to be true for standalone? In other words, should the auth
server automatically boot if the keycloak subsystem is installed on
Are there any other attributes to add? The Keycloak subsystem can do
anything it wants to the auth server at deployment time. It can change
context params, add modules, boot in some kind of admin-only mode, or
anything else. Configuration settings on the WAR could be made from
standalone.xml, domain.xml, CLI, etc. Anything you would like the
subsystem to do?
Do I need to allow for multiple auth server deployments in the same
WildFly instance? This is quite easy to do. For the second instance,
it would override the module name of the auth server WAR.
What are the plans and considerations for clustered auth server?
Anything I should be aware of at this point?
 See "A Mixed Apporach" https://developer.jboss.org/wiki/ExtendingAS7
WildFly 9 introduces features packs which seams ideal for us to build Keycloak upon.
I'd like to start a "wildfly-9" branch of Keycloak that uses feature-packs and WildFly's built in mechanism to create the appliance distro. This would replace our current custom appliance-dist. Further I'd like us to have two flavours of Keycloak:
* "appliance-lite": minimum Keycloak server only dist. For those that want a standalone Keycloak server. Builds on WildFly "web-lite" dist, but we need to add Hibernate, RestEasy and Connectors (datasources) as well
* "appliance": full WildFly dist. For those that want to co-locate their JavaEE apps with the Keycloak server. Builds on the full WildFly dist.
I've already tried to run Keycloak on WildFly 9.0.0.alpha1 web-lite and it works fine. Only thing I had to do was to include RestEasy and Hibernate jars in auth-server.war and configure the database directly in keycloak-server.json instead of using a datasource.
I think it would make sense to provide a plain Java adapter, as well as a plain Servlet adapter. Further this should be the base for all other adapters.
+--------+ +---------+ +-----------+ +---------+
| Tomcat | |JBoss AS | |PicketLink | | WildFly |
| Jetty | |JBoss EAP| | | | |
| ... | | | | | | |
+----+---+ +---+-----+ +---+-------+ +----+----+
| | | |
| +---v-----+ | +----v----+
+----->Servlet <------+ | Undertow|
| | | |
| +---------+ |
The Java adapter should have minimum dependencies (maybe only http-client?).
Don't get to hung-up with the syntax (I knocked this together in 2 min), but the general idea would be something like:
InputStream is = new FileInputStream("keycloak.json");
KeycloakOAuthClient client = KeycloakClient.createOAuth(is);
// get login url
URL loginUrl = client.createLoginUrl(redirectUri);
// exchange code to token
AccessTokenResponse response = client.getToken(code, clientCredentials);
// refresh token
We have most of the code, but what we don't is a public Java API.
Have few questions related to cookies & rememberMe.
1) Actually the KEYCLOAK_IDENTITY cookie is generated with the -1 by
default (so expires when browser is closed). Thing is that lifespan of
the identityToken generated in AuthenticationManager.createIdentityToken
is just ssoSessionIdleTimeout, which is 10 minutes by default. And
cookie is refreshed just during cookie SSO login. So for example when I
have scenario like:
* Login to admin console
* Do some admin work for 15 minutes
* Then click to "Manage my account" button (or to some other Keycloak
secured application), the token in the KEYCLOAK_IDENTITY cookie is not
valid anymore, so I am immediately logged out. Note that UserSession is
still valid as I had couple of refreshToken requests during my 15
minutes 'admin' work.
So my question is if we can use ssoSessionMaxLifespan for the identity
token instead of ssoSessionIdleTimeout? Note that even in cookie
authentication, we are also checking if UserSession is valid. So if
UserSession is expired, the login won't be successful anyway.
2) Second thing is RememberMe feature. Actually we have
KEYCLOAK_REMEMBER_ME cookie, which is set after successful login with
rememberMe. But this cookie is actually not used anywhere for relogin!
Only thing is KEYCLOAK_IDENTITY cookie set with the lifespan of
ssoSessionIdleTimeout, so once you restart browser, KEYCLOAK_IDENTITY
cookie will survive and you will be able to relogin.
Problem is that KEYCLOAK_IDENTITY is tight to particular UserSession. So
for example if I have scenario like:
* Login to admin console
* Close my browser and wait 15 minutes
* Then open my browser and try to relogin --- ATM both UserSession and
KEYCLOAK_IDENTITY cookie are not valid anymore so rememberMe doesn't
work and Keycloak login screen is displayed to me.
Also scenario like:
* Login to admin console
* Close my browser and restart Keycloak
* Then open my browser and try to relogin --- rememberMe also won't work
as UserSession is not valid (unless I am using 'jpa' or 'mongo'
IMO RememberMe shouldn't be tight to particular UserSession. I would
expect that when I start browser next day, I will be automatically
logged in even if my UserSession from previous day is already expired.
It seems that to properly support RememberMe, we should use
KEYCLOAK_REMEMBER_ME cookie instead of KEYCLOAK_IDENTITY . IMO value of
KEYCLOAK_REMEMBER_ME cookie should be random token signed by realm
privateKey and valid just for one use (Each RememberMe login will
regenerate token and refresh value of KEYCLOAK_REMEMBER_ME cookie) .
This would mean that we will need to persist stuff related to rememberMe
with some additional related informations (realm, user, timestamp,
ipAddress). So for example if admin will set Not-Before for realm, it
will also invalidate all stored rememberMe tokens.
It seems that this will require some model changes and amount of work,
but ATM RememberMe feature seems to be quite unusable to me.
<tldr>DEVELOPERS WILL NEVER HAVE TO WRITE ANOTHER LINE OF AUTH LOGIC
Over the weekend I tried my hand at writing a Android Account
Authenticator for KeyCloak. This lets Android manage the KeyCloak
account, fetch tokens, provide tokens to other apps etc. KeyCloak
Authenticator let's you drop your keycloak.json file into an apk and
access your KeyCloak Account with one line of code from any application
on your Android device.
Right now this is very much in the "I have an itch needing scratching"
phase. It doesn't do any robust error handling, hasn't been testing off
the golden scenario, has no integration with any of the AeroGear stuff,
etc. Take a moment to watch the Demo and look at the demo project.
Video Demo :
The Demo video uses Android's native account menu to request from the
authenticator a KeyCloak account. This launches the authenticator's
activity which will retrieve the credentials for Android and store
them. When I am back in the settings page and showing off the stored
account, this is all native Android UI and not part of the KeyCloak
When I launch the Demo application this is a separate application from
the authenticator apk. The Demo project fetches the KeyCloak account
from Android and gets its auth token. Then it makes a request to
KeyCloak's account service to fetch the user's account data.
In the demo app there are three lines of code related to auth.
final Account account = am.getAccountsByType("org.keycloak.Account");
String token = am.getAuthToken(account, "org.keycloak.Account.token",
null, null, null, null).getResult().getString(AccountManager.KEY_AUTHTOKEN);
provider.setDefaultHeader("Authorization", "bearer " + token);
The first two lines fetch the account and token from Android. The
second line attaches the account's auth token to the web request to the
So now what? I'll probably use this for my projects/demos because it
makes my work easier. Right now it doesn't have any connection to any
of the "official" projects (Again, I wrote this over the weekend to see
if I could) however it may be quite useful to someone. In the project's
README I've included a (incomplete) list of things that don't work.
Project : https://github.com/secondsun/keycloak-android-authenticator
Video Demo :
Demo Source :
>>Phone:404 941 4698
>>Java is my crack.
When we start working on some major features that require refactoring
(SAML, internationalization, even expanded clustering support), should
we do a 1.0.1 release? 22nd or 23rd? Before we start our feature work?
JBoss, a division of Red Hat
I had created a Branch_1_0 with the 1.0 final release. We need to
decide whether or not we're going to branch and do point releases of
1.0.x from that branch.
JBoss, a division of Red Hat