openidconnect-rs
openidconnect-rs copied to clipboard
Question on AdditionalClaims for id_token
Thanks for this awesome lib, I wish I had found it earlier, been doing some of these integrations manually..
I'm testing an integration with Azure and I need to access two non standard claims roles and groups that are sent in the ID token.
I can't figure out how to set a custom claim there though, I thought the following would do:
#[derive(Debug, serde::Deserialize, serde::Serialize)]
struct MSClaims {
groups: Option<Vec<String>>,
roles: Option<Vec<String>>,
}
impl openidconnect::AdditionalClaims for MSClaims {}
type MSClient<
HasAuthUrl = openidconnect::EndpointNotSet,
HasDeviceAuthUrl = openidconnect::EndpointNotSet,
HasIntrospectionUrl = openidconnect::EndpointNotSet,
HasRevocationUrl = openidconnect::EndpointNotSet,
HasTokenUrl = openidconnect::EndpointNotSet,
HasUserInfoUrl = openidconnect::EndpointNotSet,
> = openidconnect::Client<
MSClaims,
openidconnect::core::CoreAuthDisplay,
openidconnect::core::CoreGenderClaim,
openidconnect::core::CoreJweContentEncryptionAlgorithm,
openidconnect::core::CoreJsonWebKey,
openidconnect::core::CoreAuthPrompt,
openidconnect::StandardErrorResponse<openidconnect::core::CoreErrorResponseType>,
openidconnect::core::CoreTokenResponse,
openidconnect::core::CoreTokenIntrospectionResponse,
openidconnect::core::CoreRevocableToken,
openidconnect::core::CoreRevocationErrorResponse,
HasAuthUrl,
HasDeviceAuthUrl,
HasIntrospectionUrl,
HasRevocationUrl,
HasTokenUrl,
HasUserInfoUrl,
>;
let client = MSClient::from_provider_metadata(
provider_metadata,
openidconnect::ClientId::new(CID.to_owned()),
Some(openidconnect::ClientSecret::new(CS.to_owned())),
)
.set_redirect_uri(openidconnect::RedirectUrl::new(
"http://localhost:40000/oidc_callback".to_owned(),
)?);
But that leads to the following errors
error[E0599]: the function or associated item `from_provider_metadata` exists for struct `Client<MSClaims, ..., ..., ..., ..., ..., ..., ..., ..., ..., ..., ..., ..., ..., ..., ..., ...>`, but its trait bounds were not satisfied
--> src/main.rs:64:28
|
64 | let client = MSClient::from_provider_metadata(
| ^^^^^^^^^^^^^^^^^^^^^^ function or associated item cannot be called due to unsatisfied trait bounds
|
::: /Users/frja/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/oauth2-5.0.0/src/token/mod.rs:598:1
|
598 | pub struct StandardTokenResponse<EF, TT>
| ---------------------------------------- doesn't satisfy `_: TokenResponse<MSClaims, CoreGenderClaim, CoreJweContentEncryptionAlgorithm, CoreJwsSigningAlgorithm>`
|
= note: the full type name has been written to '/Users/frja/tmp/sl-test-oidc/tester/target/debug/deps/tester-6ce4f383b7b44458.long-type-15206237441135525973.txt'
= note: consider using `--verbose` to print the full type name to the console
= note: the following trait bounds were not satisfied:
`StandardTokenResponse<IdTokenFields<EmptyAdditionalClaims, EmptyExtraTokenFields, CoreGenderClaim, CoreJweContentEncryptionAlgorithm, CoreJwsSigningAlgorithm>, CoreTokenType>: TokenResponse<MSClaims, CoreGenderClaim, CoreJweContentEncryptionAlgorithm, CoreJwsSigningAlgorithm>`
error[E0277]: the trait bound `StandardTokenResponse<IdTokenFields<EmptyAdditionalClaims, EmptyExtraTokenFields, CoreGenderClaim, CoreJweContentEncryptionAlgorithm, CoreJwsSigningAlgorithm>, CoreTokenType>: TokenResponse<MSClaims, CoreGenderClaim, CoreJweContentEncryptionAlgorithm, CoreJwsSigningAlgorithm>` is not satisfied
--> src/main.rs:64:18
|
64 | let client = MSClient::from_provider_metadata(
| ^^^^^^^^ unsatisfied trait bound
|
= help: the trait `TokenResponse<MSClaims, CoreGenderClaim, CoreJweContentEncryptionAlgorithm, CoreJwsSigningAlgorithm>` is not implemented for `StandardTokenResponse<IdTokenFields<..., ..., ..., ..., ...>, ...>`
but trait `TokenResponse<EmptyAdditionalClaims, CoreGenderClaim, CoreJweContentEncryptionAlgorithm, CoreJwsSigningAlgorithm>` is implemented for it
= help: for that trait implementation, expected `EmptyAdditionalClaims`, found `MSClaims`
note: required by a bound in `openidconnect::Client`
--> /Users/frja/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/openidconnect-4.0.0/src/client.rs:121:9
|
93 | pub struct Client<
| ------ required by a bound in this struct
...
121 | TR: TokenResponse<AC, GC, JE, K::SigningAlgorithm>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Client`
Some errors have detailed explanations: E0277, E0599.
For more information about an error, try `rustc --explain E0277`.
Not sure how to dig myself out of this hole :)
the EmptyAdditionalClaims in the error makes me think you're using CoreClient or one of the CoreIdToken* types somewhere. is it possible client is being coerced to a CoreClient somewhere after the snippet above?
Thanks for getting back to me!
Unfortunately I can reproduce is with this minimal (I hope) code:
async fn test() {
let http_client = openidconnect::reqwest::ClientBuilder::new()
.build().unwrap();
let provider_metadata = openidconnect::core::CoreProviderMetadata::discover_async(
openidconnect::IssuerUrl::new("".to_owned()).unwrap(),
&http_client,
)
.await.unwrap();
let client = MSClient::from_provider_metadata(
provider_metadata,
openidconnect::ClientId::new("".to_owned()),
Some(openidconnect::ClientSecret::new("".to_owned())),
);
}
Turns out I had to fix the TokenResponse as well.
The following typedefs works well.
#[derive(Debug, serde::Deserialize, serde::Serialize)]
struct MSClaims {
groups: Option<Vec<String>>,
roles: Option<Vec<String>>,
}
impl openidconnect::AdditionalClaims for MSClaims {}
type MSTokenFields = openidconnect::IdTokenFields<
MSClaims,
openidconnect::EmptyExtraTokenFields,
openidconnect::core::CoreGenderClaim,
openidconnect::core::CoreJweContentEncryptionAlgorithm,
openidconnect::core::CoreJwsSigningAlgorithm,
>;
pub type MSTokenResponse =
openidconnect::StandardTokenResponse<MSTokenFields, openidconnect::core::CoreTokenType>;
type MSClient<
HasAuthUrl = openidconnect::EndpointNotSet,
HasDeviceAuthUrl = openidconnect::EndpointNotSet,
HasIntrospectionUrl = openidconnect::EndpointNotSet,
HasRevocationUrl = openidconnect::EndpointNotSet,
HasTokenUrl = openidconnect::EndpointNotSet,
HasUserInfoUrl = openidconnect::EndpointNotSet,
> = openidconnect::Client<
MSClaims,
openidconnect::core::CoreAuthDisplay,
openidconnect::core::CoreGenderClaim,
openidconnect::core::CoreJweContentEncryptionAlgorithm,
openidconnect::core::CoreJsonWebKey,
openidconnect::core::CoreAuthPrompt,
openidconnect::StandardErrorResponse<openidconnect::core::CoreErrorResponseType>,
MSTokenResponse,
openidconnect::core::CoreTokenIntrospectionResponse,
openidconnect::core::CoreRevocableToken,
openidconnect::core::CoreRevocationErrorResponse,
HasAuthUrl,
HasDeviceAuthUrl,
HasIntrospectionUrl,
HasRevocationUrl,
HasTokenUrl,
HasUserInfoUrl,
>;
Let me know if you want me to document this somehow