Start to build userinfo endpoint
This commit is contained in:
@ -8,7 +8,7 @@ use askama::Template;
|
||||
|
||||
use crate::actors::openid_sessions_actor;
|
||||
use crate::actors::openid_sessions_actor::{OpenIDSessionsActor, Session, SessionID};
|
||||
use crate::constants::{AUTHORIZE_URI, CERT_URI, OPEN_ID_ACCESS_TOKEN_LEN, OPEN_ID_ACCESS_TOKEN_TIMEOUT, OPEN_ID_AUTHORIZATION_CODE_LEN, OPEN_ID_AUTHORIZATION_CODE_TIMEOUT, OPEN_ID_REFRESH_TOKEN_LEN, OPEN_ID_REFRESH_TOKEN_TIMEOUT, OPEN_ID_SESSION_LEN, TOKEN_URI};
|
||||
use crate::constants::{AUTHORIZE_URI, CERT_URI, OPEN_ID_ACCESS_TOKEN_LEN, OPEN_ID_ACCESS_TOKEN_TIMEOUT, OPEN_ID_AUTHORIZATION_CODE_LEN, OPEN_ID_AUTHORIZATION_CODE_TIMEOUT, OPEN_ID_REFRESH_TOKEN_LEN, OPEN_ID_REFRESH_TOKEN_TIMEOUT, OPEN_ID_SESSION_LEN, TOKEN_URI, USERINFO_URI};
|
||||
use crate::controllers::base_controller::FatalErrorPage;
|
||||
use crate::data::app_config::AppConfig;
|
||||
use crate::data::client::{ClientID, ClientManager};
|
||||
@ -26,7 +26,7 @@ pub async fn get_configuration(app_conf: web::Data<AppConfig>) -> impl Responder
|
||||
issuer: app_conf.full_url("/"),
|
||||
authorization_endpoint: app_conf.full_url(AUTHORIZE_URI),
|
||||
token_endpoint: app_conf.full_url(TOKEN_URI),
|
||||
userinfo_endpoint: app_conf.full_url("openid/userinfo"),
|
||||
userinfo_endpoint: app_conf.full_url(USERINFO_URI),
|
||||
jwks_uri: app_conf.full_url(CERT_URI),
|
||||
scopes_supported: vec!["openid", "profile", "email"],
|
||||
response_types_supported: vec!["code", "id_token", "token id_token"],
|
||||
@ -387,4 +387,62 @@ struct CertsResponse {
|
||||
|
||||
pub async fn cert_uri(jwt_signer: web::Data<JWTSigner>) -> impl Responder {
|
||||
HttpResponse::Ok().json(CertsResponse { keys: vec![jwt_signer.get_json_web_key()] })
|
||||
}
|
||||
|
||||
fn user_info_error(err: &str, description: &str) -> HttpResponse {
|
||||
HttpResponse::Unauthorized()
|
||||
.insert_header(("WWW-Authenticate", format!(
|
||||
"Bearer error=\"{}\", error_description=\"{}\"",
|
||||
err,
|
||||
description
|
||||
)))
|
||||
.finish()
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
pub struct UserInfoQuery {
|
||||
access_token: Option<String>,
|
||||
}
|
||||
|
||||
pub async fn user_info_post(req: HttpRequest,
|
||||
form: Option<web::Form<UserInfoQuery>>,
|
||||
query: web::Query<UserInfoQuery>) -> impl Responder {
|
||||
user_info(req,
|
||||
form
|
||||
.map(|f| f.0.access_token)
|
||||
.unwrap_or_default()
|
||||
.or(query.0.access_token),
|
||||
).await
|
||||
}
|
||||
|
||||
pub async fn user_info_get(req: HttpRequest, query: web::Query<UserInfoQuery>) -> impl Responder {
|
||||
user_info(req, query.0.access_token).await
|
||||
}
|
||||
|
||||
/// Authenticate request using RFC6750 <https://datatracker.ietf.org/doc/html/rfc6750>///
|
||||
async fn user_info(req: HttpRequest, token: Option<String>) -> impl Responder {
|
||||
let token = match token {
|
||||
Some(t) => t,
|
||||
None => {
|
||||
let token = match req.headers().get("Authorization") {
|
||||
None => return user_info_error("invalid_request", "Missing access token!"),
|
||||
Some(t) => t
|
||||
};
|
||||
|
||||
let token = match token.to_str() {
|
||||
Err(_) => return user_info_error("invalid_request", "Failed to decode token!"),
|
||||
Ok(t) => t,
|
||||
};
|
||||
|
||||
let token = match token.strip_prefix("Bearer ") {
|
||||
None => return user_info_error("invalid_request", "Header token does not start with 'Bearer '!"),
|
||||
Some(t) => t,
|
||||
};
|
||||
|
||||
token.to_string()
|
||||
}
|
||||
};
|
||||
|
||||
// TODO : continue <https://openid.net/specs/openid-connect-core-1_0.html#RFC6749>
|
||||
HttpResponse::Ok().body(format!("token is {}", token))
|
||||
}
|
Reference in New Issue
Block a user