Kurian C created ZEPPELIN-3426:
----------------------------------
Summary: Zeppelin websocket calls when not logged in causing OAuth
state mismatch errors
Key: ZEPPELIN-3426
URL: https://issues.apache.org/jira/browse/ZEPPELIN-3426
Project: Zeppelin
Issue Type: Bug
Components: zeppelin-server
Affects Versions: 0.7.3
Reporter: Kurian C
Zeppelin websocket calls when not logged in causing OAuth state mismatch errors
We are facing issue where intermittently when we try to login to Zeppelin with
Google OAuth(configured using shiro + buji-pac4j) it fails throwing below
exception during callback
HTTP ERROR 500
Problem accessing /callback. Reason:
Server Error
Caused by:
javax.servlet.ServletException: Filtered request failed.
at
org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:384)
at
org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at
org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.apache.zeppelin.server.CorsFilter.doFilter(CorsFilter.java:72)
at
org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577)
at
org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)
at
org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
at
org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at
org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at
org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215)
at
org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.eclipse.jetty.server.Server.handle(Server.java:499)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)
at
org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
at
org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
at java.lang.Thread.run(Unknown Source)
Caused by: org.pac4j.core.exception.TechnicalException: State parameter is
different from the one sent in authentication request. Session expired or
possible threat of cross-site request forgery
at
org.pac4j.oidc.credentials.extractor.OidcExtractor.extract(OidcExtractor.java:80)
at
org.pac4j.oidc.credentials.extractor.OidcExtractor.extract(OidcExtractor.java:31)
at org.pac4j.core.client.BaseClient.retrieveCredentials(BaseClient.java:63)
at org.pac4j.core.client.IndirectClient.getCredentials(IndirectClient.java:125)
at
org.pac4j.core.engine.DefaultCallbackLogic.perform(DefaultCallbackLogic.java:79)
at io.buji.pac4j.filter.CallbackFilter.doFilter(CallbackFilter.java:79)
at
org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
at
org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
at
org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
at
org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
at
org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
at
org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:387)
at
org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
... 22 more
Caused by:
org.pac4j.core.exception.TechnicalException: State parameter is different from
the one sent in authentication request. Session expired or possible threat of
cross-site request forgery
at
org.pac4j.oidc.credentials.extractor.OidcExtractor.extract(OidcExtractor.java:80)
at
org.pac4j.oidc.credentials.extractor.OidcExtractor.extract(OidcExtractor.java:31)
at org.pac4j.core.client.BaseClient.retrieveCredentials(BaseClient.java:63)
at org.pac4j.core.client.IndirectClient.getCredentials(IndirectClient.java:125)
at
org.pac4j.core.engine.DefaultCallbackLogic.perform(DefaultCallbackLogic.java:79)
at io.buji.pac4j.filter.CallbackFilter.doFilter(CallbackFilter.java:79)
at
org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
at
org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
at
org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
at
org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
at
org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
at
org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:387)
at
org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
at
org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at
org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.apache.zeppelin.server.CorsFilter.doFilter(CorsFilter.java:72)
at
org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577)
at
org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)
at
org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
at
org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at
org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at
org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215)
at
org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.eclipse.jetty.server.Server.handle(Server.java:499)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)
at
org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
at
org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
at java.lang.Thread.run(Unknown Source)
We figured out the issue to be due state parameter being different in the
Google redirected request and that in Zeppelin session store. The difference
happens due to following scenario
When user loads the Zeppelin home page, the client side JS by default tries to
make a websocket connection irrespective of whether a user is logged in or not.
Since user is not logged in, the WS connect call fails due to auth error and it
keeps retrying(every 10 secs or so).
In certain cases, when the user hits the login button and before the response
to redirect to Google OAuth page happens, a websocket call as well is sent from
the client side JS to Zeppelin server.
In this case, when user hits the login button, a state is generated and is set
in the redirect url, but after that when the websocket call hits the server
accessing /ws , a new state is generated(/ws calls are auth protected). So when
the user authenticates with Google and gets redirected to callback url, it
throws state parameter is different.
As a possible fix, can Javascript be modified to prevent websocket calls to
backend if user is not logged in? Will there be any other impact due to this?
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)