[
https://issues.apache.org/jira/browse/NIFI-7771?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
M Tien updated NIFI-7771:
-------------------------
Fix Version/s: 1.13.0
Resolution: Fixed
Status: Resolved (was: Patch Available)
> 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
> Assignee: M Tien
> Priority: Critical
> Fix For: 1.13.0
>
> Time Spent: 40m
> 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)