-
Notifications
You must be signed in to change notification settings - Fork 131
feat(auth): allow customers to provide a SubjectTokenProvider impl #2383
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
56be8e6
094c769
11573ee
d15957d
4ee6c3a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,13 +26,31 @@ use crate::{BuildResult, Result}; | |
| use http::{Extensions, HeaderMap}; | ||
| use serde::{Deserialize, Serialize}; | ||
| use serde_json::Value; | ||
| use std::future::Future; | ||
| use std::sync::Arc; | ||
| use tokio::time::{Duration, Instant}; | ||
|
|
||
| #[async_trait::async_trait] | ||
| pub trait SubjectTokenProvider: std::fmt::Debug + Send + Sync { | ||
| /// Generate subject token that will be used on STS exchange. | ||
| async fn subject_token(&self) -> Result<String>; | ||
| fn subject_token(&self) -> impl Future<Output = Result<String>> + Send; | ||
| } | ||
|
Comment on lines
+35
to
+37
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So to override this I need to implement my own client, error detection, parsing, etc.? Bummer.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the main point of this custom subject token provider is indeed for the customer own all the stack around fetching the subject token, specially in complex scenarios like the ones we discussed where the customers needs to use a custom openssl version and other details. I think we are also evaluating how to allow injecting custom headers and/or provide a custom http client cc @sai-sunder-s
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah this is for people with advanced use case and know what they are doing. It is just complete freedom to do whatever they want. Yes that means they have to handle error detection and parsing as well but that should be ok. For example, they know best how to handle a kerberos error. |
||
|
|
||
| pub(crate) mod dynamic { | ||
| use super::Result; | ||
| #[async_trait::async_trait] | ||
| pub trait SubjectTokenProvider: std::fmt::Debug + Send + Sync { | ||
| /// Generate subject token that will be used on STS exchange. | ||
| async fn subject_token(&self) -> Result<String>; | ||
| } | ||
|
|
||
| #[async_trait::async_trait] | ||
| impl<T> SubjectTokenProvider for T | ||
| where | ||
| T: super::SubjectTokenProvider, | ||
| { | ||
| async fn subject_token(&self) -> Result<String> { | ||
| T::subject_token(self).await | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] | ||
|
|
@@ -72,7 +90,7 @@ impl CredentialSource { | |
| } | ||
| } | ||
|
|
||
| fn make_credentials_from_provider<T: SubjectTokenProvider + 'static>( | ||
| fn make_credentials_from_provider<T: dynamic::SubjectTokenProvider + 'static>( | ||
| subject_token_provider: T, | ||
| config: ExternalAccountConfig, | ||
| quota_project_id: Option<String>, | ||
|
|
@@ -103,7 +121,7 @@ struct ExternalAccountConfig { | |
| #[derive(Debug)] | ||
| struct ExternalAccountTokenProvider<T> | ||
| where | ||
| T: SubjectTokenProvider, | ||
| T: dynamic::SubjectTokenProvider, | ||
| { | ||
| subject_token_provider: T, | ||
| config: ExternalAccountConfig, | ||
|
|
@@ -112,7 +130,7 @@ where | |
| #[async_trait::async_trait] | ||
| impl<T> TokenProvider for ExternalAccountTokenProvider<T> | ||
| where | ||
| T: SubjectTokenProvider, | ||
| T: dynamic::SubjectTokenProvider, | ||
| { | ||
| async fn token(&self) -> Result<Token> { | ||
| let subject_token = self.subject_token_provider.subject_token().await?; | ||
|
|
@@ -208,7 +226,7 @@ pub struct Builder { | |
| external_account_config: Value, | ||
| quota_project_id: Option<String>, | ||
| scopes: Option<Vec<String>>, | ||
| subject_token_provider: Option<Box<dyn SubjectTokenProvider>>, | ||
| subject_token_provider: Option<Box<dyn dynamic::SubjectTokenProvider>>, | ||
| } | ||
|
|
||
| impl Builder { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the advantage of using a trait with a single function vs. a thing that implements the
AsyncFntrait?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TIL
AsyncFn. Gonna check it out how to use that. But to your point, I was just trying to follow the same pattern from the repo with things likeCredentialsProvider, but this one in particular has two methods, so makes sense to be a trait.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AsyncFn is a Rust 2024 feature.... I feat it might not work if the caller is using Rust Edition 2021, so make sure it does, otherwise the trait is a better idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trying to use
AsyncFnand as it's optional on theexternal_account::Builder, I'm not finding a way to use withoutdynandAsyncFnis notdyncompatible. Any tips ?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Says here that asyncfn is nightly-only experimental API https://doc.rust-lang.org/std/ops/trait.AsyncFn.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is not quite right.
AsyncFnis stable:rust-lang/rust#132706
Manually implementing the
AsyncFntrait is not stable. That is, you cannot sayimpl AsyncFn for MyType ...because the types and methods of the trait are unstable. But you can assume thatAsyncFnwill be around, and that you can call such functions.As to the
dyn-compatibleproblems: you could solve that with a private trait:But overall it seems that
AsyncFnis more trouble than it is worth.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Thank you for the context!.