This project takes a lot from this and makes changes for the new API (you must register your SharePoint application with Azure AD). This document sets up Azure AD for Sharepoint Online.
When using the ADAL package on the Xamarin iPhone emulator, it requires quite a process to get up and running. Installing ADAL requires the NuGet Package “Microsoft.IdentityModel.Clients.ActiveDirectory”. Once that’s installed, you must create an authenticator service to assist with authenticating.
Here’s the interface which is kept in the Shared Library:
public interface IAuthenticator { string LoggedInEmail { get; } AuthenticationResult Result { get; } void SignOut(); bool IsAuthenticated(); Task<AuthenticationResult> Authenticate(); Task CheckUpdateToken(); }
Here are the authentication settings (once again, it’s kept in the shared library). The settings are set when the user initially sets up the Azure AD Application:
public interface IAuthenticateSettings { string ClientId {get;} string Tenant { get; } string Authority { get; } string ReturnUri { get; } string GraphResourceUri { get; } string SharePointResource { get; } } public class AuthenticateSettings : IAuthenticateSettings { public string ClientId { get; private set; } = "clientID"; public string Tenant { get; private set; } = "<tenant-name>.onmicrosoft.com" public string Authority { get; private set; } = String.Format("https://login.microsoftonline.com/{0}", "<tenant>"); public string ReturnUri { get; private set; } = "Return URI"; public string GraphResourceUri { get; private set; } = "https://graph.windows.net"; public string SharePointResource { get; private set; } = "https://your sharepoint site.sharepoint.com"; }
This is how the implementation looks in the iOS project:
[assembly: Dependency(typeof(AccordCarton.iOS.Services.Authenticator))] namespace AccordCarton.iOS.Services { public class Authenticator : IAuthenticator { private readonly IAuthenticateSettings _authenticateSettings; public Authenticator(IAuthenticateSettings authenticateSettin) { _authenticateSettings = authenticateSettings; } public AuthenticationResult Result { get; private set; } public string LoggedInEmail { get { return Result == null ? string.Empty : Result.UserInfo.DisplayableId; } } public async Task<AuthenticationResult> Authenticate() { var authContext = new AuthenticationContext(_authenticateSettings.Authority); if (authContext.TokenCache.ReadItems().Any()) authContext = new AuthenticationContext(authContext.TokenCache.ReadItems().First().Authority); var controller = UIApplication.SharedApplication.KeyWindow.RootViewController; var uri = new Uri(_authenticateSettings.ReturnUri); var platformParams = new PlatformParameters(controller); var authResult = await authContext.AcquireTokenAsync(_authenticateSettings.SharePointResource, _authenticateSettings.ClientId, uri, platformParams); Result = authResult; return authResult; } public bool IsAuthenticated() { var authContext = new AuthenticationContext(_authenticateSettings.Authority); var isAuthenticated = authContext.TokenCache.ReadItems().Any(); return isAuthenticated; } public void SignOut() { var authContext = new AuthenticationContext(_authenticateSettings.Authority); authContext.TokenCache.Clear(); } public async Task CheckUpdateToken() { if (Result.ExpiresOn - DateTime.Now.ToUniversalTime() <span data-mce-type="bookmark" id="mce_SELREST_start" data-mce-style="overflow:hidden;line-height:0" style="overflow:hidden;line-height:0" ></span><span data-mce-type="bookmark" id="mce_SELREST_start" data-mce-style="overflow:hidden;line-height:0" style="overflow:hidden;line-height:0" ></span>< TimeSpan.FromMinutes(5)){ await Authenticate(); } } } }
Once this is up and running, you need to get an instance of the IAuthenticator and call Authenticate. This will allow you to authenticate through the Azure ADAL login screen:
From there, the system retrieves a token and that token can be used when performing application calls (in this case, it is sharepoint):
public class ActionItemService: IActionItemService { private readonly IAuthenticator _authenticator; public ActionItemService(IAuthenticator authenticator) { _authenticator = authenticator. } protected void SetUriAndHeaders(HttpClient client) { client.BaseAddress = new Uri(SharePointBaseAddress); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _authenticator.Result.AccessToken); client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json;odata=verbose"); client.DefaultRequestHeaders.Accept .Add(new <span data-mce-type="bookmark" id="mce_SELREST_start" data-mce-style="overflow:hidden;line-height:0" style="overflow:hidden;line-height:0" ></span>MediaTypeWithQualityHeaderValue("application/json")); } public async Task<List<ActionItem>> GetOpenActionItemsAsync() { await _authenticator.CheckUpdateToken(); using (var client = new HttpClient()) { SetUriAndHeaders(client); var response = await client.GetAsync("_api/web/lists/GetByTitle('ActionItems')/Items?$filter=Status eq'Open'"); response.EnsureSuccessStatusCode(); var contents = await response.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject<SpResponseItem<ActionItem>>(contents).Value; } } }
Now you can communicate with Sharepoint Online using the Sharepoint API.
One thing to note is that when logging in on the iOS emulator, you must login every time that you start the application, but on the real device, you only need to login once.
By default, the tokens are good for 1 hour. You’ll need to call the login function to refresh the token.