Permissions: Slow/complex interactions
by Corentin Dupont
Hi guys,
I experience some performance issue on my API server using Keycloak.
After someone issue a GET on my API server, here is what happens:
- API server -> DB server: get requested resources
- API server -> Keycloak: get client token (to get resources)
- API server -> Keycloak: get resources (to complement DB server with
resource owner & visibility)
- API server -> Keycloak: get user token (to get permission)
- API server -> Keycloak: get permission (to filter resources)
At this point the filtered resources are returned.
But this process is quite slow. I noticed a call to KC can take up to 100ms.
The complete call on the API server can take up to 600ms on my laptop, in
localhost setting.
The delays become noticeable on my UI...
With a resource SPI strategy (if developed), it should be:
- API server -> DB server: get requested resources
- API server -> Keycloak: get user token (to get permission)
- API server -> Keycloak: get permission (to filter resources)
- Keycloak -> DB server: get resources
There is a little less requests. Additional gain is that resources are not
split between 2 databases.
I wonder if resources could be pushed during the permission request? Like a
"pushed claim".
This would be even more straightforward:
- API server -> DB server: get requested resources
- API server -> Keycloak: get user token (to get permission)
- API server -> Keycloak: get permission and push resources
Can this work?
6 years, 5 months
Upgrading 3.4.3 to 4.1
by Eivind Larsen
Hi Keycloak users!
After upgrading from 3.4.3 to 4.x, client templates are converted to client
scopes. The conversion of the templates themselves look correct.
Many clients had a default template set. After upgrade the corresponding
default template is not included in the default scopes of the client.
Is this intended? Do we have to manually update each client with the
default scope?
Is there a way to add the default scopes using the API?
Best regards,
Eivind Larsen
6 years, 5 months
SAML IDP seamless SSO
by Devlin, Martin
Hi,
I am setting up a SAML IDP. The user will already exist in Keycloak, I want
that user linked to the IDP.
What I want is for the user to be linked invisibly, without having to do
anything.
I have disabled the following in the First Broker Login flow:
```
first broker login/idp-review-profile set to DISABLED
first broker login/idp-confirm-link set to DISABLED
first broker login/idp-email-verification set to DISABLED
```
This gets rid of the dialogs to confirm profile and email verification.
But there's another setting that I can't disable: "
Username Password Form For Identity Provider Reauthentication"
So as it is the user has to authenticate against the IDP (which is what I
want) but then also against Keycloak (which I don;t want).
Thanks,
Martin
6 years, 5 months
How to login without username and password
by bejond
Hi developers,
I want to use mobile number and SMS text code to login to keycloak. But keycloak requires username and password to login. I copy Authentication of Browser, and remove "Username Password Form", and I add my own "Mobile OTP" SPI. When I open login page, it shows "Invalid username or password", the log says
" 21:00:03,638 WARN [org.keycloak.events] (default task-106) type=LOGIN_ERROR, realmId=test1, clientId=security-admin-console, userId=null, ipAddress=127.0.0.1, error=invalid_redirect_uri, redirect_uri=http://localhost:8080/auth/admin/master/console/
21:00:45,711 WARN [org.keycloak.services] (default task-107) KC-SERVICES0013: Failed authentication: org.keycloak.authentication.AuthenticationFlowException: authenticator: mobile-otp-authenticator"
Is there a way to remove "Username and Password Form" and login with my own SPI? Or can I override default "Username and Password Form" with my own logic? I mean "override" is: I write a new SPI without changing keycloak source code.
If I can't achieve this, I think I need to use other OAuth open source application and bind to keycloak as an Identity Provider and change the source of OAuth application to achieve my goal. It will be better if I can achieve my goal without another IdP.
Thanks in advance.
6 years, 5 months
Custom Email Validation
by zitrone@gmx-topmail.de
Hi,
is there a way to do a custom email validation befor changing/creating
an email via the admin rest api?
I already tried to use an eventlistener to catch the adminevents create
and update on an usertype, but i think they are fired after changing the
accountdata. I also did not find a way to canncel the event from inside
the listener.
Regards
6 years, 5 months
RequiredActionProviderEntity priority migration issue
by Frederick Ding
Another user flagged a similar issue earlier today:
http://lists.jboss.org/pipermail/keycloak-user/2018-August/014977.html .
The problem appears to have been introduced in
https://github.com/keycloak/keycloak/commit/7c0ca9aad2f552c63022010a1fc4b...
.
The relevant issue in the server log when trying to start up 4.2.0 after
migrating from 3.4.3 is this:
---
> 21:05:51,751 ERROR [org.jboss.msc.service.fail] (ServerService Thread
> Pool -- 58) MSC000001: Failed to start service
> jboss.undertow.deployment.default-server.default-host./auth:
> org.jboss.msc.service.StartException in service
> jboss.undertow.deployment.default-server.default-host./auth:
> java.lang.RuntimeException: RESTEASY003325: Failed to construct public
> org.keycloak.services.resources.KeycloakApplication(javax.servlet.ServletContext,org.jboss.resteasy.core.Dispatcher)
> at
> org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:84)
> at
> java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
> at java.util.concurrent.FutureTask.run(FutureTask.java:266)
> 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)
> at org.jboss.threads.JBossThread.run(JBossThread.java:320)
> Caused by: java.lang.RuntimeException: RESTEASY003325: Failed to
> construct public
> org.keycloak.services.resources.KeycloakApplication(javax.servlet.ServletContext,org.jboss.resteasy.core.Dispatcher)
> at
> org.jboss.resteasy.core.ConstructorInjectorImpl.construct(ConstructorInjectorImpl.java:162)
> at
> org.jboss.resteasy.spi.ResteasyProviderFactory.createProviderInstance(ResteasyProviderFactory.java:2298)
> at
> org.jboss.resteasy.spi.ResteasyDeployment.createApplication(ResteasyDeployment.java:340)
> at
> org.jboss.resteasy.spi.ResteasyDeployment.start(ResteasyDeployment.java:253)
> at
> org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.init(ServletContainerDispatcher.java:120)
> at
> org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.init(HttpServletDispatcher.java:36)
> at
> io.undertow.servlet.core.LifecyleInterceptorInvocation.proceed(LifecyleInterceptorInvocation.java:117)
> at
> org.wildfly.extension.undertow.security.RunAsLifecycleInterceptor.init(RunAsLifecycleInterceptor.java:78)
> at
> io.undertow.servlet.core.LifecyleInterceptorInvocation.proceed(LifecyleInterceptorInvocation.java:103)
> at
> io.undertow.servlet.core.ManagedServlet$DefaultInstanceStrategy.start(ManagedServlet.java:250)
> at
> io.undertow.servlet.core.ManagedServlet.createServlet(ManagedServlet.java:133)
> at
> io.undertow.servlet.core.DeploymentManagerImpl$2.call(DeploymentManagerImpl.java:565)
> at
> io.undertow.servlet.core.DeploymentManagerImpl$2.call(DeploymentManagerImpl.java:536)
> at
> io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:42)
> 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.core.DeploymentManagerImpl.start(DeploymentManagerImpl.java:578)
> at
> org.wildfly.extension.undertow.deployment.UndertowDeploymentService.startContext(UndertowDeploymentService.java:100)
> at
> org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:81)
> ... 6 more
> Caused by: org.hibernate.PropertyAccessException: Null value was
> assigned to a property [class
> org.keycloak.models.jpa.entities.RequiredActionProviderEntity.priority]
> of primitive type setter of
> org.keycloak.models.jpa.entities.RequiredActionProviderEntity.priority
> at
> org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:44)
> at
> org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:713)
> at
> org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:207)
> at
> org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:4692)
> at
> org.hibernate.engine.internal.TwoPhaseLoad.doInitializeEntity(TwoPhaseLoad.java:183)
> at
> org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:125)
> at
> org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.performTwoPhaseLoad(AbstractRowReader.java:238)
> at
> org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishUp(AbstractRowReader.java:209)
> at
> org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:133)
> at
> org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:122)
> at
> org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:86)
> at
> org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer.initialize(AbstractLoadPlanBasedCollectionInitializer.java:88)
> at
> org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:688)
> at
> org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:75)
> at
> org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:2004)
> at
> org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:567)
> at
> org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:249)
> at
> org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:563)
> at
> org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:132)
> at
> org.hibernate.collection.internal.AbstractPersistentCollection$1.doWork(AbstractPersistentCollection.java:161)
> at
> org.hibernate.collection.internal.AbstractPersistentCollection$1.doWork(AbstractPersistentCollection.java:146)
> at
> org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:249)
> at
> org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:145)
> at
> org.hibernate.collection.internal.PersistentBag.isEmpty(PersistentBag.java:266)
> at
> org.keycloak.models.jpa.RealmAdapter.getRequiredActionProviders(RealmAdapter.java:1726)
> at
> org.keycloak.models.cache.infinispan.entities.CachedRealm.<init>(CachedRealm.java:256)
> at
> org.keycloak.models.cache.infinispan.RealmCacheSession.getRealm(RealmCacheSession.java:399)
> at
> org.keycloak.models.jpa.JpaRealmProvider.getRealms(JpaRealmProvider.java:102)
> at
> org.keycloak.models.cache.infinispan.RealmCacheSession.getRealms(RealmCacheSession.java:459)
> at
> org.keycloak.migration.migrators.MigrateTo3_4_1.migrate(MigrateTo3_4_1.java:40)
> at
> org.keycloak.migration.MigrationModelManager.migrate(MigrationModelManager.java:96)
> at
> org.keycloak.services.resources.KeycloakApplication.migrateModel(KeycloakApplication.java:245)
> at
> org.keycloak.services.resources.KeycloakApplication.migrateAndBootstrap(KeycloakApplication.java:186)
> at
> org.keycloak.services.resources.KeycloakApplication$1.run(KeycloakApplication.java:145)
> at
> org.keycloak.models.utils.KeycloakModelUtils.runJobInTransaction(KeycloakModelUtils.java:227)
> at
> org.keycloak.services.resources.KeycloakApplication.<init>(KeycloakApplication.java:136)
> 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.resteasy.core.ConstructorInjectorImpl.construct(ConstructorInjectorImpl.java:150)
> ... 28 more
> Caused by: java.lang.IllegalArgumentException: Can not set int field
> org.keycloak.models.jpa.entities.RequiredActionProviderEntity.priority
> to null value
> at
> sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
> at
> sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
> at
> sun.reflect.UnsafeIntegerFieldAccessorImpl.set(UnsafeIntegerFieldAccessorImpl.java:80)
> at java.lang.reflect.Field.set(Field.java:764)
> at
> org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:38)
> ... 68 more
---
Based on the SQL migration that was generated, it looks like the
database migration merely added a column without setting a value in that
column:
---
> -- Changeset
> META-INF/jpa-changelog-4.2.0.xml::4.2.0-KEYCLOAK-6313::wadahiro@gmail.com
> ALTER TABLE public.REQUIRED_ACTION_PROVIDER ADD PRIORITY INT;
>
> INSERT INTO public.databasechangelog (ID, AUTHOR, FILENAME,
> DATEEXECUTED, ORDEREXECUTED, MD5SUM, DESCRIPTION, COMMENTS, EXECTYPE,
> CONTEXTS, LABELS, LIQUIBASE, DEPLOYMENT_ID) VALUES
> ('4.2.0-KEYCLOAK-6313', 'wadahiro(a)gmail.com',
> 'META-INF/jpa-changelog-4.2.0.xml', NOW(), 67,
> '7:14d407c35bc4fe1976867756bcea0c36', 'addColumn
> tableName=REQUIRED_ACTION_PROVIDER', '', 'EXECUTED', NULL, NULL,
> '3.5.4', '3171859373');
---
When starting up, the migrator
(https://github.com/keycloak/keycloak/blob/7c0ca9aad2f552c63022010a1fc4bdb...)
that sets the default priority to 10 hasn't yet run. Meanwhile, the new
database column contains a null field for each row, which causes the
initialization to fail on server startup.
Has anyone else experienced this?
Frederick
6 years, 5 months
enable/disable permissions via the Java API
by Graser Leon (INST-CSS/BSV-OS)
Hi all,
for a project we currently try to automate out Keycloak setup programmatically using the Java API. So far I figured out most of the requirements except for one feature. How can I enable/disable the permissions of an object such as a group or a role? In the web UI they have a tab called "Permissions" with a boolean switch to enable/disable them and if I have a look at the HTTP calls I find a PUT call to my group similar to <url>/auth/admin/realms/<realm-name>/groups/<id>/management/permission with a payload of { enabled: true }. As of now I extended the org.keycloak.admin.client.resource.GroupResource interface to make it happen using RESTeasy. Is there an already existing way in the Java API to accomplish that?
Thanks in advance for any ideas.
Regards,
Leon
6 years, 5 months
Hot deploy in domain mode
by Yegui Cai
Hi.
I know in standalone mode, hot deploy can be done by putting the jar file
under standalone/deployments. How can I do hot deploy in domain mode?
Thanks!
Yegui
6 years, 5 months
Dynamically branded login?
by Craig Setera
We build and host a multitenant application that is currently using
homegrown authentication and authorization (using Picketlink). We are
considering a move to Keycloak. My preference would be to use the login
flows that are built in to Keycloak rather than building our own, however
that is dependent on whether we can properly brand those login flows on a
per-customer basis in some dynamic way.
In looking at the theme SPI support, it appears to be mostly targeted to
supporting mulitple "static" themes. Is it possible to make a theme that
is dynamic based on, for example, a query parameter? Are there any
examples anywhere on how that might be possible? Would Keycloak carry
through query parameters if they were provided when launching the login
flow?
Thanks,
Craig
6 years, 5 months
kcadm - adding a protocol-mapper
by Jamie McDowell
Hi,
I am trying to add a client protocol-mapper however when i try and run this i get a HTTP error - 500 Internal Server Error
opt/jboss/keycloak/bin/kcadm.sh create \clients/<id>/protocol-mappers/models \-r demorealm \-s protocol=openid-connect \-s protocolMapper=oidc-usermodel-realm-mapper \-s consentRequired=false \-s config.claim.name=group_membership \-s config.jsonType.label=String \-s config.id.token.claim=true \-s config.access.token.claim=true \-s config.userinfo.token.claim=true \-s config.multivalued=true \-s name=Realm \
I can confirm that kcadm works as i have been able to create groups, LDAP mappers, realms etc...
In the server.log i can see the below error when i run the above
ERROR [org.keycloak.services.error.KeycloakErrorHandler] (default task-109) Uncaught server error: com.fasterxml.jackson.databind.JsonMappingException: Can notat [Source: io.undertow.servlet.spec.ServletInputStreamImpl@55dee6f8; line: 1, column: 119] (through reference chain: org.keycloak.representations.idm.ProtocolMapperRepresentation["co at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270) at com.fasterxml.jackson.databind.DeserializationContext.reportMappingException(DeserializationContext.java:1234) at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1122) at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1075) at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:60)
Appreciate if anyone can advise on this (keycloak version is 3.4.3)
Thanks Jamie
6 years, 5 months