AWS SSO SCIM Integration Error Responses (Bad Request) #22
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Thanks for all your great work with this scim keycloak integration.
I am testing the SCIM integration with AWS IAM identity center, and I am getting some errors when running the scim:
My config:
I have tested the endpoints and credentials using this golang code, and works as expected.
Is there any option to add debug? I would like to get more details on the Bad Request error.
I am using the last snapshot version.
Thanks in advance!!
changed title from AWS SSO SCIM to AWS SSO SCIM{+ Integration Error Responses (Bad Request)+}
After some debugging seems that the cause is that AWS does not support /schema and /resourcetype endpoints, which are required by scim client. AWS Limitations.
In another keycloak scim project, seems that they "solved" this issue, by defining these endpoints when provider does not have them. commit commit.
If I am not wrong, this means that this "scenario" should be implemented in com.unboundid.scim2 right?
I will create an issue on the com.unboundid.scim2 github repo.
Thanks again!
Hey !
Sorry for now there isn't an option for debugging.
I'm not sure the source of the problem is AWS Limitions because we are implementing a Rocket.Chat SCIM Service Provider which works with this Keycloak extension, although we have only implemented the
/Users
&/Groups
endpoints.From you're logs, it's possible that AWS returns and error that is not in an SCIM format.
What operation did you try ? Sync is quite complex, maybe try creating a user for a start.
Thanks for the response.
After some more digging,the issue is not related to the missing /Schema and /Resourcetypes endpoints in AWS.
If fails, because AWS does not support some attributes defined on the scim client UserResource class.
By default, scim client sends all attributes, and these are not supported by AWS:
I have simulated the post done by the scim client with postman, and when the above ones are on the json data, AWS returns error:
Do you think that it would be possible somehow, to make the scim client not to send these "offending" fields?
Unfortunately
com.unboundid.scim2
doesn't seem to omit empty fields... If you find a way to omit empty fields, I'll implement it. But thegroups
might still be an issue.The problem is on AWS side. This should not throw an error even if it does nothing in the backend. The best solution would to be to pressure AWS to be compliant with the RFCs. Or someone needs to build a SCIM compliant proxy.
It's quite sad that giants are not willing to implement correctly simple specs like SCIM to allow true interoperability. (I heard that Azure have issues too).
Our goal is to bring SCIM to the FOSS community, we will obviously not deviate from the SCIM specs to ensure compatibility with proprietary solutions.
Anyway I hope you find a solution, I'll be curious to ear it if you do.
I'm closing the issue for now but feel free to re-open it.
Thanks again for your project and dedication.
As you say, it is sad that giants are not SCIM compliants.
I was able to create users with java scim2 client, but I need to define a new userResource definition, excluding the offending fields.
I could not find a way to omit null fields using the com.unboundid.scim2 client sdk.
Congratulations for your work!
Any chance to change from com.unboundid.scim2 to Captain-P-Goldfish/SCIM-SDK ?
Goldfish implementation seems to be more flexible, and it is on continuous development.
I am going to create a fork to use Goldfish. This will probably enable other "bad scim" implementations as AWS.
I don't plan to work on this personally. But, if the license is compatible, I'm open to a PR.
I was able to rewrite this extension to use Goldfish-SDK, and seems to work quite well.
However this is not enough to make it work with the bad SCIM implementation of AWS.
AWS does not support SCIM replace operations,and group membership management is a bit more complex. I am trying to use patch operations to achieve this.
If I was able to make it work, I could add an option in the extension to use patch or replace method. Would this be accepted or reviewed?
Thanks again.
Nice ! Thanks for investigating this.
We don't require PATCH support for our use case but, I'll be happy to review a PR. I guess we could default to PATCH when the
/ServiceProviderConfig
says it's supported and fallback on REPLACE.Here is my branch to switch to Goldfish-SDK, Whenever you have a slot, could you please review it?
I am not creating a merge request yet, because I would like to know your opinion.
I am also working in a further update, to allow to use patchUser and patchGroup instead of putUser & putGroup API. It is working quite well, but needs some xtra work, and maybe some suggestions from your side.
Off topic question, is there any plan to work on current issues (adding nested groups,pagination,,,)
Thanks
Thanks ! Could you open an MR in draft mode ? I think It will be easier for reviewing and chatting.
Seems pretty good after a quick look. But I don't have the time to properly review and test it this week.
Yes we have some plan. We've actually been granted funding from NLnet, but it takes to get things started. And we still have to take care of core business. Hopefully, during Q3 we will focus again on SCIM.
Great news!
https://lab.libreho.st/libre.sh/scim/keycloak-scim/-/merge_requests/2
It is draft, and I am waiting for Captain-Goldfish SDK to do a new release of the SDK which includes some needed features. We can discuss about it on the PR.
Thanks
I'm trying to use your implementation and get this error while creating a user
2023-07-06 12:31:58,717 INFO [sh.libre.scim.event.ScimEventListenerProvider] (executor-thread-1) f4592af1-b0f7-4edd-a324-711df2280224 CREATE 2023-07-06 12:31:58,721 INFO [sh.libre.scim.core.ScimDispatcher] (executor-thread-1) 21c2335c-f967-4cd0-968b-0e9291ef6ecb scim scim org.keycloak.storage.UserStorageProvider 2023-07-06 12:31:58,722 ERROR [org.keycloak.services] (executor-thread-1) KC-SERVICES0085: Failed to send type to sh.libre.scim.event.ScimEventListenerProvider@502b56d6: java.lang.NoClassDefFoundError: de/captaingoldfish/scim/sdk/common/exceptions/ResponseException at sh.libre.scim.core.ScimDispatcher.runOne(ScimDispatcher.java:32) at sh.libre.scim.core.ScimDispatcher.lambda$run$1(ScimDispatcher.java:27) at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183) at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179) at java.base/java.util.HashMap$ValueSpliterator.forEachRemaining(HashMap.java:1779) at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150) at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173) at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596) at sh.libre.scim.core.ScimDispatcher.run(ScimDispatcher.java:27) at sh.libre.scim.event.ScimEventListenerProvider.onEvent(ScimEventListenerProvider.java:68) at org.keycloak.services.resources.admin.AdminEventBuilder.send(AdminEventBuilder.java:251) at org.keycloak.services.resources.admin.AdminEventBuilder.success(AdminEventBuilder.java:233) at org.keycloak.services.resources.admin.UsersResource.createUser(UsersResource.java:164) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:170) at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:130) at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:660) at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:524) at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$2(ResourceMethodInvoker.java:474) at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364) at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:476) at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:434) at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:192) at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:152) at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:183) at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:152) at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:183) at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:141) at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:32) at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:492) at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:261) at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:161) at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364) at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:164) at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:247) at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73) at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:151) at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.handle(VertxRequestHandler.java:82) at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.handle(VertxRequestHandler.java:42) at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1212) at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:163) at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:141) at io.quarkus.vertx.http.runtime.StaticResourcesRecorder$2.handle(StaticResourcesRecorder.java:67) at io.quarkus.vertx.http.runtime.StaticResourcesRecorder$2.handle(StaticResourcesRecorder.java:55) at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1212) at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:163) at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:141) at io.quarkus.vertx.http.runtime.VertxHttpRecorder$5.handle(VertxHttpRecorder.java:380) at io.quarkus.vertx.http.runtime.VertxHttpRecorder$5.handle(VertxHttpRecorder.java:358) at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1212) at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:163) at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:141) at org.keycloak.quarkus.runtime.integration.web.QuarkusRequestFilter.lambda$createBlockingHandler$1(QuarkusRequestFilter.java:71) at io.vertx.core.impl.ContextImpl.lambda$null$0(ContextImpl.java:159) at io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:100) at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$1(ContextImpl.java:157) at io.quarkus.vertx.core.runtime.VertxCoreRecorder$13.runWith(VertxCoreRecorder.java:543) at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449) at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478) at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29) at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.base/java.lang.Thread.run(Thread.java:833) Caused by: java.lang.ClassNotFoundException: de.captaingoldfish.scim.sdk.common.exceptions.ResponseException at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) at io.quarkus.bootstrap.runner.RunnerClassLoader.loadClass(RunnerClassLoader.java:107) at io.quarkus.bootstrap.runner.RunnerClassLoader.loadClass(RunnerClassLoader.java:57) ... 69 more