Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question - OAuth2 Configuration Change #39

Open
b-grooters-byte opened this issue Oct 10, 2024 · 3 comments
Open

Question - OAuth2 Configuration Change #39

b-grooters-byte opened this issue Oct 10, 2024 · 3 comments

Comments

@b-grooters-byte
Copy link

We are using yew_oauth2 in a scenario where the user may be able to select a login realm. A simple example of this using keycloak would be similar to the example below. This does not appear to be the correct way to do this due to the error that occurs when the 2nd realm is selected.

In this scenario:

  • load page
  • change realm to "Realm Two"
  • Click Login

at this point the redirect to KeyCloak with the correct realm is selected for authentication, however, once authentication is complete, we see that exchange code fails

login result: failed to exchange code: Server returned error response

and in the console log output in the browser a message similar to:

POST http://localhost:8084/realms/realm_one/protocol/openid-connect/token [HTTP/1.1 400 Bad Request ...]

the interesting thing here is that while part of the configuration has correctly been updated and the authentication request has been directed to the correct realm, the subsequent post for code exchange appears to be directed to the realm initially configured. I spent some time reviewing the config change code in the OpenID Client but was not able to determine whether this is an issue in the library, not the correct way to change configuration, or something else.

use yew::prelude::*;
use yew_oauth2::openid::*;
use yew_oauth2::prelude::*;

const REALM_ONE: &str = "realm_one";
const REALM_TWO: &str = "realm_two";

#[function_component]
fn App() -> Html {
    let realm = use_state(|| AttrValue::from(REALM_ONE.to_string()));
    let realm_view = realm.clone();

    let onclick = {
        let realm = realm.clone();
        Callback::from(move |_| match realm.as_str() {
            REALM_ONE => realm.set(REALM_TWO.into()),
            _ => realm.set(REALM_ONE.into()),
        })
    };

    let button_label = match realm_view.as_str() {
        REALM_ONE => "Realm One",
        _ => "Realm Two",
    };

    let config = Config::new(
        "realm_test.client_id",
        format!("http://localhost:8084/realms/{}", &*realm_view),
    );
    html! {
        <div>
            <button {onclick}>{ "Change Realm" }</button>
            <p>{ button_label }</p>
            <OAuth2 {config}>
                <AppContent />
            </OAuth2>
        </div>
    }
}

#[function_component(AppContent)]
fn app_content() -> Html {
    let agent = use_auth_agent().expect("Must be nested inside an OAuth2 component");

    let login = use_callback(agent.clone(), |_, agent| {
        let _ = agent.start_login();
    });
    let logout = use_callback(agent, |_, agent| {
        let _ = agent.logout();
    });

    html! {
        <>
        <Failure><FailureMessage/></Failure>
        <Authenticated>
        <button onclick={logout}>{ "Logout" }</button>
        </Authenticated>
        <NotAuthenticated>
        <button onclick={login}>{ "Login" }</button>
        </NotAuthenticated>
        </>
    }
}

fn main() {
    yew::Renderer::<App>::new().render();
}
@ctron
Copy link
Owner

ctron commented Oct 10, 2024

Hm, I not sure it's been tried before. But I'd expect it to work too.

It might be that the config doesn't get passed to the agent that is being created in the background. The config would be received by the OAut2 component as a change. But then might not get passed on to the agent.

@chrysn
Copy link

chrysn commented Nov 13, 2024

I'm coming to this issue from an angle of needing multiple OpenID authentications active at the same time (I'll elaborate on the actual use case if there's interest, but for sake of simplicity say a PWA should act on GitHub and GitLab issues at the same time).

Thinking about changing OAuth2 configurations in terms of "I'm removing an instance of the agent from the pool and adding a different one" may be an easier (or trivial if multiple providers are tackled first) approach than mutating something that was originally designed assuming that it will not be mutated.

@ctron
Copy link
Owner

ctron commented Nov 20, 2024

I am not sure it easily possible at the moment. It's using the yew contexts. So that means that only one context (the closest one) would be found by child components. You'd need to somehow work around this, aggregating multiple tokens into your own context.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants