pub struct XalAuthenticator { /* private fields */ }Expand description
XAL Authenticator
Implementations§
Source§impl XalAuthenticator
Static methods
impl XalAuthenticator
Static methods
Sourcepub fn generate_random_state() -> CsrfToken
pub fn generate_random_state() -> CsrfToken
Generate OAuth2 random state
Examples
let state = XalAuthenticator::generate_random_state();Sourcepub fn generate_code_verifier() -> (PkceCodeChallenge, PkceCodeVerifier)
pub fn generate_code_verifier() -> (PkceCodeChallenge, PkceCodeVerifier)
Generate OAuth2 code verifier
§Examples
let (pkce_challenge, pkce_verifier) = XalAuthenticator::generate_code_verifier();Sourcepub fn get_device_code_verification_uri(
user_code: &UserCode,
) -> VerificationUriComplete
pub fn get_device_code_verification_uri( user_code: &UserCode, ) -> VerificationUriComplete
Obtain an alternative URL for the device code verification process
This method generates a URL with the device code already prefilled. Users only need to visit this URL and authenticate their account without copying and pasting the code.
§Arguments
user_code- The user code generated during the device code flow initialization.
§Returns
VerificationUriComplete- A URL with the device code already prefilled.
§Examples
use xal::XalAuthenticator;
use xal::oauth2::UserCode;
let user_code = UserCode::new("abc123".to_string());
let verification_uri = XalAuthenticator::get_device_code_verification_uri(&user_code);
println!("{:?}", verification_uri);Parse OAuth2 authorization response by providing the full redirect url containing a code= query parameter
§Arguments
redirect_url- The full url of the redirect endpoint containing the code= query parameter.expected_state- (Optional) The expected state that should match the state returned by the server. If the states do not match, an error will be returned.
§Returns
Ok(AuthorizationCode)- On successful validation of the server response and retrieval of the authorization code.Err(Error)- If there is an error while parsing the server response or if the states do not match.
§Errors
Error::GeneralError- If there is a problem with the response url.Error::OAuthExecutionError- If there is an error with the server response or if the authorization code is not present.
§Examples
use xal::{
XalAuthenticator, url::Url,
oauth2::CsrfToken,
};
let url = Url::parse("https://example.com/?code=123&state=ABC").unwrap();
let code = XalAuthenticator::parse_authorization_code_response(
&url,
Some(&CsrfToken::new("ABC".into())),
).unwrap();
assert_eq!(code.secret(), "123");Sourcepub fn parse_implicit_grant_url(
url: &Url,
expected_state: Option<&CsrfToken>,
) -> Result<WindowsLiveTokens, Error>
pub fn parse_implicit_grant_url( url: &Url, expected_state: Option<&CsrfToken>, ) -> Result<WindowsLiveTokens, Error>
Parse OAuth2 implicit grant response
This method takes a URL with an OAuth2 implicit grant response and optionally a CSRF token. It parses the response, verifies the CSRF token if provided, and returns the access token.
§Arguments
url- The URL containing the OAuth2 implicit grant response.expected_state- Optionally, a CSRF token to verify against.
§Returns
Result<response::WindowsLiveTokens, Error>- The access token and token type.
§Examples
use xal::XalAuthenticator;
use xal::oauth2::{CsrfToken, TokenResponse};
use xal::url::Url;
let url = Url::parse(
"https://example.com/callback#access_token=token123&token_type=Bearer&expires_in=3600&state=123abc"
)
.unwrap();
let live_tokens = XalAuthenticator::parse_implicit_grant_url(
&url,
Some(&CsrfToken::new("123abc".into()))
).unwrap();
assert_eq!(live_tokens.access_token().secret(), "token123");Source§impl XalAuthenticator
OAuth2 request functionality
impl XalAuthenticator
OAuth2 request functionality
Sourcepub fn new(
app_params: XalAppParameters,
client_params: XalClientParameters,
sandbox_id: String,
) -> Self
pub fn new( app_params: XalAppParameters, client_params: XalClientParameters, sandbox_id: String, ) -> Self
Create a new instance of the XAL Authenticator
This method initializes an instance of the XAL Authenticator with the specified
app_params, client_params, and sandbox_id.
See constants in crate::models::app_params for crate::XalAppParameters and
crate::models::client_params for crate::XalClientParameters.
§Examples
Instantiate explicitly with app/client parameters
use xal::{XalAuthenticator, app_params, client_params};
let authenticator = XalAuthenticator::new(
app_params::APP_GAMEPASS_BETA(),
client_params::CLIENT_ANDROID(),
"RETAIL".into(),
);§Notes
If you don’t have specific needs for client parameters, use crate::XalAuthenticator::default
Sourcepub fn with_device_id(
app_params: XalAppParameters,
client_params: XalClientParameters,
sandbox_id: String,
device_id: Uuid,
) -> Self
pub fn with_device_id( app_params: XalAppParameters, client_params: XalClientParameters, sandbox_id: String, device_id: Uuid, ) -> Self
Create a new instance of the XAL Authenticator with explicit Device Id.
See new() method.
§Examples
Instantiate explicitly with app/client parameters and device id
use xal::{XalAuthenticator, app_params, client_params};
let authenticator = XalAuthenticator::with_device_id(
app_params::APP_GAMEPASS_BETA(),
client_params::CLIENT_ANDROID(),
"RETAIL".into(),
uuid::uuid!("dc1183d0-a9f8-4c3f-a2a9-83706023791e")
);§Notes
If you don’t have specific needs for client parameters, use crate::XalAuthenticator::default
Sourcepub fn sandbox_id(&self) -> String
pub fn sandbox_id(&self) -> String
Get configured sandbox id
Sourcepub fn app_params(&self) -> XalAppParameters
pub fn app_params(&self) -> XalAppParameters
Get active app parameters
Sourcepub fn client_params(&self) -> XalClientParameters
pub fn client_params(&self) -> XalClientParameters
Get active client parameters
Sourcepub fn request_signer(&self) -> RequestSigner
pub fn request_signer(&self) -> RequestSigner
Get request signer instance
Sourcepub fn get_redirect_uri(&self) -> Option<Url>
pub fn get_redirect_uri(&self) -> Option<Url>
Get redirection Url
Sourcepub fn oauth_client(&self) -> Result<BasicClient, Error>
pub fn oauth_client(&self) -> Result<BasicClient, Error>
Create an internal oauth2::Client
Refer to oauth2 crate for it’s usage
Gets the authorization URL for the OAuth2 authentication flow.
When the user clicks the link in the URL, they will be prompted to sign in with their Xbox Live account.
Defining a redirect_url in crate::XalAppParameters is mandatory
for this authentication flow
§Examples
use xal::{XalAuthenticator, XalAppParameters, client_params};
use xal::oauth2::{RedirectUrl, Scope};
let mut authenticator = XalAuthenticator::new(
XalAppParameters {
client_id: "388ea51c-0b25-4029-aae2-17df49d23905".into(),
title_id: None,
auth_scopes: vec![
Scope::new("Xboxlive.signin".into()),
Scope::new("Xboxlive.offline_access".into())
],
redirect_uri: Some(RedirectUrl::new("https://login.live.com/oauth20_desktop.srf".into()).unwrap()),
client_secret: None,
},
client_params::CLIENT_ANDROID(),
"RETAIL".into()
);
let (url, state) = authenticator.get_authorization_url(false)
.unwrap();
assert!(url.as_str().starts_with("https://login.live.com/oauth20_desktop.srf"));Sourcepub async fn initiate_device_code_auth(
&mut self,
) -> Result<StandardDeviceAuthorizationResponse, Error>
pub async fn initiate_device_code_auth( &mut self, ) -> Result<StandardDeviceAuthorizationResponse, Error>
Initiates the Device Code Authentication Flow.
After presenting the returned [crate::oauth2:: EndUserVerificationUrl] and crate::oauth2::UserCode
to the user, call poll_device_code_auth.
You can transform the returned value into crate::oauth2::VerificationUriComplete by calling get_device_code_verification_uri.
§Examples
use xal::XalAuthenticator;
let mut authenticator = XalAuthenticator::default();
let device_code_resp = authenticator
.initiate_device_code_auth()
.await
.unwrap();
// Present authentication parameters from `device_code_resp` to user
let live_tokens = authenticator
.poll_device_code_auth(&device_code_resp, tokio::time::sleep)
.await
.unwrap();
println!("{live_tokens:?}");Sourcepub async fn poll_device_code_auth<S, SF>(
&mut self,
device_auth_resp: &StandardDeviceAuthorizationResponse,
sleep_fn: S,
) -> Result<WindowsLiveTokens, Error>
pub async fn poll_device_code_auth<S, SF>( &mut self, device_auth_resp: &StandardDeviceAuthorizationResponse, sleep_fn: S, ) -> Result<WindowsLiveTokens, Error>
Poll for device code.
To be called after presenting the result of start_device_code_auth to the user.
§Arguments
sleep_fnis the impl of an async sleep function
§Examples
use xal::XalAuthenticator;
let mut authenticator = XalAuthenticator::default();
let device_code_resp = authenticator
.initiate_device_code_auth()
.await
.unwrap();
// Present authentication parameters from `device_code_resp` to user
let live_tokens = authenticator
.poll_device_code_auth(&device_code_resp, tokio::time::sleep)
.await
.unwrap();
println!("{live_tokens:?}");Sourcepub async fn exchange_code_for_token(
&mut self,
authorization_code: AuthorizationCode,
code_verifier: Option<PkceCodeVerifier>,
) -> Result<WindowsLiveTokens, Error>
pub async fn exchange_code_for_token( &mut self, authorization_code: AuthorizationCode, code_verifier: Option<PkceCodeVerifier>, ) -> Result<WindowsLiveTokens, Error>
Exchange OAuth2 Authorization Token for Windows Live Access Token.
This method utilizes the PKCE extension to securely obtain an access token from the Microsoft Identity Platform.
§Arguments
authorization_code- The authorization code received from the user authentication step.code_verifier- The code verifier that was generated earlier in the PKCE process. This parameter is optional.
§Examples
use xal::XalAuthenticator;
use xal::oauth2::{AuthorizationCode, TokenResponse};
let mut authenticator = XalAuthenticator::default();
let code = AuthorizationCode::new("123".to_string());
let live_tokens = authenticator
.exchange_code_for_token(code, None)
.await?;
assert!(!live_tokens.access_token().secret().is_empty());Sourcepub async fn refresh_token_for_scope<T>(
&mut self,
refresh_token: &RefreshToken,
scopes: Vec<Scope>,
) -> Result<T, Error>where
T: DeserializeOwned,
pub async fn refresh_token_for_scope<T>(
&mut self,
refresh_token: &RefreshToken,
scopes: Vec<Scope>,
) -> Result<T, Error>where
T: DeserializeOwned,
Refresh an OAuth2 Refresh Token for specific scope(s) and deserialize into custom response type
This is used when the token response does not align with the standard.
§Examples
use xal::XalAuthenticator;
use xal::oauth2::{RefreshToken, Scope};
use serde::{Deserialize, Serialize};
// Custom JSON response body
#[derive(Debug, Serialize, Deserialize)]
pub struct XCloudTokenResponse {
pub lpt: String,
pub refresh_token: String,
pub user_id: String,
}
let mut authenticator = XalAuthenticator::default();
let scopes = vec![
Scope::new(
"service::http://Passport.NET/purpose::PURPOSE_XBOX_CLOUD_CONSOLE_TRANSFER_TOKEN".into()
)
];
let token_response = authenticator
.refresh_token_for_scope::<XCloudTokenResponse>(
&refresh_token,
scopes
)
.await
.unwrap();Sourcepub async fn refresh_token(
&mut self,
refresh_token: &RefreshToken,
) -> Result<WindowsLiveTokens, Error>
pub async fn refresh_token( &mut self, refresh_token: &RefreshToken, ) -> Result<WindowsLiveTokens, Error>
Refresh a Windows Live Refresh & Access Token by providing a Refresh Token
§Arguments
refresh_token- The refresh token to use for obtaining a new access token
§Examples
use xal::XalAuthenticator;
use xal::oauth2::RefreshToken;
let mut authenticator = XalAuthenticator::default();
let refresh_token = RefreshToken::new("old_refresh_token".to_string());
let refreshed_live_tokens = authenticator
.refresh_token(&refresh_token)
.await
.unwrap();
println!("Refreshed tokens: {refreshed_live_tokens:?}");Source§impl XalAuthenticator
Xbox Live token functionality
impl XalAuthenticator
Xbox Live token functionality
Sourcepub async fn sisu_authenticate(
&mut self,
device_token: &DeviceToken,
code_challenge: &PkceCodeChallenge,
state: &CsrfToken,
) -> Result<(SisuAuthenticationResponse, SisuSessionId), Error>
pub async fn sisu_authenticate( &mut self, device_token: &DeviceToken, code_challenge: &PkceCodeChallenge, state: &CsrfToken, ) -> Result<(SisuAuthenticationResponse, SisuSessionId), Error>
Initiate authentication via SISU flow
§Parameters
device_token: Aresponse::DeviceTokenobject representing the device token.code_challenge: APkceCodeChallengeobject representing the code challenge.state: ACsrfTokenobject representing the CSRF token.
§Errors
- If
device_tokenis missing. - If
redirect_uriis missing. - If the Sisu Authentication request fails.
§Examples
use xal::XalAuthenticator;
use xal::url::Url;
let mut authenticator = XalAuthenticator::default();
let state = XalAuthenticator::generate_random_state();
let (pkce_challenge, pkce_verifier) = XalAuthenticator::generate_code_verifier();
let device_token = authenticator.get_device_token()
.await
.unwrap();
let (resp, session_id) = authenticator.sisu_authenticate(
&device_token,
&pkce_challenge,
&state
)
.await
.unwrap();
println!(
"Visit this url and pass back the redirect url containing the authorization code {}",
resp.msa_oauth_redirect
);
let redirect_url = Url::parse("https://example.com/?code=123").unwrap();
let authorization_code = XalAuthenticator::parse_authorization_code_response(
&redirect_url, Some(&state)
).unwrap();
let live_tokens = authenticator.exchange_code_for_token(
authorization_code, Some(pkce_verifier)
)
.await
.unwrap();
let sisu_authorization_resp = authenticator.sisu_authorize(
&live_tokens, &device_token, Some(session_id)
)
.await
.unwrap();§Notes
It is mandatory to have XalAppParameters setup with a redirect_uri and title_id.
Authorize via SISU flow after completing OAuth2 Authentication
This function handles the second step of the SISU flow. The response from the server contains a collection of tokens, which can be used for further interaction with the Xbox Live service.
§Examples
use xal::XalAuthenticator;
use xal::url::Url;
let mut authenticator = XalAuthenticator::default();
let state = XalAuthenticator::generate_random_state();
let (pkce_challenge, pkce_verifier) = XalAuthenticator::generate_code_verifier();
let device_token = authenticator.get_device_token()
.await
.unwrap();
let (resp, session_id) = authenticator.sisu_authenticate(
&device_token,
&pkce_challenge,
&state
)
.await
.unwrap();
println!(
"Visit this url and pass back the redirect url containing the authorization code {}",
resp.msa_oauth_redirect
);
let redirect_url = Url::parse("https://example.com/?code=123").unwrap();
let authorization_code = XalAuthenticator::parse_authorization_code_response(
&redirect_url, Some(&state)
).unwrap();
let live_tokens = authenticator.exchange_code_for_token(
authorization_code, Some(pkce_verifier)
)
.await
.unwrap();
let sisu_authorization_resp = authenticator.sisu_authorize(
&live_tokens, &device_token, Some(session_id)
)
.await
.unwrap();Sourcepub async fn get_device_token(&mut self) -> Result<DeviceToken, Error>
pub async fn get_device_token(&mut self) -> Result<DeviceToken, Error>
Requests a Xbox Live Device Token from the Xbox Live authentication service.
This method is responsible for requesting a Xbox Live Device Token, which identifies a client device to the Xbox service.
§Errors
This method returns an Error if the POST request fails or the JSON response cannot be parsed.
§Examples
use xal::XalAuthenticator;
let mut authenticator = XalAuthenticator::default();
let device_token = authenticator.get_device_token()
.await
.unwrap();
assert!(!device_token.token.is_empty());§Notes
Device tokens can only be requested for devices of the following type:
- Android
- iOS
- Nintendo
- Win32
Xbox devices use a much more sophisticated request method.
Sourcepub async fn get_user_token(
&mut self,
access_token: &WindowsLiveTokens,
prefix: AccessTokenPrefix,
) -> Result<UserToken, Error>
pub async fn get_user_token( &mut self, access_token: &WindowsLiveTokens, prefix: AccessTokenPrefix, ) -> Result<UserToken, Error>
Retrieves a Xbox User Token for a specified Access Token.
This method sends a POST request to the Xbox Live User Authentication URL, using the provided
access_token and prefix.
The resulting User Token is then used to retrieve the final XSTS token to access Xbox Live services.
§Arguments
access_token- The Windows Live access token.prefix- The access token prefix, either “d=”, “t=” or None.
§Errors
This method returns an crate::Error if the POST request fails or the JSON response cannot be parsed.
§Examples
use xal::{XalAuthenticator, Flows, Error, AccessTokenPrefix, CliCallbackHandler};
use xal::response::WindowsLiveTokens;
let mut authenticator = XalAuthenticator::default();
let token_store = Flows::ms_device_code_flow(
&mut authenticator,
CliCallbackHandler,
tokio::time::sleep
)
.await?;
let user_token = authenticator.get_user_token(
&token_store.live_token,
AccessTokenPrefix::D,
)
.await?;Sourcepub async fn get_title_token(
&mut self,
access_token: &WindowsLiveTokens,
device_token: &DeviceToken,
) -> Result<TitleToken, Error>
pub async fn get_title_token( &mut self, access_token: &WindowsLiveTokens, device_token: &DeviceToken, ) -> Result<TitleToken, Error>
Retrieves a Title Token for a specified Access Token and Device Token.
This method sends a POST request to the Xbox Live Title Authentication URL, using the provided
access_token and device_token.
The resulting Title Token is then used to retrieve the final XSTS token to access Xbox Live services.
§Arguments
access_token- The Windows Live access token.device_token- The Xbox Live device token.
§Errors
This method returns an Error if the POST request fails or the JSON response cannot be parsed.
§Examples
use xal::{XalAuthenticator, Flows, Error, AccessTokenPrefix, CliCallbackHandler};
let mut authenticator = XalAuthenticator::new(
xal::app_params::MC_BEDROCK_SWITCH(),
xal::client_params::CLIENT_NINTENDO(),
"RETAIL".into()
);
let token_store = Flows::ms_device_code_flow(
&mut authenticator,
CliCallbackHandler,
tokio::time::sleep
)
.await?;
let device_token = authenticator.get_device_token()
.await?;
let title_token = authenticator.get_title_token(
&token_store.live_token,
&device_token,
)
.await?;Sourcepub async fn get_xsts_token(
&mut self,
device_token: Option<&DeviceToken>,
title_token: Option<&TitleToken>,
user_token: Option<&UserToken>,
relying_party: &str,
) -> Result<XSTSToken, Error>
pub async fn get_xsts_token( &mut self, device_token: Option<&DeviceToken>, title_token: Option<&TitleToken>, user_token: Option<&UserToken>, relying_party: &str, ) -> Result<XSTSToken, Error>
Authenticates with the Xbox Live service and retrieves an XSTS token.
This method sends a POST request to the Xbox Live XSTS Authentication URL, using the provided relying_party
and optionally device_token, title_token, and user_token.
The resulting XSTS token can be used to authenticate with various Xbox Live services.
§Arguments
device_token- (Optional) The Xbox Live device token.title_token- (Optional) The Xbox Live title token.user_token- (Optional) The Xbox Live user token.relying_party- The relying party of the application.
§Errors
This method returns an Error if the POST request fails or the JSON response cannot be parsed.
§Examples
use xal::{XalAuthenticator, Flows, Error, AccessTokenPrefix, CliCallbackHandler};
use xal::response::WindowsLiveTokens;
let mut authenticator = XalAuthenticator::new(
xal::app_params::MC_BEDROCK_SWITCH(),
xal::client_params::CLIENT_NINTENDO(),
"RETAIL".into()
);
let token_store = Flows::ms_device_code_flow(
&mut authenticator,
CliCallbackHandler,
tokio::time::sleep
)
.await?;
let device_token = authenticator.get_device_token()
.await?;
let title_token = authenticator.get_title_token(
&token_store.live_token,
&device_token,
)
.await?;
let user_token = authenticator.get_user_token(
&token_store.live_token,
AccessTokenPrefix::None,
)
.await?;
let xsts_token = authenticator.get_xsts_token(
Some(&device_token),
Some(&title_token),
Some(&user_token),
"rp://api.minecraftservices.com/",
).await?;