How to create a custom OTPPolicy?
by Known Michael
Hello,
I need to create a custom OTPPolicy.
Unfortunately, OTPPolicy policy is created via the constructor and not via
a factory:
public static OTPPolicy DEFAULT_POLICY = new
OTPPolicy(UserCredentialModel.TOTP, HmacOTP.HMAC_SHA1, 0, 6, 1, 30);
(from the class org.keycloak.models.OTPPolicy)
Any help will be appreciated.
6 years, 9 months
Make custom Mapper for a specific claim field with HTTP Service Call
by Brissat Vivien
Hi,
I would like to add a specific claim field in the JWT Token, that take a value issued from a Service Call (HTTP POST that return a JSON result).
I saw that I can maybe specify a custom Mapper with something like : public class PersonalMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper{}
But I don’t know where to use this code, and I don’t know where to call my Service in Keycloak.
Maybe in a custom Provider ? The documentation is not really helpful since I don’t see any SPI for Custom Mapper, or a way to achieve this.
Thanks for your help,
Best Regards
Vivien Brissat
6 years, 9 months
Access Token not refreshed // KEYCLOAK-2517
by Kuestermann, Thomas
Keycloak experts,
We're currently developing a Spring Boot based application and we're using Keycloak for the identity management. Works great so far. We recently updated Keycloak and the respective spring boot adapter and spring security module to 3.4.1.Final.
We've configured access tokens with a lifespan of 5 minutes, I think that's also the default. After the upgrade we noticed that every HTTP call is answered with a 401 - Unauthorized after the access token timed out (due to inactivity in the application). This wasn't the case before. Keycloak documentation states that
> By default the application adapter will only refresh the access token when it's expired. [1]
which doesn't seem to work anymore.
I debugged the application and came across KEYCLOAK-2517 [2] which introduced KeycloakSecurityContextRequestFilter. Looking at the code, it seems that access tokens are only refreshed when they're valid:
+ if (refreshableSecurityContext.isActive()) {
+ KeycloakDeployment deployment = resolveDeployment(request, response);
+
+ if (deployment.isAlwaysRefreshToken()) {
+ if (refreshableSecurityContext.refreshExpiredToken(false)) {
+ request.setAttribute(KeycloakSecurityContext.class.getName(), refreshableSecurityContext);
+ } else {
+ clearAuthenticationContext();
+ }
+ }
+ } else {
+ clearAuthenticationContext();
+ }
Otherwise the authentication context is cleared and access to resources is denied.
Is this intended behavior? For me, it looks like a bug. If not, what's the general guideline on how to handle access token timeouts?
Our current workaround is to overwrite keycloakSecurityContextRequestFilter() in our derived KeycloakWebSecurityConfigurerAdapter like this:
+ @Override
+ protected KeycloakSecurityContextRequestFilter keycloakSecurityContextRequestFilter() {
+ return new KeycloakSecurityContextRequestFilter() {
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response,
+ FilterChain filterChain) throws IOException, ServletException {
+ filterChain.doFilter(request, response);
+ }
+ };
+ }
It also look like others are facing the same issue [3].
Any help or pointer is highly appreciated.
[1] http://www.keycloak.org/docs/3.4/securing_apps/index.html#_refresh_token_...
[2] https://issues.jboss.org/browse/KEYCLOAK-2517 PR: https://github.com/keycloak/keycloak/pull/4741
[3] https://github.com/jhipster/generator-jhipster/issues/6929
-- Thomas
6 years, 9 months
HA for keycloak
by Lahari Guntha
Hi All,
I have launched keycloak as a Docker container. I am using Keycloak of version 3.3.0.CR2. I have all my configurations done for nearly 10 clients. It is working fine...somehow my container went to "Excited" state. Since I have configured all my applications to have SSO.....and since the container went down....and since the entry point for all my applications is Keycloak...I was not able to reach out to any of my applications.
Moreover when I started the container back I lost all my configuration made....
Is there any clear documentation i.e step by step procedure to have Keycloak with high availability???
Thanks & Regards,
Lahari G
=====-----=====-----=====
Notice: The information contained in this e-mail
message and/or attachments to it may contain
confidential or privileged information. If you are
not the intended recipient, any dissemination, use,
review, distribution, printing or copying of the
information contained in this e-mail message
and/or attachments to it are strictly prohibited. If
you have received this communication in error,
please notify us by reply e-mail or telephone and
immediately and permanently delete the message
and any attachments. Thank you
6 years, 9 months
AD FS logout
by Fernando Quiroga
Hi everyone,
I'm using keycloak-js with an AD FS to login my users, my problem comes
when I want to logout them, becuase they get redirected all the time inside
my application, here is the flow:
1) The user is logged in my site, so he is in my site dashboard
2) User makes logout
3) User is redirected to the index of my site, keycloak checks that the
user isn't logged and redirct him (due to kc_ipd_hitn parameter) to ad fs
login screen, but because the user is already logged in his AD FS, is
redirected again to my site and then to the dashboard.
So this is an inifite loop for loggin out because the keycloak logout in
the keycloak-js is not loging the user out from AD FS.
Is there any possible solution to this?
Regards
6 years, 9 months
Combining transparent and opaque tokens
by Omri Tavor
Hi,
A quick newbie question.
My application has multiple backend services and a few public gateways for public APIs.
I need all of my services to have the full user information (name, roles etc) but I don't want each of the backend services sending requests to the Keycloak server in order to get this information (this would greatly impact performance and force the application to be fully synchronous). Can I use opaque tokens for my public API (both backend calls and user calls) and then having a transparent token as the request goes through my backed services? In other words, I want to verify the user and get its information only on the initial request and then having all of the user data embedded in a token as it travels through the backend services. This token should have to be refreshed after some time. Can I do that?
Thanks,
Omri.
6 years, 9 months
Loading a custom form authenticator fails with Failed to define class ... UsernamePasswordForm
by Niels Bertram
Hi there,
getting kinda desperate here... I wrote a custom form authenticator that
extends the UsernamePasswordForm of Keycloak and packaged it up in an EJB
jar inside an EAR file (almost identical to the official example
<https://github.com/keycloak/keycloak/tree/master/examples/providers/authe...>).
I can configure it in the authentication flow but as soon as it is loaded
as part of an auth flow I get " Failed to define class
org/keycloak/authentication/authenticators/browser/UsernamePasswordForm "
error.
I have another authenticator in the same package that does *not *extend
org.keycloak.authentication.authenticators.browser.UsernamePasswordForm and
it loads and executes fine. I tried adding the module keycloak-services
explicitly to my EJB jars deployment descriptor:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="org.keycloak.keycloak-services" slot="main" />
</dependencies>
</deployment>
</jboss-deployment-structure>
No avail. Looks like something wrong with the way Keycloak accesses the
classes discovered by ServiceLoader. Anyone got any hints or seen this
before?
Many thanks Niels
Full stack trace:
23:13:01,107 WARN [org.jboss.modules] (default task-44) Failed to define
class
my.sso.plugins.authentication.authenticators.browser.CustomUsernamePasswordForm
in Module
"deployment.custom-keycloak-extension-archive.ear.custom-user-federation-ejb.jar"
from Service Module Loader: java.lang.NoClassDefFoundError: Failed to link
my/sso/plugins/authentication/authenticators/browser/CustomUsernamePasswordForm
(Module
"deployment.custom-keycloak-extension-archive.ear.custom-user-federation-ejb.jar"
from Service Module Loader):
org/keycloak/authentication/authenticators/browser/UsernamePasswordForm
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native
Method)
at
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at
org.jboss.modules.ModuleClassLoader.defineClass(ModuleClassLoader.java:446)
at
org.jboss.modules.ModuleClassLoader.loadClassLocal(ModuleClassLoader.java:274)
at
org.jboss.modules.ModuleClassLoader$1.loadClassLocal(ModuleClassLoader.java:77)
at org.jboss.modules.Module.loadModuleClass(Module.java:713)
at
org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:190)
at
org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:412)
at
org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:400)
at
org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:116)
at
my.sso.plugins.authentication.authenticators.browser.CustomUsernamePasswordFormFactory.create(CustomUsernamePasswordFormFactory.java:56)
at
my.sso.plugins.authentication.authenticators.browser.CustomUsernamePasswordFormFactory.create(CustomUsernamePasswordFormFactory.java:16)
at
org.keycloak.authentication.DefaultAuthenticationFlow.processFlow(DefaultAuthenticationFlow.java:164)
at
org.keycloak.authentication.DefaultAuthenticationFlow.processFlow(DefaultAuthenticationFlow.java:127)
at
org.keycloak.authentication.AuthenticationProcessor.authenticateOnly(AuthenticationProcessor.java:853)
at
org.keycloak.authentication.AuthenticationProcessor.authenticate(AuthenticationProcessor.java:722)
at
org.keycloak.protocol.AuthorizationEndpointBase.handleBrowserAuthenticationRequest(AuthorizationEndpointBase.java:145)
at
org.keycloak.protocol.oidc.endpoints.AuthorizationEndpoint.buildAuthorizationCodeAuthorizationResponse(AuthorizationEndpoint.java:395)
at
org.keycloak.protocol.oidc.endpoints.AuthorizationEndpoint.build(AuthorizationEndpoint.java:139)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at
org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:140)
at
org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:295)
at
org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:249)
at
org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:138)
at
org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:107)
at
org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:133)
at
org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:101)
at
org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:406)
at
org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:213)
at
org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:228)
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:85)
at
io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
at
org.keycloak.services.filters.KeycloakSessionServletFilter.doFilter(KeycloakSessionServletFilter.java:90)
at
io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at
io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at
io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
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(ServletConfidentialityConstraintHandler.java:64)
at
io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
at
io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
at
io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
at
io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
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
org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68)
at
io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at
io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
at
io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
at
io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
at
io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
at
io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
at
io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
at
org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105)
at
org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
at
org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
at
org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
at
org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
at
io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
at
io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
at
io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)
at
io.undertow.server.Connectors.executeRootHandler(Connectors.java:326)
at
io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:812)
at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
6 years, 9 months
EventListener provider not firing new realm creation event
by Venky
Hello All,
I have implemented a custom EventListener provider by following
documentation
http://www.keycloak.org/docs/latest/server_development/index.html#_events
and github examples.
It is able to receive events except the realm event (new realm creation). I
would like to get the notification about realm event as well.
I could find any way to get the realm event notification nor any
documentation. I presume this is not implemented for the current event
listener.
Is there any other way to implement this ?
If anyone was able to achieve this, could you please give me some heads up
on the what needs to be done in-order to receive realm events.
Thank you.
Best Regards,
*Venky Koneru*
6 years, 9 months
Scalable architecture for multi-tenant (multi-resource) auth solution
by Yuriy Yunikov
We're evaluating two different architectures for setting up KeyCloak to
allow users to grant access to other users and third parties to tenants
within our system.
I'm looking for experienced feedback on these to try and save some time
with experimentation.
## First approach *Dynamic Client Registration*
In this approach we would have several static services (resource servers)
that orchestrate access and then each tenant is represented via a
dynamically registered client.
We would then have a static set of roles (permissions) which are assigned
between the user and client when they are granted access.
The total universe of roles is then fixed. The proliferation here is
between users and clients or resource-servers and clients.
## Second approach *Dynamic Role Generation*
In this approach we're considering dynamically generating roles
(permissions) for each tenant in the system. We're thinking of mirroring
AWS's URN style so that the permissions look something ssl_certificate_key
They follow the general structure `urn:service:tenant:permission`
E.g.
- urn:service-1:tenant-id-1:read
- urn:service-1:tenant-id-2:read
- urn:service-1:tenant-id-1:write
- urn:service-1:tenant-id-1:admin
- urn:service-2:tenant-id-1:read
This is very simple and powerful but we have the potential for the JWT to
proliferate in size as we connect a user or service to more and more
tenants.
I feel like the first approach is more standard but requires us to add more
complexity into the system since we have to deal with registering clients
and guiding the user through the auth delegation flow each time they want
to grant a server access to a client that they own.
The second approach is dead simple technically but less standards
compliant.
We've been evaluating Authorization API
<http://www.keycloak.org/docs/latest/authorization_services/index.html#_ov...>
(UMA) for this, but it's doesn't fit at the moment as there are number of
unresolved issues on KeyCloak which have to be addressed.
https://issues.jboss.org/browse/KEYCLOAK-4134
https://issues.jboss.org/browse/KEYCLOAK-6321
https://issues.jboss.org/browse/KEYCLOAK-5737
https://issues.jboss.org/browse/KEYCLOAK-6868
https://issues.jboss.org/browse/KEYCLOAK-6547
What do people tend to do in the real world to address this issue?
Our system has an unlimited number of tenants but realistically each user
is going to be associated with a few dozen at most. Third party
applications (which are all dynamic clients) will potentially be associated
with hundreds or thousands of other clients.
6 years, 9 months
Scalable architecture for multi-tenant (multi-resource) auth solution
by Yuriy Yunikov
We're evaluating two different architectures for setting up KeyCloak to
allow users to grant access to other users and third parties to tenants
within our system.
I'm looking for experienced feedback on these to try and save some time
with experimentation.
## First approach *Dynamic Client Registration*
In this approach we would have several static services (resource servers)
that orchestrate access and then each tenant is represented via a
dynamically registered client.
We would then have a static set of roles (permissions) which are assigned
between the user and client when they are granted access.
The total universe of roles is then fixed. The proliferation here is
between users and clients or resource-servers and clients.
## Second approach *Dynamic Role Generation*
In this approach we're considering dynamically generating roles
(permissions) for each tenant in the system. We're thinking of mirroring
AWS's URN style so that the permissions look something ssl_certificate_key
They follow the general structure `urn:service:tenant:permission`
E.g.
- urn:service-1:tenant-id-1:read
- urn:service-1:tenant-id-2:read
- urn:service-1:tenant-id-1:write
- urn:service-1:tenant-id-1:admin
- urn:service-2:tenant-id-1:read
This is very simple and powerful but we have the potential for the JWT to
proliferate in size as we connect a user or service to more and more
tenants.
I feel like the first approach is more standard but requires us to add more
complexity into the system since we have to deal with registering clients
and guiding the user through the auth delegation flow each time they want
to grant a server access to a client that they own.
The second approach is dead simple technically but less standards
compliant.
What do people tend to do in the real world to address this issue? Our
system has an unlimited number of tenants but realistically each user is
going to be associated with a few dozen at most. Third party applications
(which are all dynamic clients) will potentially be associated with
hundreds or thousands of other clients.
6 years, 9 months