Open lcmgh opened 3 weeks ago
On my macOS machine it works fine, on colleague's machine not. The token that we are sending over also looks good.
Hi, this is a signing key refresh error, are you sure that your jwks endpoint is available (or correct in you .well-known/openid-configuration)? This depends of you key store refresh strategie,
Some colleagues are facing this issue always on their Mac Machine while it always works fine on mine.
I am actually spawning a mock server
/// Spawns tokio task that runs OIDC mock web server to serve public keys and well-known config.
///
/// Endpoints:
/// * `<address>/.well-known/openid-configuration`: Serves `tests/config/openid-configuration.json`
/// * `<address>/keys`: Serves public keys from `tests/config/public1.jwks`
pub async fn spawn_oidc_server_task(addr: SocketAddr) {
#[derive(Clone)]
struct AppState {
pub port: u16,
}
async fn oidc_key_handler() -> &'static str {
include_str!("../tests/config/public1.jwks")
}
async fn oidc_well_known_handler(State(state): State<AppState>) -> Json<Value> {
let mut c: Value =
serde_json::from_str(include_str!("../tests/config/openid-configuration.json"))
.unwrap();
c["issuer"] = format!("http://localhost:{}", state.port).into();
c["jwks_uri"] = format!("http://localhost:{}/keys", state.port).into();
Json(c)
}
// Start fake OIDC server that just serves keys
let oidc_server = Router::new().route("/keys", get(oidc_key_handler)).route(
"/.well-known/openid-configuration",
get(oidc_well_known_handler).with_state(AppState { port: addr.port() }),
);
tokio::task::spawn(async move {
let listener = TcpListener::bind(&addr).await.unwrap();
axum::serve(listener, oidc_server.into_make_service())
.await
.expect("failed to spawn oidc server");
});
}
During tests client generates tokens via
/// Creates authentication token signed by server `fn spawn_oidc_server_task`.
pub fn create_signed_token(
aud: &str,
namespace: &str,
service_account_name: &str,
sub: &str,
provider_url: &str,
) -> Token<Header, KubernetesClaims, Signed> {
let pem = include_bytes!("../tests/config/rsa-private1.pem");
let key = PKey::private_key_from_pem(pem).unwrap();
let algorithm = PKeyWithDigest {
digest: MessageDigest::sha256(),
key: key.clone(),
};
let header = Header {
algorithm: AlgorithmType::Rs256,
..Default::default()
};
// Timetamp now + 1 hour
let exp = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs()
+ 84000;
let exp_str = exp.to_string();
let nbf = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs()
- 100;
let nbf_str = nbf.to_string();
let claims = KubernetesClaims {
iss: Some(provider_url.to_string()),
sub: Some(sub.to_string()),
aud: Some(CustomOneOrArray::Array(vec![aud.to_string()])),
exp: Some(serde_json::from_str(&exp_str).unwrap()),
nbf: Some(serde_json::from_str(&nbf_str).unwrap()),
iat: Some(serde_json::from_str(&nbf_str).unwrap()),
jti: None,
kubernetes_io: Some(KubernetesClaim {
namespace: namespace.to_string(),
pod: PodClaim {
name: "amui-85676447b8-qwkd5".to_string(),
uid: "008da9e0-e53c-43b4-b2b1-a0a85d824915".to_string(),
},
serviceaccount: ServiceAccountClaim {
name: service_account_name.to_string(),
uid: "d13b6723-6dda-4937-8623-c6fb798bda09".to_string(),
},
}),
};
Token::new(header, claims)
.sign_with_key(&algorithm)
.unwrap()
}
openid-configuration.json
{
"issuer": "http://localhost:3000",
"jwks_uri": "http://localhost:3000/keys",
"authorization_endpoint": "urn:kubernetes:programmatic_authorization",
"response_types_supported": [
"id_token"
],
"subject_types_supported": [
"public"
],
"claims_supported": [
"sub",
"iss"
],
"id_token_signing_alg_values_supported": [
"RS256"
]
}
The message " EOF while parsing a value at line 1 column 0" comes from serde_json when you are trying to parse an empty string.
#[derive(Deserialize)]
struct XY {}
let r: Result<XY, serde_json::Error> = serde_json::from_str("");
assert_eq!(r.err().unwrap().to_string(), "EOF while parsing a value at line 1 column 0");
I think the jwks endpoint must be sending an empty response, (maybe with an error status, that is not well checked and reported by jwt-authorizer ... should be fixed), have you proxies or some proxy configuration on your machines? oran anti virus that can intercept responses?
This new commit 10a926c should be helpful to better identify the cause of such an issue, in fact before if the jwks endpoint responded with an error status it was ignored and the content (maybe empty) parsed thus resulting in a json parsing error.
We are facing the issue that on some machines we do not face any issues while on other the authorizer throws this:
I am not sure here why we get a parsing error AND a InvalidKeyAlg in here. Is there some kind of OS dependency necessary to make RS256 work?!