Wednesday, 24 May 2017

Create Azure AD App Registration with Microsoft Graph API and PowerShell

In my previous post, we had a look at how to authenticate to the Microsoft Graph API in PowerShell. In this post, lets have a look at how we can use the Microsoft Graph REST API to create an Azure AD App registration.

You need to create an App Registration in Azure AD if you have code which needs to access a service in Azure/Office 365 or if you are using Azure AD to secure your custom application. If you have been working with Azure/Office 365 for a while, chances are that you already know this and have already created a few App Registrations.

I was working on an Office 365 project recently where we had some WebJobs deployed to an Azure Web App. These WebJobs processed some list items in SharePoint Online. So naturally, we needed to use an Azure AD app to grant the WebJobs access to SharePoint Online.

For deploying this application, we were using Azure ARM templates and executing them from PowerShell. With ARM templates, we were able to deploy the Resource Group, App Service Plan, and Web App for the WebJobs. But for creating the App Registration, the two options available to us were the New-​Azure​Rm​AD​Application cmdlet which is part of the Azure Resource Manager PowerShell or the /beta/applications endpoint which is part of the Microsoft Graph API.

We found that the New-​Azure​Rm​AD​Application cmdlet is limited in features compared to the Graph API endpoint. For example, you can create an App registration with the cmdlet but you cannot set which services the app has permissions on. For setting that, you need to use the Microsoft Graph API which has the full breadth of functionality. That is why going forward, the Microsoft Graph should be the natural choice for creating Azure AD app registrations.

The way we are going to create the app registration is by making a POST request to the /beta/applications endpoint. The properties of our Azure AD app such as it's Display Name, Identifier Urls, and Required Permissions will be POSTed in the body of the request as JSON.

(As you have probably noticed already, this endpoint is in beta right now. I will update this post once it is GA)


1) Getting the App Registration properties:


The JSON we will POST will be an object of type application resource. Instead of manually "hand crafting" the JSON, it is recommended to download it from the Azure AD manifest of the app registration. Here is how:

a) Manually create an app in Azure AD by going to Azure AD -> App Registrations -> New application registration 

b) Configure it as required. E.g. Set the display name, Reply Urls, the Required permissions and other properties needed for your app

c) Go to your app -> Click on Manifest and download the JSON


Once you have the required JSON, you can delete the manually created app. Going forward, when deploying to another tenant (or the same tenant again), you can just run the following PowerShell script and won't have to create an app registration manually again.


2) Creating the App Registration with Microsoft Graph API and PowerShell:


Here is the PowerShell script you will need to create the Azure AD App Registration. I should mention that the Directory.AccessAsUser.All scope is needed to execute the /beta/applications endpoint.

After the script is run, we can see that the Azure AD app registration was successfully created:


What is happening in the script is that we are using the Get-MSGraphToken function to get the access token for the Microsoft Graph with ADAL. Then using the token, we are making a POST request to the /beta/applications endpoint. The JSON posted to create the app is pretty self explanatory in terms of displayname, identifier urls and reply urls.

What is really interesting is the requiredResourceAccess property which, at first glance, seems to have some random GUIDs. But this is in fact the Required permissions needed for my app. This JSON specifies that my app needs the following permissions:

1) Office 365 SharePoint Online: Read and write items in all site collections 
2) Windows Azure Active Directory: Sign in and read user profile

Your app might need permissions to different services. Just configure the permissions manually as required and then download the JSON from the Manifest.

After the script is run, when I go to Azure AD, I can see that my app has been created and all required properties have been set:



3) Trusting the app:


We have automated the creation of the application but it still needs to be trusted. Fortunately or unfortunately, it is still a manual process to trust the application. If you want to trust the app for all users in the tenant click on the Grant Permissions button:


Or if your application needs to be trusted by each user individually, you can skip this step. The user will be presented with a consent screen when they land on the application.

4) Troubleshooting with Fiddler:


If you have any errors while running the script, you can use Fiddler to determine the exact error being returned by the Microsoft Graph. I found it really helpful myself:

PowerShell would give me this:


But then I was able to get the real error from Fiddler:



Hope you found this post useful. Thanks for reading!

Monday, 22 May 2017

Authenticating to the Microsoft Graph API in PowerShell

In this post, lets have a look at how we can authenticate to the Microsoft Graph REST API through PowerShell. There are a few examples already available online but either they refer to old endpoints or they present the user with a login prompt to enter a username and password before authentication.

A few other examples ask for a client id to be submitted with the authentication request. You can get this client id when you register a new app in Azure AD. But what if you don't want to create an app registration? You already have a username and password, so creating a new Azure AD application just for authentication seems redundant.

Fortunately, there is way to authenticate to the Microsoft Graph API without any login prompts and without the need to create an explicit Azure AD application.

To avoid using any login prompts, we will use the AuthenticationContext.AquireToken method from the Active Directory Authentication Library (ADAL).

To avoid creating a new Client Id and Azure AD application, we will use a well know Client Id reserved for PowerShell: 1950a258-227b-4e31-a9cf-717495945fc2 This is a hard coded GUID known to Azure AD already.

Here are the steps we are going to do:

