gravitee-io / issues

Gravitee.io - API Platform - Issues
64 stars 26 forks source link

[idp] [saml] Error when saving user attributes #7336

Open ecatrain opened 2 years ago

ecatrain commented 2 years ago

:collision: Describe the bug

External SAML 2.0 IdPs often send the user attributes with the name containing the "." symbol. For example : <Attribute Name="http://schemas.microsoft.com/identity/claims/displayname"><AttributeValue>SOME_VALUE</AttributeValue></Attribute>

:rainbow: Expected behaviour

These attributes are correctly processed and can be retrieved via user claims : {#context.attributes['user']['claims']}

Current behaviour

Gravitee AM gateway throws an error and the authentication fails :

Unable to authenticate social provider io.gravitee.am.service.exception.TechnicalManagementException: An error occurs while trying to create a user at io.gravitee.am.service.impl.AbstractUserService.lambda$create$11(AbstractUserService.java:213) at io.reactivex.internal.operators.single.SingleResumeNext$ResumeMainSingleObserver.onError(SingleResumeNext.java:73) at io.reactivex.internal.operators.single.SingleFlatMap$SingleFlatMapCallback.onError(SingleFlatMap.java:90) at io.reactivex.internal.observers.ResumeSingleObserver.onError(ResumeSingleObserver.java:51) at io.reactivex.internal.operators.single.SingleFlatMap$SingleFlatMapCallback.onError(SingleFlatMap.java:90) at io.reactivex.internal.operators.single.SingleFromPublisher$ToSingleObserver.onError(SingleFromPublisher.java:87) at reactor.core.publisher.StrictSubscriber.onError(StrictSubscriber.java:106) at reactor.core.publisher.FluxMap$MapSubscriber.onError(FluxMap.java:126) at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:100) at reactor.core.publisher.Operators.error(Operators.java:196) at reactor.core.publisher.MonoError.subscribe(MonoError.java:52) at reactor.core.publisher.Mono.subscribe(Mono.java:4252) at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:97) at reactor.core.publisher.MonoFlatMap$FlatMapMain.secondError(MonoFlatMap.java:185) at reactor.core.publisher.MonoFlatMap$FlatMapInner.onError(MonoFlatMap.java:251) at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onError(MonoPeekTerminal.java:251) at reactor.core.publisher.MonoCreate$DefaultMonoSink.error(MonoCreate.java:185) at com.mongodb.reactivestreams.client.internal.MongoOperationPublisher.lambda$sinkToCallback$30(MongoOperationPublisher.java:546) at com.mongodb.reactivestreams.client.internal.OperationExecutorImpl.lambda$execute$8(OperationExecutorImpl.java:97) at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:48) at com.mongodb.internal.operation.OperationHelper$ConnectionReleasingWrappedCallback.onResult(OperationHelper.java:552) at com.mongodb.internal.operation.MixedBulkWriteOperation$6.onResult(MixedBulkWriteOperation.java:489) at com.mongodb.internal.operation.MixedBulkWriteOperation$6.onResult(MixedBulkWriteOperation.java:476) at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:48) at com.mongodb.internal.connection.DefaultServer$DefaultServerProtocolExecutor$2.onResult(DefaultServer.java:283) at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:48) at com.mongodb.internal.connection.CommandProtocolImpl$1.onResult(CommandProtocolImpl.java:82) at com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection$2.onResult(DefaultConnectionPool.java:530) at com.mongodb.internal.connection.UsageTrackingInternalConnection$2.onResult(UsageTrackingInternalConnection.java:142) at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:48) at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceiveAsync(InternalStreamConnection.java:415) at com.mongodb.internal.connection.UsageTrackingInternalConnection.sendAndReceiveAsync(UsageTrackingInternalConnection.java:145) at com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection.sendAndReceiveAsync(DefaultConnectionPool.java:527) at com.mongodb.internal.connection.CommandProtocolImpl.executeAsync(CommandProtocolImpl.java:77) at com.mongodb.internal.connection.DefaultServer$DefaultServerProtocolExecutor.executeAsync(DefaultServer.java:271) at com.mongodb.internal.connection.DefaultServerConnection.executeProtocolAsync(DefaultServerConnection.java:218) at com.mongodb.internal.connection.DefaultServerConnection.commandAsync(DefaultServerConnection.java:135) at com.mongodb.internal.operation.MixedBulkWriteOperation.executeCommandAsync(MixedBulkWriteOperation.java:440) at com.mongodb.internal.operation.MixedBulkWriteOperation.executeBatchesAsync(MixedBulkWriteOperation.java:348) at com.mongodb.internal.operation.MixedBulkWriteOperation.access$1000(MixedBulkWriteOperation.java:76) at com.mongodb.internal.operation.MixedBulkWriteOperation$2$1.call(MixedBulkWriteOperation.java:228) at com.mongodb.internal.operation.OperationHelper.validateWriteRequests(OperationHelper.java:270) at com.mongodb.internal.operation.MixedBulkWriteOperation$2.call(MixedBulkWriteOperation.java:211) at com.mongodb.internal.operation.OperationHelper$9.onResult(OperationHelper.java:734) at com.mongodb.internal.operation.OperationHelper$9.onResult(OperationHelper.java:731) at com.mongodb.internal.connection.DefaultServer$1.onResult(DefaultServer.java:120) at com.mongodb.internal.connection.DefaultServer$1.onResult(DefaultServer.java:109) at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:48) at com.mongodb.internal.connection.DefaultConnectionPool.openAsync(DefaultConnectionPool.java:204) at com.mongodb.internal.connection.DefaultConnectionPool.getAsync(DefaultConnectionPool.java:154) at com.mongodb.internal.connection.DefaultServer.getConnectionAsync(DefaultServer.java:109) at com.mongodb.internal.binding.AsyncClusterBinding$AsyncClusterBindingConnectionSource.getConnection(AsyncClusterBinding.java:134) at com.mongodb.internal.operation.OperationHelper.withAsyncConnectionSource(OperationHelper.java:731) at com.mongodb.internal.operation.OperationHelper.access$200(OperationHelper.java:69) at com.mongodb.internal.operation.OperationHelper$AsyncCallableWithConnectionAndSourceCallback.onResult(OperationHelper.java:751) at com.mongodb.internal.operation.OperationHelper$AsyncCallableWithConnectionAndSourceCallback.onResult(OperationHelper.java:739) at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:48) at com.mongodb.internal.binding.AsyncClusterBinding$1.onResult(AsyncClusterBinding.java:106) at com.mongodb.internal.binding.AsyncClusterBinding$1.onResult(AsyncClusterBinding.java:100) at com.mongodb.internal.connection.BaseCluster$ServerSelectionRequest.onResult(BaseCluster.java:438) at com.mongodb.internal.connection.BaseCluster.handleServerSelectionRequest(BaseCluster.java:302) at com.mongodb.internal.connection.BaseCluster.selectServerAsync(BaseCluster.java:155) at com.mongodb.internal.connection.SingleServerCluster.selectServerAsync(SingleServerCluster.java:41) at com.mongodb.internal.binding.AsyncClusterBinding.getAsyncClusterBindingConnectionSource(AsyncClusterBinding.java:100) at com.mongodb.internal.binding.AsyncClusterBinding.getWriteConnectionSource(AsyncClusterBinding.java:90) at com.mongodb.internal.operation.OperationHelper.withAsyncConnection(OperationHelper.java:670) at com.mongodb.internal.operation.MixedBulkWriteOperation.executeAsync(MixedBulkWriteOperation.java:205) at com.mongodb.reactivestreams.client.internal.OperationExecutorImpl.lambda$execute$9(OperationExecutorImpl.java:93) at reactor.core.publisher.MonoCreate.subscribe(MonoCreate.java:57) at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:150) at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:67) at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1812) at reactor.core.publisher.MonoCallable.subscribe(MonoCallable.java:61) at reactor.core.publisher.Mono.subscribe(Mono.java:4252) at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:75) at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) at reactor.core.publisher.MonoCreate$DefaultMonoSink.success(MonoCreate.java:129) at com.mongodb.reactivestreams.client.internal.ClientSessionHelper.lambda$createClientSessionMono$2(ClientSessionHelper.java:67) at com.mongodb.internal.connection.BaseCluster$ServerSelectionRequest.onResult(BaseCluster.java:438) at com.mongodb.internal.connection.BaseCluster.handleServerSelectionRequest(BaseCluster.java:302) at com.mongodb.internal.connection.BaseCluster.selectServerAsync(BaseCluster.java:155) at com.mongodb.internal.connection.SingleServerCluster.selectServerAsync(SingleServerCluster.java:41) at com.mongodb.reactivestreams.client.internal.ClientSessionHelper.lambda$createClientSessionMono$3(ClientSessionHelper.java:62) at reactor.core.publisher.MonoCreate.subscribe(MonoCreate.java:57) at reactor.core.publisher.Mono.subscribe(Mono.java:4252) at io.reactivex.internal.operators.single.SingleFromPublisher.subscribeActual(SingleFromPublisher.java:35) at io.reactivex.Single.subscribe(Single.java:3666) at io.reactivex.internal.operators.single.SingleFlatMap.subscribeActual(SingleFlatMap.java:36) at io.reactivex.Single.subscribe(Single.java:3666) at io.reactivex.internal.operators.single.SingleDelayWithCompletable$OtherObserver.onComplete(SingleDelayWithCompletable.java:69) at io.reactivex.internal.disposables.EmptyDisposable.complete(EmptyDisposable.java:68) at io.reactivex.internal.operators.completable.CompletableEmpty.subscribeActual(CompletableEmpty.java:27) at io.reactivex.Completable.subscribe(Completable.java:2309) at io.reactivex.internal.operators.single.SingleDelayWithCompletable.subscribeActual(SingleDelayWithCompletable.java:36) at io.reactivex.Single.subscribe(Single.java:3666) at io.reactivex.internal.operators.single.SingleFlatMap.subscribeActual(SingleFlatMap.java:36) at io.reactivex.Single.subscribe(Single.java:3666) at io.reactivex.internal.operators.single.SingleResumeNext.subscribeActual(SingleResumeNext.java:39) at io.reactivex.Single.subscribe(Single.java:3666) at io.reactivex.internal.operators.single.SingleResumeNext$ResumeMainSingleObserver.onError(SingleResumeNext.java:80) at io.reactivex.internal.operators.maybe.MaybeFlatMapSingle$FlatMapMaybeObserver.onError(MaybeFlatMapSingle.java:101) at io.reactivex.internal.operators.maybe.MaybeSwitchIfEmpty$SwitchIfEmptyMaybeObserver$OtherMaybeObserver.onError(MaybeSwitchIfEmpty.java:115) at io.reactivex.internal.operators.maybe.MaybeError.subscribeActual(MaybeError.java:35) at io.reactivex.Maybe.subscribe(Maybe.java:4290) at io.reactivex.internal.operators.maybe.MaybeSwitchIfEmpty$SwitchIfEmptyMaybeObserver.onComplete(MaybeSwitchIfEmpty.java:88) at io.reactivex.internal.operators.maybe.MaybeSwitchIfEmpty$SwitchIfEmptyMaybeObserver$OtherMaybeObserver.onComplete(MaybeSwitchIfEmpty.java:120) at io.reactivex.internal.operators.maybe.MaybeOnErrorNext$OnErrorNextMaybeObserver.onComplete(MaybeOnErrorNext.java:114) at io.reactivex.internal.operators.maybe.MaybeMap$MapMaybeObserver.onComplete(MaybeMap.java:99) at io.reactivex.internal.operators.observable.ObservableElementAtMaybe$ElementAtObserver.onComplete(ObservableElementAtMaybe.java:102) at io.reactivex.internal.operators.observable.ObservableFromPublisher$PublisherSubscriber.onComplete(ObservableFromPublisher.java:46) at reactor.core.publisher.StrictSubscriber.onComplete(StrictSubscriber.java:123) at reactor.core.publisher.MonoFlatMap$FlatMapMain.secondComplete(MonoFlatMap.java:189) at reactor.core.publisher.MonoFlatMap$FlatMapInner.onComplete(MonoFlatMap.java:260) at reactor.core.publisher.MonoCreate$DefaultMonoSink.success(MonoCreate.java:129) at com.mongodb.reactivestreams.client.internal.BatchCursorPublisher.lambda$first$0(BatchCursorPublisher.java:104) at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onComplete(MonoPeekTerminal.java:282) at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onComplete(MonoPeekTerminal.java:292) at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onComplete(MonoPeekTerminal.java:292) at reactor.core.publisher.MonoCreate$DefaultMonoSink.success(MonoCreate.java:129) at com.mongodb.reactivestreams.client.internal.MongoOperationPublisher.lambda$sinkToCallback$30(MongoOperationPublisher.java:548) at com.mongodb.internal.operation.AsyncQueryBatchCursor.next(AsyncQueryBatchCursor.java:212) at com.mongodb.internal.operation.AsyncQueryBatchCursor.next(AsyncQueryBatchCursor.java:146) at com.mongodb.reactivestreams.client.internal.BatchCursor.lambda$next$0(BatchCursor.java:35) at reactor.core.publisher.MonoCreate.subscribe(MonoCreate.java:57) at reactor.core.publisher.Mono.subscribe(Mono.java:4252) at reactor.core.publisher.Mono.subscribeWith(Mono.java:4363) at reactor.core.publisher.Mono.subscribe(Mono.java:4083) at com.mongodb.reactivestreams.client.internal.BatchCursorPublisher.lambda$first$1(BatchCursorPublisher.java:109) at reactor.core.publisher.MonoCreate.subscribe(MonoCreate.java:57) at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:150) at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:121) at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1812) at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:241) at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onNext(MonoPeekTerminal.java:173) at reactor.core.publisher.MonoCreate$DefaultMonoSink.success(MonoCreate.java:156) at com.mongodb.reactivestreams.client.internal.MongoOperationPublisher.lambda$sinkToCallback$30(MongoOperationPublisher.java:550) at com.mongodb.reactivestreams.client.internal.OperationExecutorImpl.lambda$execute$2(OperationExecutorImpl.java:73) at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:48) at com.mongodb.internal.operation.FindOperation$3.onResult(FindOperation.java:755) at com.mongodb.internal.operation.OperationHelper$ReferenceCountedReleasingWrappedCallback.onResult(OperationHelper.java:532) at com.mongodb.internal.operation.CommandOperationHelper$10.onResult(CommandOperationHelper.java:483) at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:48) at com.mongodb.internal.connection.DefaultServer$DefaultServerProtocolExecutor$2.onResult(DefaultServer.java:286) at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:48) at com.mongodb.internal.connection.CommandProtocolImpl$1.onResult(CommandProtocolImpl.java:84) at com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection$2.onResult(DefaultConnectionPool.java:530) at com.mongodb.internal.connection.UsageTrackingInternalConnection$2.onResult(UsageTrackingInternalConnection.java:142) at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:48) at com.mongodb.internal.connection.InternalStreamConnection$2$1.onResult(InternalStreamConnection.java:462) at com.mongodb.internal.connection.InternalStreamConnection$2$1.onResult(InternalStreamConnection.java:439) at com.mongodb.internal.connection.InternalStreamConnection$MessageHeaderCallback$MessageCallback.onResult(InternalStreamConnection.java:744) at com.mongodb.internal.connection.InternalStreamConnection$MessageHeaderCallback$MessageCallback.onResult(InternalStreamConnection.java:711) at com.mongodb.internal.connection.InternalStreamConnection$5.completed(InternalStreamConnection.java:581) at com.mongodb.internal.connection.InternalStreamConnection$5.completed(InternalStreamConnection.java:578) at com.mongodb.internal.connection.AsynchronousChannelStream$BasicCompletionHandler.completed(AsynchronousChannelStream.java:250) at com.mongodb.internal.connection.AsynchronousChannelStream$BasicCompletionHandler.completed(AsynchronousChannelStream.java:233) at java.base/sun.nio.ch.Invoker.invokeUnchecked(Unknown Source) at java.base/sun.nio.ch.Invoker.invokeDirect(Unknown Source) at java.base/sun.nio.ch.UnixAsynchronousSocketChannelImpl.implRead(Unknown Source) at java.base/sun.nio.ch.AsynchronousSocketChannelImpl.read(Unknown Source) at java.base/sun.nio.ch.AsynchronousSocketChannelImpl.read(Unknown Source) at com.mongodb.internal.connection.AsynchronousSocketChannelStream$AsynchronousSocketChannelAdapter.read(AsynchronousSocketChannelStream.java:144) at com.mongodb.internal.connection.AsynchronousChannelStream.readAsync(AsynchronousChannelStream.java:118) at com.mongodb.internal.connection.AsynchronousChannelStream.readAsync(AsynchronousChannelStream.java:107) at com.mongodb.internal.connection.InternalStreamConnection.readAsync(InternalStreamConnection.java:578) at com.mongodb.internal.connection.InternalStreamConnection.access$1100(InternalStreamConnection.java:78) at com.mongodb.internal.connection.InternalStreamConnection$MessageHeaderCallback.onResult(InternalStreamConnection.java:701) at com.mongodb.internal.connection.InternalStreamConnection$MessageHeaderCallback.onResult(InternalStreamConnection.java:686) at com.mongodb.internal.connection.InternalStreamConnection$5.completed(InternalStreamConnection.java:581) at com.mongodb.internal.connection.InternalStreamConnection$5.completed(InternalStreamConnection.java:578) at com.mongodb.internal.connection.AsynchronousChannelStream$BasicCompletionHandler.completed(AsynchronousChannelStream.java:250) at com.mongodb.internal.connection.AsynchronousChannelStream$BasicCompletionHandler.completed(AsynchronousChannelStream.java:233) at java.base/sun.nio.ch.Invoker.invokeUnchecked(Unknown Source) at java.base/sun.nio.ch.Invoker$2.run(Unknown Source) at java.base/sun.nio.ch.AsynchronousChannelGroupImpl$1.run(Unknown Source) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.base/java.lang.Thread.run(Unknown Source) Caused by: java.lang.IllegalArgumentException: Invalid BSON field name http://schemas.microsoft.com/identity/claims/displayname at org.bson.AbstractBsonWriter.writeName(AbstractBsonWriter.java:534) at com.mongodb.internal.connection.BsonWriterDecorator.writeName(BsonWriterDecorator.java:193) at com.mongodb.internal.connection.IdHoldingBsonWriter.writeName(IdHoldingBsonWriter.java:302) at org.bson.codecs.DocumentCodec.writeMap(DocumentCodec.java:216) at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:159) at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:46) at org.bson.codecs.pojo.LazyPropertyModelCodec.encode(LazyPropertyModelCodec.java:56) at org.bson.codecs.EncoderContext.encodeWithChildContext(EncoderContext.java:91) at org.bson.codecs.pojo.PojoCodecImpl.encodeValue(PojoCodecImpl.java:162) at org.bson.codecs.pojo.PojoCodecImpl.encodeProperty(PojoCodecImpl.java:150) at org.bson.codecs.pojo.PojoCodecImpl.encode(PojoCodecImpl.java:87) at org.bson.codecs.pojo.AutomaticPojoCodec.encode(AutomaticPojoCodec.java:50) at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63) at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29) at com.mongodb.internal.connection.SplittablePayload$WriteRequestEncoder.encode(SplittablePayload.java:200) at com.mongodb.internal.connection.SplittablePayload$WriteRequestEncoder.encode(SplittablePayload.java:187) at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63) at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29) at com.mongodb.internal.connection.BsonWriterHelper.writeDocument(BsonWriterHelper.java:77) at com.mongodb.internal.connection.BsonWriterHelper.writePayload(BsonWriterHelper.java:59) at com.mongodb.internal.connection.BsonWriterHelper.writePayloadArray(BsonWriterHelper.java:50) at com.mongodb.internal.connection.SplittablePayloadBsonWriter.writeEndDocument(SplittablePayloadBsonWriter.java:64) at org.bson.codecs.BsonDocumentCodec.encode(BsonDocumentCodec.java:121) at org.bson.codecs.BsonDocumentCodec.encode(BsonDocumentCodec.java:42) at com.mongodb.internal.connection.CommandMessage.addDocumentWithPayload(CommandMessage.java:198) at com.mongodb.internal.connection.CommandMessage.encodeMessageBodyWithMetadata(CommandMessage.java:182) at com.mongodb.internal.connection.RequestMessage.encode(RequestMessage.java:138) at com.mongodb.internal.connection.CommandMessage.encode(CommandMessage.java:59) at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceiveAsync(InternalStreamConnection.java:392) ... 148 common frames omitted

:computer: Desktop:

Please complete the following information:

ecatrain commented 2 years ago

Hello,

Maybe it would be possible to add an option to SAML IdP to ignore attributes if nothing is present in the mapping, it would be useful and could allow to avoid this bug.

Best regards, Elizaveta