Skip to content

Commit

Permalink
Set expected audience to jsonwebtoken validation option to get ID tok…
Browse files Browse the repository at this point in the history
…en (#249)

jsonwebtoken validate audience as default validation rule. But audiecen
is not set. So set "target_audience" in the claim as expected audience.

target_audiecen:
https://cloud.google.com/iap/docs/authentication-howto?hl=ja#bash

See for more details:
#248
  • Loading branch information
h-michael authored Apr 12, 2024
1 parent e789b5b commit ff65df4
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 15 deletions.
3 changes: 3 additions & 0 deletions foundation/auth/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,7 @@ pub enum Error {

#[error("unexpected impersonation token response : status={0}, detail={1}")]
UnexpectedImpersonateTokenResponse(u16, String),

#[error("No target_audience Found in the private claims")]
NoTargetAudienceFound,
}
7 changes: 4 additions & 3 deletions foundation/auth/src/token_source/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,18 @@ struct ExpClaim {
}

impl InternalIdToken {
fn to_token(&self) -> Result<Token, Error> {
fn to_token(&self, audience: &str) -> Result<Token, Error> {
Ok(Token {
access_token: self.id_token.clone(),
token_type: "Bearer".into(),
expiry: time::OffsetDateTime::from_unix_timestamp(self.get_exp()?).ok(),
expiry: time::OffsetDateTime::from_unix_timestamp(self.get_exp(audience)?).ok(),
})
}

fn get_exp(&self) -> Result<i64, Error> {
fn get_exp(&self, audience: &str) -> Result<i64, Error> {
let mut validation = jsonwebtoken::Validation::default();
validation.insecure_disable_signature_validation();
validation.set_audience(&[audience]);
let decoding_key = jsonwebtoken::DecodingKey::from_secret(b"");
Ok(
jsonwebtoken::decode::<ExpClaim>(self.id_token.as_str(), &decoding_key, &validation)?
Expand Down
32 changes: 20 additions & 12 deletions foundation/auth/src/token_source/service_account_token_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,32 +176,40 @@ impl TokenSource for OAuth2ServiceAccountTokenSource {
let iat = OffsetDateTime::now_utc();
let exp = iat + time::Duration::hours(1);

let request_token = Claims {
let claims = Claims {
iss: self.email.as_ref(),
sub: self.sub.as_ref().map(|s| s.as_ref()),
scope: Some(self.scopes.as_ref()),
aud: self.token_url.as_ref(),
exp: exp.unix_timestamp(),
iat: iat.unix_timestamp(),
private_claims: &self.private_claims,
}
.token(&self.pk, &self.pk_id)?;
};
let request_token = claims.token(&self.pk, &self.pk_id)?;

let form = [
("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer"),
("assertion", request_token.as_str()),
];

match self.use_id_token {
true => Ok(self
.client
.post(self.token_url.as_str())
.form(&form)
.send()
.await?
.json::<InternalIdToken>()
.await?
.to_token()?),
true => {
let audience = claims
.private_claims
.get("target_audience")
.ok_or(Error::NoTargetAudienceFound)?
.as_str()
.ok_or(Error::NoTargetAudienceFound)?;
Ok(self
.client
.post(self.token_url.as_str())
.form(&form)
.send()
.await?
.json::<InternalIdToken>()
.await?
.to_token(audience)?)
}
false => Ok(self
.client
.post(self.token_url.as_str())
Expand Down

0 comments on commit ff65df4

Please sign in to comment.