Start to build userinfo endpoint

This commit is contained in:
2022-04-14 18:39:18 +02:00
parent 27cee8d3a0
commit b867016a71
4 changed files with 65 additions and 4 deletions

View File

@ -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))
}