You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-11-23 11:02:35 +03:00
PKCE support
This commit is contained in:
@@ -168,7 +168,7 @@ struct Params {
|
||||
auth: AuthorizationRequest,
|
||||
|
||||
#[serde(flatten)]
|
||||
pkce: Option<pkce::Request>,
|
||||
pkce: Option<pkce::AuthorizationRequest>,
|
||||
}
|
||||
|
||||
/// Given a list of response types and an optional user-defined response mode,
|
||||
@@ -349,7 +349,7 @@ async fn get(
|
||||
.add_code(&mut txn, &code, ¶ms.pkce)
|
||||
.await
|
||||
.wrap_error()?;
|
||||
};
|
||||
}
|
||||
|
||||
// Do we already have a user session for this oauth2 session?
|
||||
let user_session = oauth2_session.fetch_session(&mut txn).await.wrap_error()?;
|
||||
|
||||
@@ -16,6 +16,7 @@ use std::collections::HashSet;
|
||||
|
||||
use oauth2_types::{
|
||||
oidc::Metadata,
|
||||
pkce::CodeChallengeMethod,
|
||||
requests::{ClientAuthenticationMethod, GrantType, ResponseMode},
|
||||
};
|
||||
use warp::{Filter, Rejection, Reply};
|
||||
@@ -62,6 +63,13 @@ pub(super) fn filter(
|
||||
s
|
||||
});
|
||||
|
||||
let code_challenge_methods_supported = Some({
|
||||
let mut s = HashSet::new();
|
||||
s.insert(CodeChallengeMethod::Plain);
|
||||
s.insert(CodeChallengeMethod::S256);
|
||||
s
|
||||
});
|
||||
|
||||
let metadata = Metadata {
|
||||
authorization_endpoint: base.join("oauth2/authorize").ok(),
|
||||
token_endpoint: base.join("oauth2/token").ok(),
|
||||
@@ -75,7 +83,7 @@ pub(super) fn filter(
|
||||
response_modes_supported,
|
||||
grant_types_supported,
|
||||
token_endpoint_auth_methods_supported,
|
||||
code_challenge_methods_supported: None,
|
||||
code_challenge_methods_supported,
|
||||
};
|
||||
|
||||
let cors = warp::cors().allow_any_origin();
|
||||
|
||||
@@ -19,7 +19,10 @@ use headers::{CacheControl, Pragma};
|
||||
use hyper::StatusCode;
|
||||
use jwt_compact::{Claims, Header, TimeOptions};
|
||||
use oauth2_types::{
|
||||
errors::{InvalidGrant, OAuth2Error, OAuth2ErrorCode, UnauthorizedClient},
|
||||
errors::{
|
||||
InvalidGrant, InvalidRequest, OAuth2Error, OAuth2ErrorCode, ServerError, UnauthorizedClient,
|
||||
},
|
||||
pkce::CodeChallengeMethod,
|
||||
requests::{
|
||||
AccessTokenRequest, AccessTokenResponse, AuthorizationCodeGrant, RefreshTokenGrant,
|
||||
},
|
||||
@@ -166,6 +169,34 @@ async fn authorization_code_grant(
|
||||
return error(UnauthorizedClient);
|
||||
}
|
||||
|
||||
match (
|
||||
code.code_challenge_method.as_ref(),
|
||||
code.code_challenge.as_ref(),
|
||||
grant.code_verifier.as_ref(),
|
||||
) {
|
||||
(None, None, None) => {}
|
||||
// We have a challenge but no verifier (or vice-versa)? Bad request.
|
||||
(Some(_), Some(_), None) | (None, None, Some(_)) => return error(InvalidRequest),
|
||||
(Some(0 /* Plain */), Some(code_challenge), Some(code_verifier)) => {
|
||||
if !CodeChallengeMethod::Plain.verify(code_challenge, code_verifier) {
|
||||
return error(InvalidRequest);
|
||||
}
|
||||
}
|
||||
(Some(1 /* S256 */), Some(code_challenge), Some(code_verifier)) => {
|
||||
if !CodeChallengeMethod::S256.verify(code_challenge, code_verifier) {
|
||||
return error(InvalidRequest);
|
||||
}
|
||||
}
|
||||
|
||||
// We have something else?
|
||||
// That's a DB inconcistancy, we should bail out
|
||||
_ => {
|
||||
// TODO: are we sure we want to handle errors like that?
|
||||
tracing::error!("Invalid state from the database");
|
||||
return error(ServerError); // Somthing bad happened in the database
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: verify PKCE
|
||||
let ttl = Duration::minutes(5);
|
||||
let (access_token, refresh_token) = {
|
||||
|
||||
Reference in New Issue
Block a user