Last active
February 25, 2022 23:19
-
-
Save rgregg/0f45cebbfbde4b7e4157 to your computer and use it in GitHub Desktop.
Windows Store App Sign-in for OneDrive SDK
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Text; | |
using System.Threading.Tasks; | |
using Windows.Security.Authentication.OnlineId; | |
namespace OneDrive | |
{ | |
public class MsaForStoreApps | |
{ | |
private const string OnlineIdTicketPolicyForLiveServices = "DELEGATION"; | |
private const int UserNotFoundLoginExceptionHResult = -2147023579; | |
private const int ConsentNotGrantedExceptionHResult = -2138701812; | |
private const int InvalidClientExceptionHResult = -2138701821; | |
private const int InvalidAuthTargetExceptionHResult = -2138701823; | |
private OnlineIdAuthenticator Authenticator { get; set; } | |
public MsaForStoreApps() | |
{ | |
Authenticator = new OnlineIdAuthenticator(); | |
} | |
public async Task<AuthToken> SignInAsync(string[] requestedScopes, bool silent = false) | |
{ | |
try | |
{ | |
string accessToken = await GetAccessTokenAsync(requestedScopes, silent); | |
AuthToken results = new AuthToken(AuthStatus.Successful, this, accessToken, requestedScopes); | |
return results; | |
} | |
catch (TaskCanceledException) | |
{ | |
return null; | |
} | |
catch (Exception comExp) | |
{ | |
switch (comExp.HResult) | |
{ | |
case UserNotFoundLoginExceptionHResult: | |
return new AuthToken(AuthStatus.Unknown, this); | |
case ConsentNotGrantedExceptionHResult: | |
return new AuthToken(AuthStatus.Failure, this); | |
case InvalidClientExceptionHResult: | |
case InvalidAuthTargetExceptionHResult: | |
// This usually means you haven't assoicated your app with the store app yet. | |
return new AuthToken(AuthStatus.InvalidRequest, this); | |
default: | |
return new AuthToken(AuthStatus.ServerError, this); | |
} | |
} | |
} | |
private async Task<string> GetAccessTokenAsync(string[] requestedScopes, bool silent) | |
{ | |
string accessToken = null; | |
string scopes = BuildScopeString(requestedScopes); | |
CredentialPromptType promptType = silent ? CredentialPromptType.DoNotPrompt : CredentialPromptType.PromptIfNeeded; | |
var ticketRequests = new List<OnlineIdServiceTicketRequest>(); | |
ticketRequests.Add(new OnlineIdServiceTicketRequest(scopes, OnlineIdTicketPolicyForLiveServices)); | |
UserIdentity identity = await Authenticator.AuthenticateUserAsync(ticketRequests, promptType); | |
if (identity.Tickets != null && identity.Tickets.Count > 0) | |
{ | |
accessToken = identity.Tickets[0].Value; | |
} | |
return accessToken; | |
} | |
public bool CanSignOut | |
{ | |
get { return Authenticator.CanSignOut; } | |
} | |
private static string BuildScopeString(string[] requestedScopes) | |
{ | |
StringBuilder sb = new StringBuilder(); | |
foreach (string scope in requestedScopes) | |
{ | |
if (sb.Length > 0) | |
sb.Append(' '); | |
sb.Append(scope); | |
} | |
return sb.ToString(); | |
} | |
} | |
public class AuthToken : OneDrive.IAuthenticationInfo | |
{ | |
public AuthToken(AuthStatus result, MsaForStoreApps client, string accessToken = null, string[] scopes = null) | |
{ | |
AuthClient = client; | |
AccessToken = accessToken; | |
Scopes = scopes; | |
Status = result; | |
} | |
public MsaForStoreApps AuthClient { get; private set; } | |
public string AccessToken { get; private set; } | |
public string[] Scopes { get; private set; } | |
public AuthStatus Status { get; private set; } | |
public string RefreshToken | |
{ | |
get { throw new NotImplementedException(); } | |
} | |
public string TokenType | |
{ | |
get { return "Bearer"; } | |
} | |
public DateTimeOffset TokenExpiration | |
{ | |
get { return DateTimeOffset.MaxValue; } | |
} | |
public Task<bool> RefreshAccessTokenAsync() | |
{ | |
throw new NotImplementedException(); | |
} | |
public string AuthorizationHeaderValue | |
{ | |
get { return "Bearer " + AccessToken; } | |
} | |
} | |
public enum AuthStatus | |
{ | |
Unknown, | |
Successful, | |
Failure, | |
InvalidRequest, | |
ServerError | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private async void SignInButton_Click(object sender, RoutedEventArgs e) | |
{ | |
OneDrive.MsaForStoreApps authClient = new OneDrive.MsaForStoreApps(); | |
ODConnection oneDriveConnection = null; | |
var token = await authClient.SignInAsync(new string[] { "wl.signin", "onedrive.readwrite" }); | |
if (token.Status == OneDrive.AuthStatus.Successful) | |
{ | |
oneDriveConnection = new OneDrive.ODConnection("https://api.onedrive.com/v1.0", token); | |
var rootItem = await oneDriveConnection.GetRootItemAsync(OneDrive.ItemRetrievalOptions.Default); | |
} | |
else | |
{ | |
textBlockStatus.Text = string.Format("Error signing into OneDrive: " + token.Status.ToString()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment