fix(oauth): rfc8414 should judement the response_types (#485)
response_types_supported should be judement while try to do 'Authorization Code Flow' Signed-off-by: jokemanfire <hu.dingyang@zte.com.cn>
This commit is contained in:
parent
d4fcac02f8
commit
bce0555068
2 changed files with 21 additions and 2 deletions
|
|
@ -154,7 +154,7 @@ pub enum AuthError {
|
|||
}
|
||||
|
||||
/// oauth2 metadata
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, Default)]
|
||||
pub struct AuthorizationMetadata {
|
||||
pub authorization_endpoint: String,
|
||||
pub token_endpoint: String,
|
||||
|
|
@ -162,6 +162,7 @@ pub struct AuthorizationMetadata {
|
|||
pub issuer: Option<String>,
|
||||
pub jwks_uri: Option<String>,
|
||||
pub scopes_supported: Option<Vec<String>>,
|
||||
pub response_types_supported: Option<Vec<String>>,
|
||||
// allow additional fields
|
||||
#[serde(flatten)]
|
||||
pub additional_fields: HashMap<String, serde_json::Value>,
|
||||
|
|
@ -379,7 +380,17 @@ impl AuthorizationManager {
|
|||
self.oauth_client = Some(client_builder);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// validate if the server support the response type
|
||||
fn validate_response_supported(&self, response_type: &str) -> Result<(), AuthError> {
|
||||
if let Some(metadata) = self.metadata.as_ref() {
|
||||
if let Some(response_types_supported) = metadata.response_types_supported.as_ref() {
|
||||
if !response_types_supported.contains(&response_type.to_string()) {
|
||||
return Err(AuthError::InvalidScope(response_type.to_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
/// dynamic register oauth2 client
|
||||
pub async fn register_client(
|
||||
&mut self,
|
||||
|
|
@ -397,6 +408,10 @@ impl AuthorizationManager {
|
|||
));
|
||||
};
|
||||
|
||||
// RFC 8414 RECOMMENDS response_types_supported in the metadata. This field is optional,
|
||||
// but if present and does not include the flow we use ("code"), bail out early with a clear error.
|
||||
self.validate_response_supported("code")?;
|
||||
|
||||
let registration_request = ClientRegistrationRequest {
|
||||
client_name: name.to_string(),
|
||||
redirect_uris: vec![redirect_uri.to_string()],
|
||||
|
|
@ -485,6 +500,9 @@ impl AuthorizationManager {
|
|||
.as_ref()
|
||||
.ok_or_else(|| AuthError::InternalError("OAuth client not configured".to_string()))?;
|
||||
|
||||
// ensure the server supports the response type we intend to use when metadata is available
|
||||
self.validate_response_supported("code")?;
|
||||
|
||||
// generate pkce challenge
|
||||
let (pkce_challenge, pkce_verifier) = PkceCodeChallenge::new_random_sha256();
|
||||
|
||||
|
|
|
|||
|
|
@ -529,6 +529,7 @@ async fn oauth_authorization_server() -> impl IntoResponse {
|
|||
token_endpoint: format!("http://{}/oauth/token", BIND_ADDRESS),
|
||||
scopes_supported: Some(vec!["profile".to_string(), "email".to_string()]),
|
||||
registration_endpoint: Some(format!("http://{}/oauth/register", BIND_ADDRESS)),
|
||||
response_types_supported: Some(vec!["code".to_string()]),
|
||||
issuer: Some(BIND_ADDRESS.to_string()),
|
||||
jwks_uri: Some(format!("http://{}/oauth/jwks", BIND_ADDRESS)),
|
||||
additional_fields,
|
||||
|
|
|
|||
Loading…
Reference in a new issue