1) Make sure we have the username and password of a user in Azure AD
2) Use the username, password and PowerShell client id to get an access token from ADAL.
2) Use the access token to call the Microsoft Graph REST API.

Before going ahead, make sure you have the Microsoft.IdentityModel.Clients.ActiveDirectory.dll on your machine. If you have been working with Office 365/Azure PowerShell, chances are you have this already. If not, you can get it from a number of places. You can use the Azure Resource Manager PowerShell cmdlets to get a hold of it: https://docs.microsoft.com/en-us/powershell/azure/install-azurerm-ps?view=azurermps-4.0.0 or you can use nuget to download it: https://www.nuget.org/packages/Microsoft.IdentityModel.Clients.ActiveDirectory

And here is the PowerShell script to authenticate the Microsoft Graph:


Running this script gets the current user from the /v1.0/me endpoint:



Thanks for reading!

Friday, 12 May 2017

Getting the current context (SPHttpClient, PageContext) in a SharePoint Framework Service

I have briefly written about building SPFx services (using ServiceScopes) in my previous post, SharePoint Framework: Org Chart web part using Office UI Fabric, React and OData batching

In this post, lets have a more in-depth look at how to actually get the current SharePoint context in your service, without passing it in explicitly.

All the code used in this post is available on GitHub: https://github.com/vman/SPFx-Service-Context-Demo


Building an SPFx service using ServiceScopes:


Suppose you want to create a service which you want to call from multiple SPFx webparts. The idea is that the code of your service should load on the page only once even if multiple web parts using the same service are added to the page. There is already some great information out there on building such kind of service in SPFx so I won't repeat it here. Have a look:

Share data through a SharePoint Framework service

Building shared code in SharePoint Framework - revisited

I myself have been working on building an SPFx service as an npm package and then using it in a webpart:
https://github.com/vman/SPFx-Service

But before you go ahead and start using ServiceScopes to build your SPFx service, have a read through this Tech Note from the SPFx team:
https://github.com/SharePoint/sp-dev-docs/wiki/Tech-Note:-ServiceScope-API

To summarise, it is recommended to consider other alternatives first before using ServiceScopes. Other alternatives include explicitly passing in dependencies like SPHttpClient in the constructor of your service, or if your service has multiple dependencies, then build a class which has all the dependencies as properties and then pass an object of the class to your service's constructor.

While these recommendations would work in some scenarios, they might not be viable in all conditions. If you are building your service as an npm package, passing in the current context every time you want to use the service might be very burdensome. Ideally, your service should be able to determine all the information about the current context on its own. So lets have a look in this post on how do to that.

Quick note before moving ahead: Building library packages in SPFx is currently not available but it is on the roadmap. It would be nice to see the "build a library" option in the SPFx Yeoman generator. The UserVoice link for this request is here: https://sharepoint.uservoice.com/forums/329220-sharepoint-dev-platform/suggestions/19224202-add-support-for-library-packages-in-the-sharepoint

In this post, to keep things simple, I am going to build my service in the same package as my SPFx webpart. The idea is to demonstrate the concept of using ServiceScopes to get the current context. It would work exactly the same if the service was part of a different SPFx package. If you want to have a look at how this works, have a look at my github repo here: https://github.com/vman/SPFx-Service


Getting the current context in an SPFx service:


Now that you have decided to build an SPFx service using ServiceScopes, lets have a look at how to get the current context in your service without passing it in explicitly.

First, you need to build a service which accepts a ServiceScope object in the constructor. This is the only dependency your service will need. Also, you will not need to explicitly pass in this dependency. SharePoint Framework will handle this for you.

Here is my code for the service:

Now lets have a look at what is going on in the code:

First, we are importing the SPHttpClient class from the @microsoft/sp-http package and the PageContext class from the @microsoft/sp-page-context package.

These classes expose their own ServiceKeys, so in the constructor of our service, we are using those keys to grab an instance of these classes. These instances of classes will already be initialised thanks to the ServiceScope.whenFinished and ServiceScope.consume methods. We can then use the instances in the methods of our class.

Using the current web url to initialise PnP-JS-Core :


Just as an example, you could use the initialised PageContext object to get the current web url and pass it to the PnP JS library. This can be useful if you want to get lists in the current web:



Consuming the service:


Now you have built your service, it is time to consume it from your SPFx web part. It is very straightforward, you just have to instantiate an object of your class using the ServiceScope.consume method and your are good to go. I am using async/await just to keep things simple, but using Promise.then will also work here:


Have a look at the complete code in this post here: https://github.com/vman/SPFx-Service-Context-Demo

Thanks for reading! Hope you have found this post helpful.

Friday, 28 April 2017

Error handling in SharePoint Framework when using Async/Await

This is a quick follow up post to my previous post Using TypeScript async/await to simplify your SharePoint Framework code.

Since publishing my previous post, some folks have asked how would the error handling work when using async/await in SharePoint Framework. So decided to make this short how-to post.

At first glance, it is really straightforward, you essentially have to wrap your code in a try..catch block and the typescript compiler does the rest.

But there is something interesting here. Under the hood, SharePoint Framework uses the fetch API to make http requests. MDN has some great info on the fetch API if you haven't seen it already: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

