pub fn authorize_callback(
model: &AuthorizationModel,
pending: &PendingAuthorization,
callback: &AuthorizationCallback,
) -> Result<AuthorizedCode, CallbackError>Expand description
Validate an authorization callback against the request that started it.
Checks, in this order and for the reasons in the module documentation:
state, then iss, then whether the response carries a grant or a refusal.
§Errors
CallbackError::StateMismatch if the state is absent or different —
checked first so that neither a forged success nor a forged refusal can be
acted on. CallbackError::Issuer if a present iss names another server.
CallbackError::Refused if the server refused, carrying its error code.
CallbackError::NoOutcome if the response carries neither a code nor an
error.
§Examples
use protocol_droid::domain::ProtocolVersion;
use protocol_droid::domain::mcp::authorization::authorization_model;
use protocol_droid::domain::mcp::resource_metadata::ResourceUri;
use protocol_droid::domain::oauth::registration::{ClientId, RegisteredClient};
use protocol_droid::domain::oauth::resource::ResourceParameters;
use protocol_droid::application::oauth::client::{AuthorizationSecrets, SecretError, State, begin_authorization};
use protocol_droid::application::oauth::callback::{AuthorizationCallback, authorize_callback};
use protocol_droid::domain::oauth::pkce::{ChallengeMethod, CodeVerifier};
struct Fixed;
impl AuthorizationSecrets for Fixed {
fn new_state(&self) -> Result<State, SecretError> { Ok(State::new("state-value")) }
fn new_code_verifier(&self) -> Result<CodeVerifier, SecretError> {
CodeVerifier::new("a".repeat(43)).map_err(|_| SecretError::Rejected)
}
}
let model = authorization_model(ProtocolVersion::V2026_07_28);
let client = RegisteredClient::from_metadata_document(
"https://auth.example.com",
ClientId::metadata_url("https://client.example.com/metadata.json")?,
);
let resource = ResourceUri::new("https://api.example.com/app")?;
let pending = begin_authorization(
&model, &client, "https://client.example.com/callback",
ResourceParameters::single(&resource), &Fixed,
)?;
let callback = AuthorizationCallback::granted("the-code", "state-value");
let authorized = authorize_callback(&model, &pending, &callback)?;
assert_eq!(authorized.code(), "the-code");
assert!(authorize_callback(&model, &pending, &AuthorizationCallback::granted("c", "wrong")).is_err());