[ https://issues.apache.org/jira/browse/NIFI-7771?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17230506#comment-17230506 ]
humpfhumpf commented on NIFI-7771: ---------------------------------- Thx for your reply. My PR could be considered as a workaround. [~mtien]: if you cannot reproduce the case, do not hesitate to contact me. > Infinite loop on WebUI when node stopped in cluster > --------------------------------------------------- > > Key: NIFI-7771 > URL: https://issues.apache.org/jira/browse/NIFI-7771 > Project: Apache NiFi > Issue Type: Bug > Components: Core UI > Affects Versions: 1.10.0, 1.9.2, 1.12.0, 1.11.4 > Environment: Linux > Reporter: humpfhumpf > Priority: Critical > Time Spent: 10m > Remaining Estimate: 0h > > h2. Context > Before the bug occurs, one needs: > * a load-balancer which uses client IP affinity to “select” one NiFi > instance in the cluster; > * a fresh and successful OpenID Connect authentication on WebUI. > Then, stops the NiFi instance, which was “selected” by the load-balancer for > you. > In the mean time, the WebUI (javascript) continues to poll WebAPI by fetching > status URLs, but all calls return HTTP 401 error. Then WebUI shows an error > screen: “Unauthorized. Unable to validate the access token.”, with 2 links: > “log out” and “home”. > If you click on the “home” link, *the browser enters in an infinite loop of > redirects between NiFi and OIDC Identity Provider.* > The offending HTTP flows is: > * “home” link calls: GET /nifi > * Redirects to: GET /nifi/ > ** asynchronously calls: GET /nifi-api/flow/current-user => failed HTTP 401 > * Redirects to: GET /nifi/login > * Redirects to: GET <my_idp_url>/openid-connect/auth > * Redirects to: GET /nifi-api/access/oidc/callback > * Redirects to: GET /nifi > * Redirects to: GET /nifi/ > ** asynchronously calls: GET /nifi-api/flow/current-user => failed HTTP 401 > * [loop] > > The stack trace of {{/nifi-api/flow/current-user}} call is: > > {code:java} > ERROR [NiFi Web Server-284] o.a.nifi.web.security.jwt.JwtService There was an > error validating the JWT io.jsonwebtoken.JwtException: Unable to validate the > access token. > at > org.apache.nifi.web.security.jwt.JwtService.parseTokenFromBase64EncodedString(JwtService.java:106) > at > org.apache.nifi.web.security.jwt.JwtService.getAuthenticationFromToken(JwtService.java:60) > at > org.apache.nifi.web.security.jwt.JwtAuthenticationProvider.authenticate(JwtAuthenticationProvider.java:48) > at > org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174) > at > org.apache.nifi.web.security.NiFiAuthenticationFilter.authenticate(NiFiAuthenticationFilter.java:78) > at > org.apache.nifi.web.security.NiFiAuthenticationFilter.doFilter(NiFiAuthenticationFilter.java:58) > at > org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) > at > org.apache.nifi.web.security.NiFiAuthenticationFilter.authenticate(NiFiAuthenticationFilter.java:99) > at > org.apache.nifi.web.security.NiFiAuthenticationFilter.doFilter(NiFiAuthenticationFilter.java:58) > ... > Caused by: io.jsonwebtoken.SignatureException: JWT signature does not match > locally computed signature. JWT validity cannot be asserted and should not be > trusted. > at > io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:342) > at > io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:458) > at > io.jsonwebtoken.impl.DefaultJwtParser.parseClaimsJws(DefaultJwtParser.java:518) > at > org.apache.nifi.web.security.jwt.JwtService.parseTokenFromBase64EncodedString(JwtService.java:102) > ... > {code} > > > In my opinion, there are 2 problems: > h2. Problem 1 > The NiFi JWT token is used (and not replaced) by nfCanvas.init() even after > loadCurrentUser() failed with an authentication error (when GET > /nifi-api/flow/current-user returns 401). > In such case, this token, stored in nfStorage (in Javascript Local Storage of > browser), should be cleared before redirecting to /nifi/login. > h2. Problem 2 > The NiFi JWT token is not shared among NiFi cluster. > This token is not the original id_token returned by the OIDC Identity > Provider, but a new one, generated by the NiFi instance on which the browser > was routed during the OIDC connection flow. > This token is closely related to some data stored in H2 users database > (nifi-user-keys.h2.db). > Its “KEY” table contains the following data for each user: email, a primary > key (auto increment) and a generated UUID. > The NiFi JWT token contains (among other things) a copy of email and the > auto-incremented primary key. Moreover, this JWT is HS256-signed with UUID > key. > *But, both primary key and UUID are not shared in NiFi cluster.* > It seems to be the reason why WebUI must interrupt its polling to WebAPI: > stored JWT is no more valid on the new “selected” NiFi instance, to which the > load-balancer routes your browser. > I think there are 3 solutions: > * Use a shared secret (from a new property in nifi.properties) to sign NiFi > JWT tokens. The uselessness of the primary key inside the token should be > checked; > * Synchronize the H2 users database among NiFi cluster; > * Replace the NiFi interal JWT token by the official OIDC JWT “id_token” on > every WebAPI calls. > -- This message was sent by Atlassian Jira (v8.3.4#803005)