Crates.io | graph-oauth |
lib.rs | graph-oauth |
version | 2.0.2 |
source | src |
created_at | 2020-12-13 11:56:35.565354 |
updated_at | 2024-10-10 09:35:14.233502 |
description | Rust SDK Client for Microsoft Identity Platform |
homepage | https://github.com/sreeise/graph-rs-sdk |
repository | https://github.com/sreeise/graph-rs-sdk |
max_upload_size | |
id | 322387 |
size | 486,012 |
Support for:
interactive-auth
]openssl
]OAuth and Openid client for Microsoft Graph as part of the graph-rs-sdk project. This project can however be used outside graph-rs-sdk as an OAuth client for Microsoft Identity Platform or by using graph-rs-sdk.
For async:
graph-oauth = "2.0.1"
tokio = { version = "1.25.0", features = ["full"] }
For blocking:
graph-oauth = "2.0.1"
native-tls
: Use the native-tls
TLS backend (OpenSSL on *nix, SChannel on Windows, Secure Transport on macOS).rustls-tls
: Use the rustls-tls
TLS backend (cross-platform backend, only supports TLS 1.2 and 1.3).interactive-auth
: Interactive Authentication using the wry crate to run web view on
platforms that support it such as on a desktop.openssl
: Use X509 Certificates from the openssl crate in the OAuth2 and OpenId Connect flows.Default features: default=["native-tls"]
These features enable the native-tls and rustls-tls features in the reqwest crate. For more info see the reqwest crate.
The following examples use the anyhow
crate for its Result type. It is also recommended that users
of this crate use the anyhow
crate for better error handling.
The crate is undergoing major development in order to support all or most scenarios in the Microsoft Identity Platform where its possible to do so. The master branch on GitHub may have some unstable features. Any version that is not a pre-release version of the crate is considered stable.
Use application builders to store your auth configuration and have the client handle the access token requests for you.
There are two main types for building your chosen OAuth or OpenId Connect Flow.
PublicClientApplication
ConfidentialClientApplication
Once you have built a ConfidentialClientApplication
or a PublicClientApplication
you can pass these to the graph client.
Automatic token refresh is also done by passing the ConfidentialClientApplication
or the
PublicClientApplication
to the Graph
client.
For more extensive examples see the OAuth Examples in the examples/oauth directory on GitHub.
let confidental_client: ConfidentialClientApplication<ClientSecretCredential> = ...
let graph_client = Graph::from(confidential_client);
The authorization code grant is considered a confidential client (except in the hybrid flow) and we can get an access token by using the authorization code returned in the query of the URL on redirect after sign in is performed by the user.
Once you have the authorization code you can pass this to the client and the client will perform the request to get an access token on the first graph api call that you make.
use graph_rs_sdk::{
Graph,
oauth::ConfidentialClientApplication,
};
async fn build_client(
authorization_code: &str,
client_id: &str,
client_secret: &str,
redirect_uri: url::Url,
scope: Vec<&str>
) -> anyhow::Result<GraphClient> {
let mut confidential_client = ConfidentialClientApplication::builder(client_id)
.with_authorization_code(authorization_code) // returns builder type for AuthorizationCodeCredential
.with_client_secret(client_secret)
.with_scope(scope)
.with_redirect_uri(redirect_uri)?
.build();
let graph_client = Graph::from(&confidential_client);
Ok(graph_client)
}
The OAuth 2.0 client credentials grant flow permits a web service (confidential client) to use its own credentials, instead of impersonating a user, to authenticate when calling another web service. The grant specified in RFC 6749, sometimes called two-legged OAuth, can be used to access web-hosted resources by using the identity of an application. This type is commonly used for server-to-server interactions that must run in the background, without immediate interaction with a user, and is often referred to as daemons or service accounts.
Client credentials flow requires a one time administrator acceptance of the permissions for your apps scopes. To see an example of building the URL to sign in and accept permissions as an administrator see Admin Consent Example
use graph_rs_sdk::{oauth::ConfidentialClientApplication, GraphClient};
pub async fn build_client(client_id: &str, client_secret: &str, tenant: &str) -> GraphClient {
let mut confidential_client_application = ConfidentialClientApplication::builder(client_id)
.with_client_secret(client_secret)
.with_tenant(tenant)
.build();
GraphClient::from(&confidential_client_application)
}
Environment Variables:
pub fn client_secret_credential() -> anyhow::Result<GraphClient> {
let confidential_client = EnvironmentCredential::client_secret_credential()?;
Ok(GraphClient::from(&confidential_client))
}
Environment Variables:
pub fn username_password() -> anyhow::Result<GraphClient> {
let public_client = EnvironmentCredential::resource_owner_password_credential()?;
Ok(GraphClient::from(&public_client))
}
Using automatic token refresh requires getting a refresh token as part of the token response.
To get a refresh token you must include the offline_access
scope.
Automatic token refresh is done by passing the ConfidentialClientApplication
or the
PublicClientApplication
to the Graph
client.
If you are using the client credentials
grant you do not need the offline_access
scope.
Tokens will still be automatically refreshed as this flow does not require using a refresh token to get
a new access token.
async fn authenticate(client_id: &str, tenant: &str, redirect_uri: url::Url) {
let scope = vec!["offline_access"];
let mut credential_builder = ConfidentialClientApplication::builder(client_id)
.auth_code_url_builder()
.with_tenant(tenant)
.with_scope(scope) // Adds offline_access as a scope which is needed to get a refresh token.
.with_redirect_uri(redirect_uri)
.url();
// ... add any other parameters you need
}
Requires Feature interactive_auth
[dependencies]
graph-rs-sdk = { version = "...", features = ["interactive_auth"] }
Interactive Authentication uses the wry crate to run web view on platforms that support it such as on a desktop.
use graph_rs_sdk::{
identity::{
interactive::WithInteractiveAuth, AuthorizationCodeCredential, IntoCredentialBuilder,
Secret,
},
GraphClient,
http::Url,
};
async fn authenticate(
tenant_id: &str,
client_id: &str,
client_secret: &str,
redirect_uri: &str,
scope: Vec<&str>,
) -> anyhow::Result<GraphClient> {
std::env::set_var("RUST_LOG", "debug");
pretty_env_logger::init();
let (authorization_response, credential_builder) =
AuthorizationCodeCredential::authorization_url_builder(client_id)
.with_tenant(tenant_id)
.with_scope(scope) // Adds offline_access as a scope which is needed to get a refresh token.
.with_redirect_uri(Url::parse(redirect_uri)?)
.with_interactive_auth(Secret("secret".to_string()), Default::default())
.into_credential_builder()?;
debug!("{authorization_response:#?}");
let confidential_client = credential_builder.build();
Ok(GraphClient::from(&confidential_client))
}