ramosbugs / openidconnect-rs

OpenID Connect Library for Rust

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Implementing device authorisation flow

ljyanesm opened this issue · comments

Hi,

I've been using this crate for implementing oidc. But, have found a small difficulty with implementing the device grant authorization flow (https://developer.okta.com/docs/guides/device-authorization-grant/main/). The main difficult I am bumping into is that although one can extend the ProviderMetadata type to include some additional fields.

// Teach openidconnect-rs about the device authorization url.
#[derive(Clone, Debug, Deserialize, Serialize)]
struct DeviceEndpointProviderMetadata {
    device_authorization_endpoint: String,
}
impl AdditionalProviderMetadata for DeviceEndpointProviderMetadata {}
type DeviceAuthorizationProviderMetadata = ProviderMetadata<
    DeviceEndpointProviderMetadata,
    CoreAuthDisplay,
    CoreClientAuthMethod,
    CoreClaimName,
    CoreClaimType,
    CoreGrantType,
    CoreJweContentEncryptionAlgorithm,
    CoreJweKeyManagementAlgorithm,
    CoreJwsSigningAlgorithm,
    CoreJsonWebKeyType,
    CoreJsonWebKeyUse,
    CoreJsonWebKey,
    CoreResponseMode,
    CoreResponseType,
    CoreSubjectIdentifierType,
>;

Having the device_authorization_endpoint in the ProviderMetadata object is not enough to populate the underlaying oauth2::Client in the CoreClient as the internal device_authorization_url: Option<DeviceAuthorizationUrl> field is not reachable from outside the openidconnect-rs crate.

Given there's neither a method to populate the device_authorization_url in the CoreClient nor some way (that I know of, if there's one please let me know) to extend the CoreClient, implementing this flow becomes a bit tricky.

The current only option I think I have is making a full copy of the CoreClient in my crate to add some functionality to populate the device_authorization_url in the oauth2::Client in the new method or from_provider_metadata and add a couple of methods to expose it and prepare requests against it, but that would be mostly repeating the same code in the existing CoreClient.

Maybe I am holding it wrong?

Apologies if this is the case. Any guidance you could possibly share for implementing the device grant authorization flow would be appreciated.

Thank you very much for this crate,
Luis

Hi @ljyanesm,

As you mentioned, this crate doesn't currently expose an interface for leveraging the oauth2 crate's support for the device authorization flow. I would be happy to accept a PR that does the following:

  • Adds Client::device_authorization_url(), Client::set_device_authorization_url(), Client::exchange_device_access_token(), and Client::exchange_device_code() methods that forward the calls to the inner oauth2_client
  • Re-exports the relevant types from oauth2 (e.g., DeviceAccessTokenRequest) so that users don't need to directly depend on that crate
  • Adds OAuth 2.0 Device Authorization Grant to the list of supported standards in the README

This is similar to the work done in #39 to expose two other features from the oauth2 crate via this crate.

I don't see any standards that define a device_authorization_endpoint field in the OIDC provider metadata (please let me know if you're aware of one), so that would still be a vendor-specific field that users need to define themselves using AdditionalProviderMetadata as you showed above. It might be useful to add a working Okta example that leverages this, though.

@ramosbugs,

Would it be possible for you to, please, cut a release for these changes if not too much to ask? Happy to wait it out if something else is getting worked on.

Thanks again for the crate and the help with the PR.

Just released 3.2.0 with this change!