Created
April 30, 2015 04:00
-
-
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
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 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