Skip to content

Commit f97ce6c

Browse files
committedAug 26, 2022
remove introspect http call on checking token validitiy
1 parent 31dc156 commit f97ce6c

File tree

4 files changed

+83
-58
lines changed

4 files changed

+83
-58
lines changed
 

‎.idea/workspace.xml

+32-42
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rust-keycloak"
3-
version = "0.2.0"
3+
version = "0.3.0"
44
authors = ["Q <q@magicalcodewit.ch>"]
55
edition = "2018"
66

@@ -11,10 +11,10 @@ actix-web = "3"
1111
reqwest = { version = "0.11", features = ["json"] }
1212
url = "2"
1313
serde = { version = "1.0", features = ["derive"] }
14-
serde_json = "1"
14+
serde_json = "1.0"
1515
chrono = { version = "0.4", features = ["serde"] }
1616
rand = "0.8"
17-
alcoholic_jwt = "1"
17+
alcoholic_jwt = "4091"
1818
futures = { version = "0.3", features = ["compat"] }
1919
futures01 = { version = "0.1", package = "futures" }
2020
failure = "0.1"

‎src/.keycloak.rs.swp

-1 KB
Binary file not shown.

‎src/oauth.rs

+48-13
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ pub struct OAuthTokenIntrospectAccess {
3838

3939
#[derive(Debug, Clone, Deserialize)]
4040
pub struct OAuthTokenIntrospect {
41-
pub active: bool,
41+
#[serde(default)]
42+
pub active: Option<bool>,
4243
pub scope: Option<String>,
4344
pub client_id: Option<String>,
4445
pub username: Option<String>,
@@ -72,10 +73,14 @@ impl<'de> serde::de::Visitor<'de> for AudVisitor {
7273
Ok(Some(vec![value.to_string()]))
7374
}
7475

76+
fn visit_string<E: serde::de::Error>(self, value: String) -> Result<Self::Value, E> {
77+
Ok(Some(vec![value]))
78+
}
79+
7580
fn visit_seq<A: serde::de::SeqAccess<'de>>(self, mut value: A) -> Result<Self::Value, A::Error> {
7681
let mut values = vec![];
77-
while let Some(elm) = value.next_element::<&str>()? {
78-
values.push(elm.to_string());
82+
while let Some(elm) = value.next_element::<std::borrow::Cow<'de, str>>()? {
83+
values.push(elm.into_owned());
7984
}
8085
Ok(Some(values))
8186
}
@@ -432,26 +437,56 @@ impl OAuthClient {
432437
pub async fn verify_token<'a, R>(&self, token: &str, role: R) -> Result<OAuthTokenIntrospect, VerifyTokenError>
433438
where R: Into<Option<&'a str>>
434439
{
435-
let i = self.introspect_token(token).await?;
440+
let keys = self.jwks().await?;
441+
let wk = self.well_known().await?;
436442

437-
if !i.active {
438-
return Err(VerifyTokenError::Forbidden);
439-
}
443+
let validations = vec![
444+
alcoholic_jwt::Validation::Audience(self.config.client_id.clone()),
445+
alcoholic_jwt::Validation::Issuer(wk.issuer.clone()),
446+
alcoholic_jwt::Validation::NotExpired,
447+
alcoholic_jwt::Validation::SubjectPresent,
448+
];
449+
450+
let kid = match match alcoholic_jwt::token_kid(token) {
451+
Ok(k) => k,
452+
Err(e) => return Err(VerifyTokenError::InternalServerError(format!("{:?}", e)))
453+
} {
454+
Some(k) => k,
455+
None => return Err(VerifyTokenError::InternalServerError("no token kid".to_string()))
456+
};
457+
458+
let key = match keys.find(&kid) {
459+
Some(k) => k,
460+
None => return Err(VerifyTokenError::InternalServerError("unable to find key".to_string()))
461+
};
462+
463+
let token = match alcoholic_jwt::validate(token, key, validations) {
464+
Ok(k) => k,
465+
Err(e) => {
466+
return Err(VerifyTokenError::Forbidden)
467+
}
468+
};
469+
470+
let data: OAuthTokenIntrospect = match serde_json::from_value(token.claims) {
471+
Ok(c) => c,
472+
Err(e) => {
473+
return Err(VerifyTokenError::InternalServerError(format!("{:?}", e)))
474+
}
475+
};
440476

441477
if let Some(r) = role.into() {
442-
match (&i.aud, &i.resource_access) {
443-
(Some(aud), Some(resource_access)) => {
444-
if !aud.contains(&self.config.client_id) ||
445-
!resource_access.contains_key(&self.config.client_id) ||
478+
match &data.resource_access {
479+
Some(resource_access) => {
480+
if !resource_access.contains_key(&self.config.client_id) ||
446481
!resource_access.get(&self.config.client_id).unwrap().roles.contains(&r.to_owned()) {
447482
return Err(VerifyTokenError::Forbidden);
448483
}
449-
Ok(i)
484+
Ok(data)
450485
}
451486
_ => Err(VerifyTokenError::Forbidden)
452487
}
453488
} else {
454-
Ok(i)
489+
Ok(data)
455490
}
456491
}
457492

0 commit comments

Comments
 (0)
Please sign in to comment.