Closed phantomjinx closed 1 year ago
Generally, this is not a right direction. You should not touch anything on the default hawtio/react routes.
Firstly, what OAuth are we talking about? If it's OpenShift OAuth, then we don't need a custom login page, as each OpenShift cluster must have provided its own login page and it is what hawtio-online uses for its authentication as well.
The main mechanics of hawtio/react authentication are that the userService
resolves an authenticated user in some way and if it's resolved hawtio/react considers the user is indeed authenticated and thus allows routes to /*
:
https://github.com/hawtio/hawtio-next/blob/6bcaec8ff813500ba243e75e408564e14747c723/packages/hawtio/src/auth/user-service.ts#L50-L89
As you can see in the code, by default it resolves the user by fetching /user
endpoint API from the server. The server is responsible for managing the authentication state and returning the authenticated user. The userService
provides FetchUserHook
, which is the extension point for an authentication plugin to provide the custom way to resolve the user. Registration of the hook should be done at index.ts
of each authentication plugin:
https://github.com/hawtio/hawtio-next/blob/6bcaec8ff813500ba243e75e408564e14747c723/packages/hawtio/src/plugins/auth/keycloak/index.ts#L7
Since hawtio/react is just an index.html
with js scripts, in most cases when a request reaches the index.html
it should be already authenticated and the user should be resolved. Unauthenticated requests should generally be intercepted before reaching index.html
and redirected to the specific login page provided by an authentication provider such as Keycloak and OpenShift OAuth. The Hawtio login page and /login
are used only for a server that doesn't have its own authentication mechanics, where the authentication filter redirects unauthenticated requests to /login
.
So, all you need to do should be providing a custom hook to userService
and please don't try to modify the flow of Hawtio authentication.
This is not Openshift OAuth but Form OAuth which comes with its own custom login page that is served via online/login
. See hawtio-oauth form directory here.
The 1.0 version includes its own login page since this page only has token on it and not user/password.
I am not changing the flow but migrating an existing flow.
OK, then instead of customising browser router, what about extending HawtioLogin component so that an auth plugin can optionally provide its own login page component to replace the default one?
Could do. Although, <HawtioLogin/>
is not exported either. Nothing from ui
package is.
To avoid exporting, would mean providing some kind of JSX Element to 'replace' <HawtioLogin/>
so that would be a modified suggestion 3 above, I think.
No, you can look at HawtioPage component for how a non-exported Hawtio component can refer and use plugins in an inversion-of-control way.
@tadayosi,
So I think I have a solution but please review:
On the hawtio/react side:
title
and componentId
for login. In addition the singleton component registry is accessible via a getter method;So an example of how this works is available in the OAuth Test App. Have not coded higher up the Hawtio-Online stack till we are happy with this approach:
(Please note: since hawtio/react does not export HawtioLogin
and HawtioLoadingPage
, I oopy them for the purposes of the test application)
OAuth-App:
OAuth:
OAuthFormLoginForm
to the configManager
component registryHopefully, that makes sense but feel free to ask questions if you cannot make head or tail of it.
Thanks. It looks great in general. There are a few comments that I'd like to see addressed. If you could create a pull req, then it'd be easier to review it in more details.
usePlugins
hook: https://github.com/hawtio/hawtio-next/blob/main/packages/hawtio/src/core/hooks.ts#L8-L30 Why don't you just use the same hook for extending the login component?componentId
to the Login
type in hawtconfig.json
. title
is fine.isLogin?: boolean
flag to the Plugin
interface https://github.com/hawtio/hawtio-next/blob/main/packages/hawtio/src/core/core.ts#L39 and providing a custom login component through the plugin interface? We should then filter out login component plugins at the existing places where plugins are used.Draft PRs for this created, for review.
Changes tested using both Openshift and Minicube, specifically:
In Hawtio-Online react app, I have called the Hawtio component directly as the base app, eg.
This has been sufficient for an implementation without requirement to add other routes. However, now that I am adding the possibility of an oauth login page, hawtio-online requires its own
<BrowserRouter/>
.This generates a router-cannot-be-inside-a-router error since
<Hawtio/>
already contains a<BrowserRouter/>
switching<HawtioPage/>
with its own login page (<HawtioLogin/>
).Now, hawtio-online does not need the original
<HawtioLogin/>
component since it is being overridden with theOAuthLoginPage
(token login rather than user/password). So what to do?<HawtioPage/>
) and so bypass the<Hawtio/>
component altogether. This would allow control of the<BrowserRouter />
wholly in hawtio-online. However, this seems like exporting internals / implementations ofhawtio/react
and not really fixing the issue.<Hawtio/>
is a component to be inserted in other components, perhaps it would make sense to have it return a set of<Route/>
components for inclusion in a parent<BrowserRouter/>
(maybe even do this conditionally based on a given prop??). Although whether the existing<HawtioLogin />
can be overridden in this regard am not sure?<Hawtio/>
that includes extra routes or overrides existing routes. That way<Hawtio/>
remains the single<BrowserRouter/>
but 'parent' components can add custom links/pages/routes to it. This seems the preferred solution but unsure if there are unforseen problems.