mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-04-20 23:03:20 +03:00
oidc: route auth requests through shared HTTP/tcp-proxy path while keeping TLS warmup
Signed-off-by: 21pages <sunboeasy@gmail.com>
This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
use super::HbbHttpResponse;
|
use super::HbbHttpResponse;
|
||||||
use crate::hbbs_http::create_http_client_with_url;
|
use crate::hbbs_http::create_http_client_with_url;
|
||||||
use hbb_common::{config::LocalConfig, log, ResultType};
|
use hbb_common::{config::LocalConfig, log, ResultType};
|
||||||
use reqwest::blocking::Client;
|
use serde::de::DeserializeOwned;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use serde_repr::{Deserialize_repr, Serialize_repr};
|
use serde_repr::{Deserialize_repr, Serialize_repr};
|
||||||
|
use serde_json::{Map, Value};
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
@@ -109,7 +110,7 @@ pub struct AuthBody {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct OidcSession {
|
pub struct OidcSession {
|
||||||
client: Option<Client>,
|
warmed_api_server: Option<String>,
|
||||||
state_msg: &'static str,
|
state_msg: &'static str,
|
||||||
failed_msg: String,
|
failed_msg: String,
|
||||||
code_url: Option<OidcAuthUrl>,
|
code_url: Option<OidcAuthUrl>,
|
||||||
@@ -136,7 +137,7 @@ impl Default for UserStatus {
|
|||||||
impl OidcSession {
|
impl OidcSession {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
client: None,
|
warmed_api_server: None,
|
||||||
state_msg: REQUESTING_ACCOUNT_AUTH,
|
state_msg: REQUESTING_ACCOUNT_AUTH,
|
||||||
failed_msg: "".to_owned(),
|
failed_msg: "".to_owned(),
|
||||||
code_url: None,
|
code_url: None,
|
||||||
@@ -149,11 +150,28 @@ impl OidcSession {
|
|||||||
|
|
||||||
fn ensure_client(api_server: &str) {
|
fn ensure_client(api_server: &str) {
|
||||||
let mut write_guard = OIDC_SESSION.write().unwrap();
|
let mut write_guard = OIDC_SESSION.write().unwrap();
|
||||||
if write_guard.client.is_none() {
|
if write_guard.warmed_api_server.as_deref() == Some(api_server) {
|
||||||
// This URL is used to detect the appropriate TLS implementation for the server.
|
return;
|
||||||
let login_option_url = format!("{}/api/login-options", &api_server);
|
}
|
||||||
let client = create_http_client_with_url(&login_option_url);
|
// This URL is used to detect the appropriate TLS implementation for the server.
|
||||||
write_guard.client = Some(client);
|
let login_option_url = format!("{}/api/login-options", api_server);
|
||||||
|
let _ = create_http_client_with_url(&login_option_url);
|
||||||
|
write_guard.warmed_api_server = Some(api_server.to_owned());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_hbb_http_response<T: DeserializeOwned>(body: &str) -> ResultType<HbbHttpResponse<T>> {
|
||||||
|
let map = serde_json::from_str::<Map<String, Value>>(body)?;
|
||||||
|
if let Some(error) = map.get("error") {
|
||||||
|
if let Some(err) = error.as_str() {
|
||||||
|
Ok(HbbHttpResponse::Error(err.to_owned()))
|
||||||
|
} else {
|
||||||
|
Ok(HbbHttpResponse::ErrorFormat)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
match serde_json::from_value(Value::Object(map)) {
|
||||||
|
Ok(v) => Ok(HbbHttpResponse::Data(v)),
|
||||||
|
Err(_) => Ok(HbbHttpResponse::DataTypeFormat),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,26 +182,15 @@ impl OidcSession {
|
|||||||
uuid: &str,
|
uuid: &str,
|
||||||
) -> ResultType<HbbHttpResponse<OidcAuthUrl>> {
|
) -> ResultType<HbbHttpResponse<OidcAuthUrl>> {
|
||||||
Self::ensure_client(api_server);
|
Self::ensure_client(api_server);
|
||||||
let resp = if let Some(client) = &OIDC_SESSION.read().unwrap().client {
|
let body = serde_json::json!({
|
||||||
client
|
"op": op,
|
||||||
.post(format!("{}/api/oidc/auth", api_server))
|
"id": id,
|
||||||
.json(&serde_json::json!({
|
"uuid": uuid,
|
||||||
"op": op,
|
"deviceInfo": crate::ui_interface::get_login_device_info(),
|
||||||
"id": id,
|
})
|
||||||
"uuid": uuid,
|
.to_string();
|
||||||
"deviceInfo": crate::ui_interface::get_login_device_info(),
|
let resp = crate::post_request_sync(format!("{}/api/oidc/auth", api_server), body, "")?;
|
||||||
}))
|
Self::parse_hbb_http_response(&resp)
|
||||||
.send()?
|
|
||||||
} else {
|
|
||||||
hbb_common::bail!("http client not initialized");
|
|
||||||
};
|
|
||||||
let status = resp.status();
|
|
||||||
match resp.try_into() {
|
|
||||||
Ok(v) => Ok(v),
|
|
||||||
Err(err) => {
|
|
||||||
hbb_common::bail!("Http status: {}, err: {}", status, err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn query(
|
fn query(
|
||||||
@@ -197,11 +204,19 @@ impl OidcSession {
|
|||||||
&[("code", code), ("id", id), ("uuid", uuid)],
|
&[("code", code), ("id", id), ("uuid", uuid)],
|
||||||
)?;
|
)?;
|
||||||
Self::ensure_client(api_server);
|
Self::ensure_client(api_server);
|
||||||
if let Some(client) = &OIDC_SESSION.read().unwrap().client {
|
#[derive(Deserialize)]
|
||||||
Ok(client.get(url).send()?.try_into()?)
|
struct HttpResponseBody {
|
||||||
} else {
|
body: String,
|
||||||
hbb_common::bail!("http client not initialized")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let resp = crate::http_request_sync(
|
||||||
|
url.to_string(),
|
||||||
|
"GET".to_owned(),
|
||||||
|
None,
|
||||||
|
"{}".to_owned(),
|
||||||
|
)?;
|
||||||
|
let resp = serde_json::from_str::<HttpResponseBody>(&resp)?;
|
||||||
|
Self::parse_hbb_http_response(&resp.body)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset(&mut self) {
|
fn reset(&mut self) {
|
||||||
|
|||||||
Reference in New Issue
Block a user