We’re happy to announce the availablity of Moqui SSO. This new feature is for anyone looking to add new login options to Moqui. The new Moqui SSO component supports the following protocols:
OAuth
OpenID Connect
SAML
How to enable Moqui SSO?
You can enable SSO by following these 2 simple steps:
Get the SSO component
./gradlew getComponent -Pcomponent=moqui-sso
Load the seed data (pick the flow you wish to enable):
I was able to set it up with GitHub. For those that are interested in how, here’s a couple steps:
Setup Note: Before following Ayman’s steps ahead, you’ll need to update your git repo with the latest moqui-framework, and moqui-runtime. This will add the moqui-sso component to addons.xml in moqui-framework, and the necessary changes to moqui-runtime (i.e. the Login screen)
Note: For @aabiabdallah and those who try this out on a chromium browser. I was able to have it work just fine with firefox. However on a chromium browser, the 303 redirect for the /sso/Login endpoint form submit wasn’t allowed (see error below). Can someone please reproduce this?
Refused to send form data to 'http://localhost:8080/sso/login' because it violates the following Content Security Policy directive: "form-action 'self'".
Yes, I reproduced the Refused error.
That is becuase you have a
<meta http-equiv="Content-Security-Policy" />
somewhere defined in the html head section. If you remove this definition, it will redirect smoothly to Github. Or you can add Github to this definition
Have you noticed the error when trying to use LinkedIn Sign In with LinkedIn using OpenID Connect
I got the following error:
--- 2024-02-13 03:44:03.776 [qtp872826668-29] ERROR org.moqui.impl.context.LoggerFacadeImpl [] []
An error occurred while handling callback
*org.pac4j.core.exception.TechnicalException: Bad token response, error=invalid_request, description=A required parameter client_secret is missing*
at org.pac4j.oidc.credentials.authenticator.OidcAuthenticator.executeTokenRequest(OidcAuthenticator.java:206) ~[pac4j-oidc-5.7.1.jar:?]
at org.pac4j.oidc.credentials.authenticator.OidcAuthenticator.validate(OidcAuthenticator.java:165) ~[pac4j-oidc-5.7.1.jar:?]
at org.pac4j.core.client.BaseClient.lambda$retrieveCredentials$0(BaseClient.java:75) ~[pac4j-core-5.7.1.jar:?]
at java.util.Optional.ifPresent(Optional.java:183) ~[?:?]
at org.pac4j.core.client.BaseClient.retrieveCredentials(BaseClient.java:72) ~[pac4j-core-5.7.1.jar:?]
at org.pac4j.core.client.IndirectClient.getCredentials(IndirectClient.java:145) ~[pac4j-core-5.7.1.jar:?]
at org.pac4j.core.engine.DefaultCallbackLogic.perform(DefaultCallbackLogic.java:75) ~[pac4j-core-5.7.1.jar:?]
at org.pac4j.core.engine.CallbackLogic$perform.call(Unknown Source) ~[?:?]
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47) ~[moqui_temp10653206240214054500WEB-INF_lib_groovy-3.0.9.jar.:3.0.9]
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) ~[moqui_temp10653206240214054500WEB-INF_lib_groovy-3.0.9.jar.:3.0.9]
at org.moqui.sso.AuthenticationFlow.handleCallback(AuthenticationFlow.groovy:87) ~[moqui-sso-1.0.0.jar:?]
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
at org.moqui.impl.service.runner.JavaServiceRunner.runService(JavaServiceRunner.groovy:66) ~[moqui_temp13016124410341027508WEB-INF_lib_moqui-framework-3.0.0.jar.:3.0.0]
at org.moqui.impl.service.ServiceCallSyncImpl.callSingle(ServiceCallSyncImpl.java:322) ~[moqui_temp13016124410341027508WEB-INF_lib_moqui-framework-3.0.0.jar.:3.0.0]
at org.moqui.impl.service.ServiceCallSyncImpl.call(ServiceCallSyncImpl.java:125) ~[moqui_temp13016124410341027508WEB-INF_lib_moqui-framework-3.0.0.jar.:3.0.0]
at org.moqui.service.ServiceCallSync$call$0.call(Unknown Source) ~[?:?]
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47) ~[moqui_temp10653206240214054500WEB-INF_lib_groovy-3.0.9.jar.:3.0.9]
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) ~[moqui_temp10653206240214054500WEB-INF_lib_groovy-3.0.9.jar.:3.0.9]
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:130) ~[moqui_temp10653206240214054500WEB-INF_lib_groovy-3.0.9.jar.:3.0.9]
at component___moqui_sso_screen_sso_xml_transition_callback_actions.run(component___moqui_sso_screen_sso_xml_transition_callback_actions:11) ~[?:?]
at org.moqui.impl.actions.XmlAction.run(XmlAction.java:67) ~[moqui_temp13016124410341027508WEB-INF_lib_moqui-framework-3.0.0.jar.:3.0.0]
at org.moqui.impl.screen.ScreenDefinition$TransitionItem.run(ScreenDefinition.groovy:987) ~[moqui_temp13016124410341027508WEB-INF_lib_moqui-framework-3.0.0.jar.:3.0.0]
at org.moqui.impl.screen.ScreenRenderImpl.recursiveRunTransition(ScreenRenderImpl.groovy:757) ~[moqui_temp13016124410341027508WEB-INF_lib_moqui-framework-3.0.0.jar.:3.0.0]
at org.moqui.impl.screen.ScreenRenderImpl.recursiveRunTransition(ScreenRenderImpl.groovy:753) ~[moqui_temp13016124410341027508WEB-INF_lib_moqui-framework-3.0.0.jar.:3.0.0]
at org.moqui.impl.screen.ScreenRenderImpl.internalRender(ScreenRenderImpl.groovy:454) ~[moqui_temp13016124410341027508WEB-INF_lib_moqui-framework-3.0.0.jar.:3.0.0]
at org.moqui.impl.screen.ScreenRenderImpl.render(ScreenRenderImpl.groovy:170) ~[moqui_temp13016124410341027508WEB-INF_lib_moqui-framework-3.0.0.jar.:3.0.0]
at org.moqui.impl.webapp.MoquiServlet.service(MoquiServlet.groovy:118) ~[moqui_temp13016124410341027508WEB-INF_lib_moqui-framework-3.0.0.jar.:3.0.0]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:750) ~[moqui.war:3.0.0]
at org.eclipse.jetty.servlet.ServletHolder$NotAsync.service(ServletHolder.java:1410) ~[moqui_temp14844224054252611520execlib_jetty-servlet-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:764) ~[moqui_temp14844224054252611520execlib_jetty-servlet-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1630) ~[moqui_temp14844224054252611520execlib_jetty-servlet-10.0.9.jar.:10.0.9]
at HostCleanFilter.doFilter(HostCleanFilter.java:225) ~[moqui.war:?]
at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202) ~[moqui_temp14844224054252611520execlib_jetty-servlet-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1600) ~[moqui_temp14844224054252611520execlib_jetty-servlet-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:170) ~[moqui_temp33892897111477974execlib_websocket-servlet-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202) ~[moqui_temp14844224054252611520execlib_jetty-servlet-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1600) ~[moqui_temp14844224054252611520execlib_jetty-servlet-10.0.9.jar.:10.0.9]
at org.moqui.impl.webapp.ElasticRequestLogFilter.doFilter(ElasticRequestLogFilter.groovy:110) ~[moqui_temp13016124410341027508WEB-INF_lib_moqui-framework-3.0.0.jar.:3.0.0]
at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202) ~[moqui_temp14844224054252611520execlib_jetty-servlet-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1600) ~[moqui_temp14844224054252611520execlib_jetty-servlet-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:506) ~[moqui_temp14844224054252611520execlib_jetty-servlet-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:131) ~[moqui_temp8753752083419951429execlib_jetty-server-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:578) ~[moqui_temp16966687951898033334execlib_jetty-security-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122) ~[moqui_temp8753752083419951429execlib_jetty-server-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:223) ~[moqui_temp8753752083419951429execlib_jetty-server-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1571) ~[moqui_temp8753752083419951429execlib_jetty-server-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221) ~[moqui_temp8753752083419951429execlib_jetty-server-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1378) ~[moqui_temp8753752083419951429execlib_jetty-server-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176) ~[moqui_temp8753752083419951429execlib_jetty-server-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:463) ~[moqui_temp14844224054252611520execlib_jetty-servlet-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1544) ~[moqui_temp8753752083419951429execlib_jetty-server-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:174) ~[moqui_temp8753752083419951429execlib_jetty-server-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1300) ~[moqui_temp8753752083419951429execlib_jetty-server-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129) ~[moqui_temp8753752083419951429execlib_jetty-server-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:717) ~[moqui_temp8753752083419951429execlib_jetty-server-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122) ~[moqui_temp8753752083419951429execlib_jetty-server-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.server.Server.handle(Server.java:562) ~[moqui_temp8753752083419951429execlib_jetty-server-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.server.HttpChannel.lambda$handle$0(HttpChannel.java:505) ~[moqui_temp8753752083419951429execlib_jetty-server-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:762) ~[moqui_temp8753752083419951429execlib_jetty-server-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:497) ~[moqui_temp8753752083419951429execlib_jetty-server-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:282) ~[moqui_temp8753752083419951429execlib_jetty-server-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:319) ~[moqui_temp7075068661577100833WEB-INF_lib_jetty-io-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100) ~[moqui_temp7075068661577100833WEB-INF_lib_jetty-io-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53) ~[moqui_temp7075068661577100833WEB-INF_lib_jetty-io-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:412) ~[moqui_temp3153816534271096162WEB-INF_lib_jetty-util-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:381) ~[moqui_temp3153816534271096162WEB-INF_lib_jetty-util-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:268) ~[moqui_temp3153816534271096162WEB-INF_lib_jetty-util-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.lambda$new$0(AdaptiveExecutionStrategy.java:138) ~[moqui_temp3153816534271096162WEB-INF_lib_jetty-util-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:407) ~[moqui_temp3153816534271096162WEB-INF_lib_jetty-util-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:894) ~[moqui_temp3153816534271096162WEB-INF_lib_jetty-util-10.0.9.jar.:10.0.9]
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1038) ~[moqui_temp3153816534271096162WEB-INF_lib_jetty-util-10.0.9.jar.:10.0.9]
at java.lang.Thread.run(Thread.java:829) ~[?:?]
--- 2024-02-13 03:44:03.794 [qtp872826668-29] ERROR org.moqui.impl.webapp.MoquiServlet [] []
Internal error processing request: java.lang.IllegalStateException: Committed
java.lang.IllegalStateException: Committed
It seems that the pac4j code does not set client secret properly. login#user seems fine. Only error in handdleCalback
The OOTB support for LinkedIn is via OAuth. I see you’re using the OIDC end point in your log. Which client did you use for this (i.e. clientTypeEnumId)?
OctLinkedIn is what I am using. authFlowTypeEnumId="AftOidc" and with OidcFlow entity.
Should I use ClientType with OctOther? LinkedIn now is deprecating the old Oauth, starting using openid connection.
The linkedIn openid connection is kind of oauth2. The pac4j package OctLinkedIn client is based on oauth1. Thus not working with LinkedIn openid connection.
Working smoothly with Github and x(twitter). Just remember for Twitter, not use clientId and client secret, it has to be api key and corresponding secret.
If somebody will use this sso component for Google Auth2, remember the redirect uri setup in Google cloud console has to be https://yourDomainName.com/sso/callback?client_name=Google . The important part is ?client_name=Google as pac4j Goolge2Client will append this to the end of the callback url. If not present, Google will comoplain the uri_dismatch or something like this.
And with Google Aouth2, the Profile will not return the valid username, thus a proper username has to be created by using profile’s id or email field value.