Custom federation - webservice
by Jorge M.
I'm developing a custom federation that communicates with my user
repository via webservices.
Probably this is a very strange scenario for a federation but that's the
unique way that I have to communicate with the repository.
My problem is that, as the webservices only exposes methods such as
createUser and updateUser, I'm having problems with registrations and user
profile updates because I'm not being able to do atomic calls to the
webservice methods, with all the information that I need.
As far as I know, from the properties file example and from the ldap
federation source (probably I'm missing something) it seems that the
federation api is intended to update and sync attribute by attribute
(Keycloak <-> Federation).
Am i wrong? Do you suggest another approach? Should I give up from having a
federation that uses a webservice?
Thank you.
8 years, 3 months
Google redirect url
by Thomas Raehalme
Hi!
Google doesn't accept wildcards in redirect URLs. This means I have to
create a separate client for every realm in the Google console.
Any chance we could have a shared redirect URL across realms? Maybe as an
option in the federation configuration? Then I could share the same Google
config for each tenant.
Best regards,
Thomas
8 years, 3 months
module re-org
by Bill Burke
I can't find the original email on this, but we need to do this for
1.9. I can start doing it one module at a time:
Common:
keycloak-common
keycloak-common-saml
keycloak-common-oidc
Libraries server:
keycloak-server-spi - all SPI interfaces and common code
keycloak-server-saml - all saml server code, broker and protocol plugins
keycloak-server-oidc - all oidc code, broker and protocol plugins
keycloak-server-impl - everything
Libraries client:
This structure is not going to change as it is already broken out the
way it should be to gain re-use between servlet containers.
Questions:
Do we care about breaking out server side OIDC and SAML?
--
Bill Burke
JBoss, a division of Red Hat
http://bill.burkecentral.com
8 years, 3 months
UserFederationProvider with non-trivial configuration
by Josh Cain
Hi all,
I've got a UserFederationProvider that needs 6-8 configuration elements, to
include enumerated types and even a couple of files. I'd like to keep the
configuration of this provider in the Keycloak admin console, but am not
sure how to do so.
I've read through the themes documentation
<http://keycloak.github.io/docs/userguide/keycloak-server/html/themes.html>,
but I have not been able to find a suitable solution. I thought of just
dropping a new partial in there to handle more straightforward
configuration items like enumerated types, but couldn't find a way to do so
without having to override the entire app.js. What's more, I was not
certain if Keycloak was already set up to handle something like a File
object in the REST/DB backend.
I suppose my question boils down to "How can I integrate enumerated and
file type configuration options for my UserFederationProvider into the
Keycloak administration system?" Any help would be much appreciated -
thanks!
Josh Cain | Software Applications Engineer
*Identity and Access Management*
*Red Hat*
+1 843-737-1735
8 years, 3 months
Upgrading to Jackson2
by Stian Thorgersen
Now that we no longer need to support EAP 6.4 on the server side we can
upgrade to Jackson2, which is supposed to be significantly faster than
Jackson.
Question - Can we require Jackson2 for adapters as well? Or should we make
JSON serialization support on the adapter side pluggable somehow? Or should
we support both Jackson and Jackson2 on the adapter side.
8 years, 3 months
Possible defect when using SAML Client Java Servlet Filter
by Akshay Kini
Hi Folks,
I was using the filter: org.keycloak.adapters.saml.servlet.SamlFilter in
our application.
I got the following exception in the logs:
ERROR
[org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/].[AppName]]
Servlet.service() for servlet NasDefault threw exception:
java.lang.RuntimeException: This method is not supported in a restored
authenticated request
at
org.keycloak.adapters.servlet.FilterSessionStore$1.getDateHeader(FilterSessionStore.java:178)
[:1.7.0.CR1]
at
org.apache.catalina.servlets.DefaultServlet.checkIfModifiedSince(DefaultServlet.java:1731)
[:]
at
org.apache.catalina.servlets.DefaultServlet.checkIfHeaders(DefaultServlet.java:608)
[:]
at
org.apache.catalina.servlets.DefaultServlet.serveResource(DefaultServlet.java:714)
[:]
at
org.apache.catalina.servlets.DefaultServlet.doGet(DefaultServlet.java:368)
[:]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:734)
[:1.0.0.Final]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
[:1.0.0.Final]
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:324)
[:]
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:242)
[:]
... (trimmed)
...
at
org.keycloak.adapters.saml.servlet.SamlFilter.doFilter(SamlFilter.java:125)
[:1.7.0.CR1]
...(trimmed)
...
etc.
After looking into the Keycloak code base, I saw the method (implemented in
an anonymous class):
javax.servlet.http.HttpServletRequestWrapper#getDateHeader
inside the class: org.keycloak.adapters.servlet.FilterSessionStore
The code was:
@Override
public long getDateHeader(String name) {
if (!needRequestRestore) return super.getDateHeader(name);
throw new RuntimeException("This method is not supported in a
restored authenticated request");
}
Looks like a particular case isn't implemented yet, and an exception is
thrown.
After looking into the JEE API at:
http://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServletRequest...
It is required that any class implementing HttpServletRequest
getDateHeader() method, return a -1 in case it cannot get the required
header.
Hence, I suggest that instead of throwing an exception to handle the error
condition, we should return -1.
*Any help appreciated.*
Thanks,
Regards,
Akshay
8 years, 3 months
Mvn artifact: org.keycloak:keycloak-admin-client
by Andrew Zenk
I'm writing some code that will hook into the keycloak admin rest api. I
noticed that this client module exists under the integration tree in the
repo, though it doesn't seem to align with the current rest api 100%. Is
it something that is currently being maintained?
--
Andrew Zenk, EIT
Polar Geospatial Center
University of Minnesota
Office: (612) 625-0872
Cell: (612) 414-9617
8 years, 3 months
Exception in 1.7.0 during login using federation provider
by Scott Rossillo
Hey,
I’m trying to publish an example of how to do on demand user migration using a federation provider. It’s a modified version of what we use on an older Keycloak version. The error I’m getting (with H2, Keycloak 1.7.0 out-of-the-box) is below.
At the time the exception is thrown, Kecyloak hasn’t attempted to validate credentials yet.
It has only called these methods:
- UserModel getUserByUsername(RealmModel realm, String username);
- public boolean isValid(RealmModel realm, UserModel local);
After calling session.users().addUser() am I supposed to release something?
Thanks,
Scott
-------
Methods:
@Override
public UserModel getUserByUsername(RealmModel realm, String username) { {
String username = rawUsername.toLowerCase().trim();
FederatedUserModel remoteUser = federatedUserService.getUserDetails(username);
LOG.infof("Creating user model for: %s", username);
UserModel userModel = session.users().addUser(realm, username);
if (!username.equals(remoteUser.getEmail())) {
throw new IllegalStateException(String.format("Local and remote users differ: [%s != %s]", username, remoteUser.getUsername()));
}
userModel.setFederationLink(model.getId());
userModel.setEnabled(remoteUser.isEnabled());
userModel.setEmail(username);
userModel.setEmailVerified(remoteUser.isEmailVerified());
userModel.setFirstName(remoteUser.getFirstName());
userModel.setLastName(remoteUser.getLastName());
if (remoteUser.getAttributes() != null) {
Map<String, List<String>> attributes = remoteUser.getAttributes();
for (String attributeName : attributes.keySet())
userModel.setAttribute(attributeName, attributes.get(attributeName));
}
if (remoteUser.getRoles() != null) {
for (String role : remoteUser.getRoles()) {
RoleModel roleModel = realm.getRole(role);
if (roleModel != null) {
userModel.grantRole(roleModel);
LOG.infof("Granted user %s, role %s", username, role);
}
}
}
return userModel;
}
@Override
public boolean isValid(RealmModel realm, UserModel local)
{
Response response = federatedUserService.validateUserExists(local.getUsername());
return HttpStatus.SC_ACCEPTED == response.getStatus();
}
Exception:
2:13:51,497 WARN [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-88) SQL Error: 50200, SQLState: HYT00
12:13:51,498 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-88) Timeout trying to lock table "USER_ENTITY"; SQL statement:
select userentity0_.ID as ID1_46_, userentity0_.CREATED_TIMESTAMP as CREATED_2_46_, userentity0_.EMAIL as EMAIL3_46_, userentity0_.EMAIL_CONSTRAINT as EMAIL_CO4_46_, userentity0_.EMAIL_VERIFIED as EMAIL_VE5_46_, userentity0_.ENABLED as ENABLED6_46_, userentity0_.FEDERATION_LINK as FEDERATI7_46_, userentity0_.FIRST_NAME as FIRST_NA8_46_, userentity0_.LAST_NAME as LAST_NAM9_46_, userentity0_.REALM_ID as REALM_I10_46_, userentity0_.SERVICE_ACCOUNT_CLIENT_LINK as SERVICE11_46_, userentity0_.TOTP as TOTP12_46_, userentity0_.USERNAME as USERNAM13_46_ from USER_ENTITY userentity0_ where userentity0_.ID=? and userentity0_.REALM_ID=? [50200-173]
12:13:51,499 ERROR [org.keycloak.authentication.AuthenticationProcessor] (default task-88) failed authentication: javax.persistence.PessimisticLockException: could not extract ResultSet
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.wrapLockException(AbstractEntityManagerImpl.java:1831)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1720)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:458)
at org.keycloak.models.jpa.JpaUserProvider.getUserById(JpaUserProvider.java:260)
at org.keycloak.models.cache.infinispan.DefaultCacheUserProvider.getUserById(DefaultCacheUserProvider.java:122)
at org.keycloak.models.UserFederationManager.deleteInvalidUser(UserFederationManager.java:112)
at org.keycloak.models.UserFederationManager.validateUser(UserFederationManager.java:100)
at org.keycloak.models.UserFederationManager.validCredentials(UserFederationManager.java:409)
at org.keycloak.authentication.authenticators.browser.AbstractUsernameFormAuthenticator.validatePassword(AbstractUsernameFormAuthenticator.java:152)
at org.keycloak.authentication.authenticators.browser.AbstractUsernameFormAuthenticator.validateUserAndPassword(AbstractUsernameFormAuthenticator.java:128)
at org.keycloak.authentication.authenticators.browser.UsernamePasswordForm.validateForm(UsernamePasswordForm.java:41)
at org.keycloak.authentication.authenticators.browser.UsernamePasswordForm.action(UsernamePasswordForm.java:34)
at org.keycloak.authentication.DefaultAuthenticationFlow.processAction(DefaultAuthenticationFlow.java:65)
at org.keycloak.authentication.DefaultAuthenticationFlow.processAction(DefaultAuthenticationFlow.java:57)
at org.keycloak.authentication.AuthenticationProcessor.authenticationAction(AuthenticationProcessor.java:744)
at org.keycloak.services.resources.LoginActionsService.processFlow(LoginActionsService.java:299)
at org.keycloak.services.resources.LoginActionsService.processAuthentication(LoginActionsService.java:280)
at org.keycloak.services.resources.LoginActionsService.authenticateForm(LoginActionsService.java:326)
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:103)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:356)
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.KeycloakSessionServletFilter.doFilter(KeycloakSessionServletFilter.java:61)
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(ServletConfidentialityConstraintHandler.java:64)
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58)
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java: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:282)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:261)
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.hibernate.PessimisticLockException: could not extract ResultSet
at org.hibernate.dialect.H2Dialect$2.convert(H2Dialect.java:342)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:91)
at org.hibernate.loader.Loader.getResultSet(Loader.java:2066)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1863)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1839)
at org.hibernate.loader.Loader.doQuery(Loader.java:910)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:355)
at org.hibernate.loader.Loader.doList(Loader.java:2554)
at org.hibernate.loader.Loader.doList(Loader.java:2540)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2370)
at org.hibernate.loader.Loader.list(Loader.java:2365)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:497)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:387)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:236)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1300)
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:103)
at org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:573)
at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:449)
... 62 more
Caused by: org.h2.jdbc.JdbcSQLException: Timeout trying to lock table "USER_ENTITY"; SQL statement:
select userentity0_.ID as ID1_46_, userentity0_.CREATED_TIMESTAMP as CREATED_2_46_, userentity0_.EMAIL as EMAIL3_46_, userentity0_.EMAIL_CONSTRAINT as EMAIL_CO4_46_, userentity0_.EMAIL_VERIFIED as EMAIL_VE5_46_, userentity0_.ENABLED as ENABLED6_46_, userentity0_.FEDERATION_LINK as FEDERATI7_46_, userentity0_.FIRST_NAME as FIRST_NA8_46_, userentity0_.LAST_NAME as LAST_NAM9_46_, userentity0_.REALM_ID as REALM_I10_46_, userentity0_.SERVICE_ACCOUNT_CLIENT_LINK as SERVICE11_46_, userentity0_.TOTP as TOTP12_46_, userentity0_.USERNAME as USERNAM13_46_ from USER_ENTITY userentity0_ where userentity0_.ID=? and userentity0_.REALM_ID=? [50200-173]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:331)
at org.h2.message.DbException.get(DbException.java:171)
at org.h2.message.DbException.get(DbException.java:148)
at org.h2.table.RegularTable.doLock(RegularTable.java:521)
at org.h2.table.RegularTable.lock(RegularTable.java:455)
at org.h2.table.TableFilter.lock(TableFilter.java:145)
at org.h2.command.dml.Select.queryWithoutCache(Select.java:611)
at org.h2.command.dml.Query.query(Query.java:314)
at org.h2.command.dml.Query.query(Query.java:284)
at org.h2.command.dml.Query.query(Query.java:36)
at org.h2.command.CommandContainer.query(CommandContainer.java:91)
at org.h2.command.Command.executeQuery(Command.java:195)
at org.h2.jdbc.JdbcPreparedStatement.executeQuery(JdbcPreparedStatement.java:106)
at org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.executeQuery(WrappedPreparedStatement.java:504)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:82)
... 78 more
8 years, 3 months
Why isn't the configuration/providers directory on my classpath when attempting to load a file?
by Josh Cain
Hi all,
I'm in the process of writing an SPI for a federation provider that relies
on a third party library, and the library in turn uses a number of files.
I placed my SPI .jar, the third party library .jar, as well as its required
files in the keycloak-1.7.0.Final/standalone/configuration/providers
directory. However, when the third party library attempts to locate its
required files on the classpath, it cannot find them.
Just for a sanity check, I've placed the files places like the sun/jdk/main
module on the AS, and observed that the files were picked up properly since
that particular folder was on the classpath.
Can anyone help me understand why those files are not being picked up as
classpath resources? Does the configuration/providers directory not get
added to the classpath?
Just FYI, I poked through the library a bit, and it doesn't seem to be
doing anything strange. It winds up doing the equivalent of:
Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath);
Josh Cain | Software Applications Engineer
*Identity and Access Management*
*Red Hat*
+1 843-737-1735
8 years, 3 months