What would be surprising for some (including me) is that the fetch API rejects the promise only when network errors occur. A "404 Not found" is considered as valid response and the Promise is resolved.

E.g. If you make a get request to a SharePoint list which does not exist, the fetch API (and the SharePoint Framework) will actually resolve your Promise.

A fetch() promise will reject with a TypeError when a network error is encountered, although this usually means permission issues or similar — a 404 does not constitute a network error, for example. An accurate check for a successful fetch() would include checking that the promise resolved, then checking that the Response.ok property has a value of true.

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Checking_that_the_fetch_was_successful

There has also been some discusson on this on the SharePoint Framewok GitHub repo:
https://github.com/SharePoint/sp-dev-docs/issues/184

This is why, in addition to a try..catch block, you have to also check the Response.ok property of the returned Response. Here is the basic code you need to handle errors when using async/await:


What you can also do is, since the fetch API returns promises, you can use chaining to detect if the Response.ok property is false. Have a look at this post: Handling Failed HTTP Responses With fetch()

Update 6th May 2017: Here is a slightly more complex example where I have built a service with a custom get method which also handles errors for you:

And here is how to consume the service from your SPFx webpart:

Here is the GitHub repository for the service if you are interested:
https://github.com/vman/SPFx-Fetcher


Hope you find this useful!

Tuesday, 25 April 2017

Using TypeScript async/await to simplify your SharePoint Framework code

I recently learned about the Async/Await functionality in TypeScript and I was really surprised how easily you can simplify your code with it. Using Async/Await, you can get rid of spaghetti code as well as long chains of Promises and callbacks in your asynchronous functions.

The Async/Await functionality has been around since TypeScript 1.7 but back then it was only available for the ES6/ES2016 runtime. Since TypeScript 2.1, async/await works for ES5 and ES3 runtimes as well, which is very good news. I am kicking myself that I did not start using it sooner.

As with anything new I learn, I have tried to apply it to SharePoint as well to see how I can improve my development experience. Turns out using async/await can really make your SharePoint Framework code simpler and more readable. Lets have a look at some examples and compare between using Promises and Async/Await in your code.

Also, an important thing to note is that although I am making comparisons between using Promises and using async/await, ultimately the aync/await code is downleveled to using Promises by the typescript compiler. If the runtime does not have a native Promise object, we should make sure we have the right polyfills available.

The comparison here is more around code readability and conciseness.

All the code I am using is running inside a SharePoint Framework webpart. So, when you see the 'this' keyword in the code, it refers to my SPFx webpart which inherits from the BaseClientSideWebPart class. Since I am calling the code from inside my webpart, I have access to 'this'.

Here is my import statements for the code:


Simple example using Promises and 'then' callbacks:



Same code using async/await:



Here is a slightly more complex example with code which accepts an array of SharePoint login names and uses the batching framework to get the user profile properties of each user in the array.

You will need the IPerson interface for this:


Complex example using Promises and 'then' callbacks:



Same code using async/await:



As you can see, there is significantly less callbacks when using async/await and the code is also a lot more readable.

Hope you found this post useful. Thanks for reading!


Friday, 21 April 2017

Create/Update SharePoint list items with REST without the '__metadata' property

When updating list items in SharePoint with the REST API, we need to know the ListItemEntityTypeFullName of the list item we are planning to update. There are some good examples on MSDN regarding this https://msdn.microsoft.com/en-us/library/office/dn292552.aspx

The ListItemEntityTypeFullName property (SP.Data.ProjectPolicyItemListItem in the previous example) is especially important if you want to create and update list items. This value must be passed as the type property in the metadata that you pass in the body of the HTTP request whenever you create and update list items.

For example, when you want to update list items in a list called "MyCustomList" you need to know the ListItemEntityTypeFullName of the list items before hand. In this case, it will be SP.Data.MyCustomListListItem. Most examples around the internet do this by querying the list first and then getting the ListItemEntityTypeFullName property from it and using that in the call to update the list items.

If you do not specify the ListItemEntityTypeFullName, you get this error
An entry without a type name was found, but no expected type was specified. To allow entries without type information, the expected type must also be specified when the model is specified

The good news is that you only need to use the entity type full name when you are using "application/json;odata=verbose" as your Accept and Content-Type headers.

If you are using "application/json;odata=nometadata" in your Accept and Content-Type headers, then you do not need the ListItemEntityTypeFullName as well.

Here is are a couple of quick gists I have put together to show how we can create and update list items without specifying the ListItemEntityTypeFullName. I should mention I have tested these only in SharePoint Online at the time of this writing:

1) Create list item without specifying ListItemEntityTypeFullName



2) Update list item without specifying ListItemEntityTypeFullName


Wednesday, 12 April 2017

Send emails to authenticated external users using CSOM

Here is some quick code I put together to send emails in SharePoint Online to external users who have accepted sharing invitations and signed in as authenticated users.

Before having look at the code, I should mention my site collection has external sharing turned on and the "Allow external users who accept sharing invitations and sign in as authenticated users" option selected.


And here is the code:


Thanks for reading!