Skip to content

Instantly share code, notes, and snippets.

@dylanberry
Last active February 8, 2020 18:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dylanberry/72545bb12c3fba92b1acbd5126910c09 to your computer and use it in GitHub Desktop.
Save dylanberry/72545bb12c3fba92b1acbd5126910c09 to your computer and use it in GitHub Desktop.
public class AuthenticationService
{
public bool IsUserAuthenticated => !string.IsNullOrWhiteSpace(AccessToken);
public string AccessToken { get; private set; }
private readonly IPublicClientApplication _publicClientApplication;
private readonly string[] _scopes;
private readonly JwtSecurityTokenHandler _jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
public AuthenticationService()
{
_publicClientApplication = PublicClientApplicationBuilder.Create(Secrets.MSALClientId)
.WithIosKeychainSecurityGroup(Secrets.AppId)
.WithB2CAuthority(Secrets.MSALBaseUri + Secrets.MSALPolicySignin)
.Build();
_scopes = Secrets.MSALScopes.Split(';');
}
public async Task<AuthenticationResult> LoginAsync()
{
AuthenticationResult result = null;
try
{
result = await AutoSigninAsync() ?? await SigninAsync();
if (result != null)
{
AccessToken = result.AccessToken;
}
}
catch (MsalClientException msalClientException) // ignore the exception thrown when the user cancels login
when (msalClientException.ErrorCode is MsalError.AuthenticationCanceledError)
{
Console.WriteLine(msalClientException);
}
return result;
}
public async Task LogoutAsync()
{
AccessToken = null;
var accounts = await _publicClientApplication.GetAccountsAsync();
foreach (var account in accounts)
{
await _publicClientApplication.RemoveAsync(account);
}
}
private async Task<AuthenticationResult> AutoSigninAsync()
{
var accounts = await _publicClientApplication.GetAccountsAsync();
var account = accounts?.FirstOrDefault();
if (account is null) return null;
AuthenticationResult authenticationResult;
try
{
authenticationResult = await SigninSilentAsync(account);
}
catch (MsalUiRequiredException msalUiRequiredException)
{
Console.WriteLine(msalUiRequiredException);
authenticationResult = await SigninAsync();
}
return authenticationResult;
}
private Task<AuthenticationResult> SigninSilentAsync(IAccount account) =>
_publicClientApplication
.AcquireTokenSilent(_scopes, account)
.ExecuteAsync();
private Task<AuthenticationResult> SigninAsync() =>
_publicClientApplication
.AcquireTokenInteractive(_scopes)
.WithPrompt(Prompt.SelectAccount)
.WithUseEmbeddedWebView(true)
.WithParentActivityOrWindow(App.UIParent)
.ExecuteAsync();
public async Task<AuthenticationResult> SignupAsync()
{
AuthenticationResult result = null;
try
{
var signupResult = await _publicClientApplication
.AcquireTokenInteractive(_scopes)
.WithPrompt(Prompt.SelectAccount)
.WithUseEmbeddedWebView(true)
.WithParentActivityOrWindow(App.UIParent)
.WithB2CAuthority(Secrets.MSALBaseUri + Secrets.MSALPolicySignup)
.ExecuteAsync();
if (signupResult != null)
{
result = await SigninSilentAsync(signupResult.Account);
AccessToken = signupResult.AccessToken;
}
}
catch (MsalClientException msalClientException) // ignore the exception thrown when the user cancels login
when (msalClientException.ErrorCode is MsalError.AuthenticationCanceledError)
{
Console.WriteLine(msalClientException);
}
return result;
}
public TokenValidationResult ValidateAuthToken(string token)
{
if (string.IsNullOrEmpty(token)) return TokenValidationResult.Empty;
var isExpired = _jwtSecurityTokenHandler.ReadJwtToken(token).ValidTo <= DateTime.Now.ToUniversalTime();
return isExpired ? TokenValidationResult.Expired : TokenValidationResult.Valid;
}
}
public enum TokenValidationResult
{
Unknown,
Empty,
Expired,
Valid,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment