Skip to content

Commit 125dbfd

Browse files
authored
fix!: reject missing issuer in authorization server metadata by default (#1054)
1 parent c284607 commit 125dbfd

1 file changed

Lines changed: 18 additions & 18 deletions

File tree

crates/rmcp/src/transport/auth.rs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,7 +1013,7 @@ pub struct AuthorizationManager {
10131013
resource_scopes: RwLock<Vec<String>>,
10141014
/// OIDC Dynamic Client Registration `application_type` (SEP-837)
10151015
application_type: Option<String>,
1016-
strict_issuer_validation: bool,
1016+
allow_missing_issuer: bool,
10171017
}
10181018

10191019
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -1259,7 +1259,7 @@ impl AuthorizationManager {
12591259
www_auth_scopes: RwLock::new(Vec::new()),
12601260
resource_scopes: RwLock::new(Vec::new()),
12611261
application_type: Some(DEFAULT_APPLICATION_TYPE.to_string()),
1262-
strict_issuer_validation: false,
1262+
allow_missing_issuer: false,
12631263
};
12641264

12651265
Ok(manager)
@@ -1270,15 +1270,15 @@ impl AuthorizationManager {
12701270
self.scope_upgrade_config = config;
12711271
}
12721272

1273-
/// Configure whether authorization server metadata discovery requires the
1274-
/// metadata `issuer` field.
1273+
/// Configure whether authorization server metadata discovery tolerates a
1274+
/// missing `issuer` field.
12751275
///
1276-
/// The default is `false` to preserve compatibility with legacy
1277-
/// authorization servers that omit `issuer`. Set this to `true` to enforce
1278-
/// the RFC 8414/OIDC requirement that discovered metadata include `issuer`
1279-
/// whenever the expected issuer can be derived from the discovery URL.
1280-
pub fn set_strict_issuer_validation(&mut self, strict: bool) {
1281-
self.strict_issuer_validation = strict;
1276+
/// The default is `false`, enforcing the RFC 8414/OIDC requirement that
1277+
/// discovered metadata include `issuer` whenever the expected issuer can be
1278+
/// derived from the discovery URL. Set this to `true` only for compatibility
1279+
/// with authorization servers that return incomplete metadata.
1280+
pub fn set_allow_missing_issuer(&mut self, allow: bool) {
1281+
self.allow_missing_issuer = allow;
12821282
}
12831283

12841284
/// Set a custom credential store
@@ -2370,10 +2370,10 @@ impl AuthorizationManager {
23702370
return Ok(());
23712371
};
23722372
let Some(received_issuer) = metadata.issuer.as_deref() else {
2373-
if self.strict_issuer_validation {
2374-
return Err(AuthError::AuthorizationServerMissingIssuer { expected_issuer });
2373+
if self.allow_missing_issuer {
2374+
return Ok(());
23752375
}
2376-
return Ok(());
2376+
return Err(AuthError::AuthorizationServerMissingIssuer { expected_issuer });
23772377
};
23782378
if !Self::issuer_identifiers_match(received_issuer, &expected_issuer) {
23792379
return Err(AuthError::AuthorizationServerMismatch {
@@ -4095,7 +4095,7 @@ mod tests {
40954095
}
40964096

40974097
#[tokio::test]
4098-
async fn authorization_metadata_allows_missing_issuer_by_default() {
4098+
async fn authorization_metadata_allows_missing_issuer_when_configured() {
40994099
let discovery_url =
41004100
Url::parse("https://auth.example.com/.well-known/openid-configuration/tenant1")
41014101
.unwrap();
@@ -4106,17 +4106,18 @@ mod tests {
41064106
..Default::default()
41074107
};
41084108

4109-
let manager = AuthorizationManager::new("https://mcp.example.com/")
4109+
let mut manager = AuthorizationManager::new("https://mcp.example.com/")
41104110
.await
41114111
.unwrap();
4112+
manager.set_allow_missing_issuer(true);
41124113

41134114
manager
41144115
.validate_authorization_metadata_issuer(&discovery_url, &metadata)
41154116
.unwrap();
41164117
}
41174118

41184119
#[tokio::test]
4119-
async fn authorization_metadata_rejects_missing_issuer_when_required() {
4120+
async fn authorization_metadata_rejects_missing_issuer_by_default() {
41204121
let discovery_url =
41214122
Url::parse("https://auth.example.com/.well-known/openid-configuration/tenant1")
41224123
.unwrap();
@@ -4126,10 +4127,9 @@ mod tests {
41264127
token_endpoint: "https://auth.example.com/tenant1/token".to_string(),
41274128
..Default::default()
41284129
};
4129-
let mut manager = AuthorizationManager::new("https://mcp.example.com/")
4130+
let manager = AuthorizationManager::new("https://mcp.example.com/")
41304131
.await
41314132
.unwrap();
4132-
manager.set_strict_issuer_validation(true);
41334133

41344134
let error = manager
41354135
.validate_authorization_metadata_issuer(&discovery_url, &metadata)

0 commit comments

Comments
 (0)