Refresh token - should it expire?
by Juraci Paixão Kröhling
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Hello,
I'm building a secret store application that will sit in front of
Hawkular and will be responsible for replacing API keys into actual
Keycloak authentication data.
Based on the suggestions from Stian, the current code does the following
:
- - User logs in Hawkular via Keycloak
- - Once the user wants to create a new application key/secret, the user
is redirected to /secret-store/tokens/create , which takes the KC
authentication data and stores the refresh_token into the database,
creating a new key/secret
- - User configures an external application (like a monitoring agent in
a server), adding this key/secret to its configuration
- - The agent makes a call to the Hawkular backend, sending this key/secre
t
- - An undertow filter gets this key/secret from the request, fetches
the refresh_token from the database, gets a bearer token from Keycloak
based on this refresh_token and sets it to the request's context (ie:
replacing the Authorization header)
- - Keycloak uses this bearer token to perform what it needs to do
- - Request reaches the Hawkular backend
It all works, but the session from the *user* (second step) eventually
expires, causing the refresh_token to be invalid[1].
So, the question is whether this token is indeed supposed to be
attached to an user session, or if it's a bug. If the behavior I'm
seeing is the correct one, what could be a proper way to store a token
so that it can be replaced at a later time?
1 - http://git.io/vLAtF
Best,
Juca.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2
iQEcBAEBCAAGBQJViUgHAAoJEDnJtskdmzLMCIsH/iOeGmCDANgjvliyeKMWcx0/
j0cFdJuENBqzgPRlj0tSSJeFZeNnIs07ARJk2E0Xoq1D2gSq3KAw3hTOq7nPNfOk
SoG5f1dLDkwCB8a+d/IGNfPw6Tmbzn0i2kwRSbhSJdfYCDxg9xiMPnV2MjvunPYa
f6sXHz0yZjwylis3UuBw7WUNr1wAYOpjfmdBmt0B6hEqBXbIZflX2OEhim7dC+PQ
WBx4lobqWWR+pMF12oabngNPLoE1r8SGSJkkiusMZxaTIWOViiHIYkRzVcul32z7
1OI0EOHnnv4YJ1rzc9frAIu7EPZq0i4BM1YT9pRBlNFBWH/ZQawEyCN6KCrNHDI=
=EA+F
-----END PGP SIGNATURE-----
9 years, 2 months
Having trouble with LDAP attribute mapping in 1.3.1
by Kevin Thorpe
Thanks to the team for 1.3.1. We were eagerly waiting for that to add LDAP
attribute mappings which I see has now been done. Unfortunately I can't
seem to get it to work.
I have added a user attribute mapper to my ldap federation. This maps the
LDAP atribute 'applications' which exists on my LDAP user record to
'applications' in Keycloak.
I have also added a user attribute token mapper to my Keycloak client
definition to map user attribute 'applications' to token claim
'applications'. I've also asked to add to both id and access token.
However this attribute is not present in either the ID or access token when
testing. Is there something I've missed?
Something that may be an issue though is that I'm using a home written
openid-connect Lua client based on your javascript one. This uses the
endpoint /auth/realms/master/protocol/openid-connect/token. Is it that the
openid-connect endpoint doesn't support these attributes yet?
*Kevin Thorpe*
CTO, PI ltd
9 years, 4 months
Error during "Synchronize all users" from an LDAP Server
by Giovanni Baruzzi
Dear Friends,
I got the following exception trying to “synchronize all users” from a LDAP Server. The dialog user is „Settings->User Federation->Settings.
Please find the details about the LDAP Server further below after the Java LOG.
Thank for your attention,
Giovanni
=====================
20:23:38,119 ERROR [io.undertow.request] (default task-9) UT005023: Exception handling request to /auth/admin/realms/demo/user-federation/instances/6f4de879-f4b7-4d74-9141-46044c4b9e09/sync: java.lang.RuntimeException: request path: /auth/admin/realms/demo/user-fede ration/instances/6f4de879-f4b7-4d74-9141-46044c4b9e09/sync
at org.keycloak.services.filters.KeycloakSessionServletFilter.doFilter(KeycloakSessionServletFilter.java:54)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132)
at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:85)
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler. java:78)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java :131)
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java :57)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstrai ntHandler.java:64)
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58)
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.ja va:72)
at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:274)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:253)
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:80)
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:172)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:199)
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:774)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.jboss.resteasy.spi.UnhandledException: java.lang.IllegalStateException: Expected String but attribute was [adub, sdub] of type java.util.TreeSet
at org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:76)
at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:212)
at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:149)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:372)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:179)
at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:220)
at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:86)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:130)
at org.keycloak.services.filters.ClientConnectionFilter.doFilter(ClientConnectionFilter.java:41)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132)
at org.keycloak.services.filters.KeycloakSessionServletFilter.doFilter(KeycloakSessionServletFilter.java:40)
... 29 more
Caused by: java.lang.IllegalStateException: Expected String but attribute was [adub, sdub] of type java.util.TreeSet
at org.keycloak.federation.ldap.idm.model.LDAPObject.getAttributeAsString(LDAPObject.java:79)
at org.keycloak.federation.ldap.LDAPUtils.getUsername(LDAPUtils.java:76)
at org.keycloak.federation.ldap.LDAPFederationProvider.importLDAPUsers(LDAPFederationProvider.java:390)
at org.keycloak.federation.ldap.LDAPFederationProviderFactory.importLdapUsers(LDAPFederationProviderFactory.java:269)
at org.keycloak.federation.ldap.LDAPFederationProviderFactory$1.run(LDAPFederationProviderFactory.java:223)
at org.keycloak.models.utils.KeycloakModelUtils.runJobInTransaction(KeycloakModelUtils.java:241)
at org.keycloak.federation.ldap.LDAPFederationProviderFactory.syncImpl(LDAPFederationProviderFactory.java:219)
at org.keycloak.federation.ldap.LDAPFederationProviderFactory.syncAllUsers(LDAPFederationProviderFactory.java:177)
at org.keycloak.services.managers.UsersSyncManager.syncAllUsers(UsersSyncManager.java:50)
at org.keycloak.services.resources.admin.UserFederationProviderResource.syncUsers(UserFederationProviderResource.java:144)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:137)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:296)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:250)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:140)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:109)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:135)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:109)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:135)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:109)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:135)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:103)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:356)
... 40 more
The LDAP Server is a port389 (nearly identical to RedHat) this is an excerpt of the LDIF of the people container
(all test data, not real people)
dn: ou=People, dc=syntlogo,dc=de
objectClass: top
objectClass: organizationalunit
ou: People
dn: uid=cros, ou=People, dc=syntlogo,dc=de
cn: Carlo Rossi
sn: Rossi
givenName: Carlo
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
ou: Accounting
ou: People
l: Milano
uid: cros
mail: carlo.rossi(a)mycompany.com<mailto:carlo.rossi@mycompany.com>
telephoneNumber: +39-02-2267-4798
facsimileTelephoneNumber: +39-02-2267-9751
roomNumber: 4612
userPassword: {SSHA}dvuiZA9vGMEqopNlIJ2qwxf0igE1fmJVLB8MRw==
dn: uid=gste, ou=People, dc=syntlogo,dc=de
cn: Gudrun Steinle
sn: Steinle
givenName: Gudrun
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
ou: Accounting
ou: People
l: Stuttgart
uid: gste
mail: gudrun.steinle(a)mycompany.com<mailto:gudrun.steinle@mycompany.com>
telephoneNumber: +49-711-2359-9187
facsimileTelephoneNumber: +49-711-2359-8473
roomNumber: 4117
userPassword: {SSHA}wc8v0cdM3GNzzQZ9EkfH5EdUBUMqVtMCDlTXFQ==
dn: uid=abia, ou=People, dc=syntlogo,dc=de
cn: Antonio Bianchi
sn: Bianchi
givenName: Antonio
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
ou: Human Resources
ou: People
l: Milano
uid: abia
mail: antonio.bianchi(a)mycompany.com<mailto:antonio.bianchi@mycompany.com>
telephoneNumber: +39-02-2267- 5625
facsimileTelephoneNumber: +39-02-2267- 3372
roomNumber: 2871
userPassword: {SSHA}+b2IRLQ2tPT5xLSiYAnM4vuUrY7FMac/NwGXFQ==
and in the log of the LDAP server is the following to see:
[18/May/2015:14:32:26 +0200] conn=168 fd=64 slot=64 connection from 10.1.0.90 to 10.1.0.93
[18/May/2015:14:32:26 +0200] conn=169 fd=65 slot=65 connection from 10.1.0.90 to 10.1.0.93
[18/May/2015:14:32:26 +0200] conn=169 op=0 BIND dn="cn=directory manager" method=128 version=3
[18/May/2015:14:32:26 +0200] conn=169 op=0 RESULT err=0 tag=97 nentries=0 etime=0 dn="cn=directory manager"
[18/May/2015:14:32:26 +0200] conn=169 op=1 SRCH base="ou=people,dc=syntlogo,dc=local" scope=1 filter="(&(objectClass=organizationalPerson)(objectClass=inetOrgPerson))" attrs="uid nsUniqueId mail createTimestamp sn cn objectClass modifyTimestamp"
[18/May/2015:14:32:26 +0200] conn=169 op=1 RESULT err=0 tag=101 nentries=19 etime=0 notes=P
9 years, 5 months
How read added mapper attribute from ldap?
by Adam Daduev
Hi.
I try use new feature of keycloak 1.3.1, i added new attribute, like
department, but i can not get it in my web bean, i try get new attribute
from KeycloakSecurityContext, but con not found.
How can i get my new added atribute?
Thanks!
9 years, 5 months
Update the user only with required fields
by Chamantha De Silva
Hi Team,
There are situations that we use update user rest API, to update just one element of user (eg: enabled : false etc.) .
This requires a pre fetched user object from the GET user call, other wise rest of the user information tend to be truncated after the update call.
Is there a possibility to update only specific elements of the user instead of sending whole the user object (objective is to avoid the GET call right before the update call and avoid possible tendency of data truncations )? Your kind reply is highly appreciated.
Best regards,
Chamantha
9 years, 5 months
keycloak 1.3.1 OpenID Connect token introspection url
by Niels Bertram
Hi there,
I am trying to configure a server side (RP) client which requires a JWT
introspection URL on the OP. I tried to find such endpoint on the KeyCloak
server without avail neither did I actually find any url of type
"introspect" in the OpenID Connect Specification.
Does anyone know if/how a OAuth2 client can validate a JWT token via a back
channel with the KeyCloak server?
The client I am trying to configure is the MITREid client as per
https://github.com/mitreid-connect/OpenID-Connect-Java-Spring-Server/wiki...
Looking at the code, the client will issue a post to the introspection
endpoint with some form data:
POST /auth/realms/myrealm/protocol/openid-connect/introspect HTTP/1.1
Host: localhost:8080
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
client_id=myapp&client_secret=mysupersecret&token=eyJhbGciO[trunkated but
valid access token]
Any pointers are much appreciated.
Kind Regards,
Niels
9 years, 6 months
User Registration using UserFederationProvider
by Greg Jones
Hi Team,
We are implementing Keycloak as an SSO Server, linked to our existing back-end that is currently responsible for maintaining user registration details. We have developed a UserFederationProvider and are able to login correctly and add our existing authentication token to the JSON Web Token.
The next step was to use the back-end server for user registrations and this is where we are having problems.
We have added the desired fields to registration.ftl for our chosen theme and have verified that these fields are being added as attributes. We have the problem that the federation provider’s register(RealmModel realm, UserModel user) method is called before any fields (other than username) are populated from the registration form (See LoginActionsService.java - line 625) and we cannot register the user without these fields being populated.
For our demo to the team, we have found a work-around, whereby we have created an EventListenerProvider that handles the REGISTER event, and performs the user registration at that point. This works since we have all of the information we need by then.
Clearly, Keycloak is expecting to be the primary holder for information collected during the registration process but there are several issues with the way it currently works:
1. There is no way to add validation for any extra fields that are added to the registration page, or to change the validation rules for existing fields on that page. It would be useful to have a Validation SPI for modules to be able to provide their own validation.
2. As mentioned, the federation provider’s register method is called before the additional fields are added to the UserModel.
3. There is no way for the federation provider’s register method to report an error during registration, e.g. a comms error or missing data. Any exception thrown during this call results in a blank page showing “Internal Server Error”.
I am hoping for some guidance here, on whether we have chosen the correct approach to user registration or whether we should be doing it differently.
Thanks in advance,
Greg Jones
9 years, 6 months
Importing an Application (Client) into an Existing Realm
by Lohitha Chiranjeewa
Hi,
We get the need to create applications (clients) from time to time in our
already existing realm. Since these clients have to be created in all the
environments (dev, QA, staging, production) we'd like it to be (partly)
automated rather than creating them through Admin console in each
environment.
We've seen an 'Import Client' option in the Clients section in the Admin
console, but not sure how to create the initial client so that it can be
imported. The only import type is 'SAML 2.0 Entity Descriptor', which we
aren't sure about as well. Can someone point out how we should continue to
build the initial client here?
Also, if there is an option to update the existing realm with the 'Export
Realm' facility, that would do as well. However that's not possible I
suppose?
Regards,
Lohitha.
9 years, 6 months
Maximum number of clients (applications) in a realm
by Orestis Tsakiridis
Hi all,
Is there a limit in the maximum number of clients/applications in single
realm supported by keycloak?
I can see that the keycloak admin UI is not built with a big number in
mind. For instance, when assigning "Client roles" to a realm user there is
a dropdown with all clients/applications in the realm. I guess this
shouldn't grow too big to be usuable.
I'm working on a scenario where i need to implement authorization in a
system where new machines (and their respective keycloak applications) will
be added on the fly. So i'm worying about what will happen if the number
starts to grow.
Thanks
9 years, 6 months
Keycloak suitability in microservice-based platform
by Shannon Lloyd
Hi,
We are evaluating Keycloak for possible use in a microservices-based SaaS
platform that we are building, and I have a few questions around the
suitability of Keycloak within the architecture that we are planning on
using.
Briefly, we will have a handful of end-user applications with their own UIs
and a large number of backend services with which those UIs will speak.
Some of those services will act as aggregating/gateway services which will
delegate to other services further downstream, so there will be a lot of
service-to-service comms. Our design currently calls for each logical
application (i.e. a UI plus a handful of supporting services) to have its
own set of roles that make sense within the context of that application.
Because many/most roles will only make sense in that one context, it does
not make sense for a user's token to contain all possible roles across the
entire realm (the tokens would be insanely large). We came up with the idea
of having an authentication/identity token (containing no
application-specific roles) to represent the logged in user, and then
passing this token to downstream services which would then (e.g. via a
filter in front of that service) retrieve and cache application-specific
tokens (with roles) from the SSO service for that combination of
authenticated identity and application/client (relying on the fact that the
identity token is valid and not expired as proof of an active session).
Firstly, does this seem like a reasonable approach?
Secondly, how much support is there in Keycloak to support something like
this? We are not using an app server, so it doesn't appear to be a simple
case of leveraging one of the existing adapters. We have a custom
Java(-SE)-based framework (happens to use Undertow for HTTP, but only
undertow-core). What support exists for custom, programmatic authentication
and JWT retrieval outside of the set of adapters provided in the Keycloak
distribution? Are there any examples along these lines? Is it a case of us
needing to trawl through all the REST endpoints exposed via
keycloak-services to figure out what is do-able, or are the non-admin
endpoints documented somewhere in the same way that the admin endpoints
have been documented?
I noticed this on the Keycloak blog about a month ago:
If a service needs to invoke another service it can pass on the token it
received, which will invoke the other service with the users permissions.
Soon we'll add support for services to authenticate directly with Keycloak
to be able to invoke other services with their own permissions, not just on
behalf of users.
Is there any news on these plans? It sounds like the sort of thing that we
would require.
Cheers,
Shannon
9 years, 6 months