Skip to content

Instantly share code, notes, and snippets.

@jlattimer
Created April 30, 2015 04:00
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 jlattimer/866f2968f2f204b268de to your computer and use it in GitHub Desktop.
Save jlattimer/866f2968f2f204b268de to your computer and use it in GitHub Desktop.
Xamarin iOS log into Dynamics CRM and retrieve Access Token and uses Refresh Token to renew after expiration
using Foundation;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System;
using System.Linq;
using System.Threading.Tasks;
using UIKit;
namespace YourNamespace
{
public class CrmOauth
{
private static AuthenticationResult _authResult;
public static string ClientId = "[GUID_HERE]";
public static string CommonAuthority = "https://login.windows.net/[GUID_HERE]/oauth2/authorize?api-version=1.0";
public static Uri ReturnUri = new Uri("http://yourapp-redirect");
public static string CrmUrl = "https://org.crm.dynamics.com";
//Use:
//var gotToken = await CrmOauth.GetToken(this);
//if (gotToken)
// //Do CRM Stuff - read Access Token - NSUserDefaults.StandardUserDefaults.StringForKey("AccessToken")
async public static Task<bool> GetToken(UIViewController controller)
{
NSString tokenExpirationKey = new NSString("AccessTokenExpirationDate");
//Check if token data is saved
if (!string.IsNullOrEmpty(NSUserDefaults.StandardUserDefaults.StringForKey("AccessToken")) &&
NSUserDefaults.StandardUserDefaults.ValueForKey(tokenExpirationKey) != null &&
!string.IsNullOrEmpty(NSUserDefaults.StandardUserDefaults.StringForKey("RefreshToken")))
{
NSDate nsdate = (NSDate)NSUserDefaults.StandardUserDefaults.ValueForKey(tokenExpirationKey);
DateTime d = new DateTime(2001, 1, 1, 0, 0, 0).AddSeconds(nsdate.SecondsSinceReferenceDate);
DateTime tokenExpireDate = DateTime.SpecifyKind(d, DateTimeKind.Unspecified);
DateTime currentDate = DateTime.Now.ToUniversalTime();
//Check if Access Token is expired
if (currentDate > tokenExpireDate)
{
try
{
//Access Token is expired use Refresh Token to renew
var authContext = new AuthenticationContext(CommonAuthority);
if (authContext.TokenCache.ReadItems().Any())
authContext = new AuthenticationContext(authContext.TokenCache.ReadItems().First().Authority);
_authResult =
await
authContext.AcquireTokenByRefreshTokenAsync(
NSUserDefaults.StandardUserDefaults.StringForKey("RefreshToken"),
ClientId);
SaveTokens();
return true;
}
catch (Exception)
{
//Refresh failed - go to standard login
}
}
else //Access Token is still valid
return true;
}
//Standard login prompt
try
{
var authContext = new AuthenticationContext(CommonAuthority);
if (authContext.TokenCache.ReadItems().Any())
authContext = new AuthenticationContext(authContext.TokenCache.ReadItems().First().Authority);
_authResult =
await
authContext.AcquireTokenAsync(CrmUrl, ClientId,
ReturnUri, new AuthorizationParameters(controller));
SaveTokens();
return true;
}
catch (AdalServiceException ex)
{
if (ex.StatusCode == 0)
{
//Access Denied and/or hit Cancel button on login screen
}
return false;
}
}
private static void SaveTokens()
{
NSUserDefaults.StandardUserDefaults.SetString(_authResult.AccessToken, "AccessToken");
NSDate tokenExpiration = (NSDate)_authResult.ExpiresOn.UtcDateTime;
NSString tokenExpirationKey = new NSString("AccessTokenExpirationDate");
NSUserDefaults.StandardUserDefaults.SetValueForKey(tokenExpiration, tokenExpirationKey);
NSUserDefaults.StandardUserDefaults.SetString(_authResult.RefreshToken, "RefreshToken");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment