-
Notifications
You must be signed in to change notification settings - Fork 38
Description
I'm trying to implement oidc authentication on a server side (Rust) app with the following flow:
- User attempts to hit endpoint
- Middleware sees there is no valid session information
- Middleware calls Frontier to start a Register flow (calling Authenticate with a AuthenticateRequest message. callback_url is set to http://localhost:3030/sso/callback)
- My app gets the URL from Frontier and responds with a HTTP Redirect to SSO endpoint
- SSO returns to http://localhost:3030/sso/callback, and the following code is run
struct SSOCallbackData {
code: String,
state: String,
session_state: String,
iss: String,
}
# works. responds with a successful status and provides cookies
let req = reqwest::get(format!("https://public-url/v1beta1/auth/callback?code={}&state={}&session_state={}&iss={}", query.code, query.state, query.session_state, query.iss)).await.unwrap();
return HttpResponse::Ok().body(format!("body: {:#?}", req));
let body = req.text().await.unwrap();
info!("body: {}", body);
#
#
# fails with " Status { code: Internal, message: "oauth2: \"invalid_grant\" \"Code not valid\"", metadata: MetadataMap { headers: {"content-type": "application/grpc"} }, source: None }"
let mut chan = self.channel.clone();
let mut opts = prost_types::Struct::default();
opts.fields.insert("iss".to_string(), prost_types::Value::from(query.iss));
opts.fields.insert("session_state".to_string(), prost_types::Value::from(query.session_state));
let request = AuthCallbackRequest {
strategy_name: "".to_string(),
state: query.state,
code: query.code,
state_options: Some(opts),
};
chan.auth_callback(request).await...
I would expect both methods of calling Frontier to work, but the gRPC one consistently fails and I'm not sure why. There is no error in the server logs other than oauth2: "invalid_grant" "Code not valid"
"Code not valid" is the error Keycloak responds with, but it's not clear what changes between HTTP and gRPC that would cause the value sent to keycloak to be different.
I also tried to have the SSO flow use /v1beta1/auth/callback as the callback endpoint. This worked fine, but when Frontier redirected back to my application, I was not given a token or any way to call Frontier after the SSO flow is completed. I think the design assumption is that the SSO flows are done entirely client side, so the browser's cookies can be used. This doesn't work with a server side app, as I have no access to another domain's cookies.