Updated Fiddler OAuth Inspector
This post will detail some of the updates made to the Fiddler OAuth inspector and gives examples of how to use it.
I previously wrote about Creating a Fiddler Extension for SharePoint 2013 App Tokens. As my friend Andrew Connell let me know, the tool is valuable beyond the context of SharePoint, it is a generic JWT parser that can be used with any JWT token. This post will show the generic capabilities as well as a few SharePoint-specific capabilities. The updated source code for the Fiddler extension can be found at https://github.com/andrewconnell/SPOAuthFiddlerExt.
I’ve been asked a few times to write up some documentation on the tool and show how to use it. The rest of this post will show how to deploy it and some techniques for using it. If you have any more suggestions on how to use it, please leave comments. If you have any changes you’d like to see in it, submit a pull request for the GitHub repository at https://github.com/andrewconnell/SPOAuthFiddlerExt.
Deploying the Fiddler Extension
Deploying the extension is simple. Build the project, copy the SPOAuthFiddlerExt.dll, NewtonSoft.Json.dll, and Newtonsoft.Json.xml files to the C:\Program Files (x86)\Fiddler2\Inspectors folder. Here is a picture of the Inspectors folder on my machine.
There is a Visual Studio post-build action defined that will copy the required DLLs for you. In order for this to work, you have to run Visual Studio as administrator.
Once you deploy the add-in and start Fiddler, you can click on an HTTP request and see the SPOAuth tab under “Inspectors”.
Data will only show up in the extension when the request being inspected contains the “Authorization: Bearer” HTTP header with a JWT token value. It will also show up when the request contains a form post value named “AppContext”, “AppContextToken”, “AccessToken”, or “SPAppToken” with a JWT token value. These are to handle SharePoint-specific inspections.
Example: Single Page Application with Azure Active Directory
In a previous post, I showed how to create a Single Page Application that calls a custom Web API protected by Azure AD. I am using IIS Express to develop and debug the application, so I need to use the URL “https://localhost.fiddler” with the application for localhost traffic to capture in Fiddler (for more information, see Problem: Traffic sent to http://localhost or http://127.0.0.1 is not captured).
I replace any HTTP calls in my application to use the host name localhost.fiddler The first is in app.js, replace the localhost endpoint with the Fiddler endpoint.
The next change is the actual service call itself, in mailSvc.js, changing “localhost” to localhost.fiddler.
Change the project to launch using the localhost.fiddler host name so that hitting F5 will launch the browser using the localhost.fiddler endpoint.
Now that I have made changes in the app, I need to also make changes in Azure AD. When the user logs into the application, they are redirected to Azure AD to sign in, and then are redirected back to the application. The first change is to update the sign-on URL for the application with the localhost.fiddler host name.
Finally, we change the reply URL for the application to reply to the localhost.fiddler endpoint.
Start Fiddler, and the run the project. You should now see the output in Fiddler.
Know What to Look For
The extension is used to decode an access token. It doesn’t perform validation, and it doesn’t point out where errors might have occurred, you need to have a sense of what you’re looking for. The most frequent issues that I see are an invalid audience (verified in the “aud” claim) and having a different set of claims than expected.
Here’s a good example. I was debugging the application and kept getting weird errors in my SPA application, “Exception of type 'Microsoft.Office365.Discovery.DiscoveryFailedException' was thrown”:
Sweet! I go look in Fiddler and see the 500 HTTP error when I call the custom Web API.
Click on that record and go to the Inspectors/SPOAuth tab.
You can now inspect the JWT token. First, we look at it in plan text view.
Next, we switch over to an easier to read property grid. I immediately see my problem. I am logged in as a user who has access to the Azure AD tenant, but does not have an O365 account in my tenant, I need to be logged in as a user who has access to O365.
To verify this, I launch an In Private browsing session. I am prompted to log in:
This time it works as expected.
I can pop over to Fiddler to verify that the user is now the correct user in the access token, and I can see the return values in the response pane.
Example: SharePoint Provider-Hosted App
Here’s another example of using the extension. I create a new SharePoint provider-hosted app, and I want to capture the traffic in Fiddler. I go to the appmanifest.xml file and change the StartUrl to the localhost.fiddler URL.
Start Fiddler and then hit F5 in Visual Studio to start debugging. You are prompted to log in:
You are asked if you trust the app, click Trust It.
The app runs, and in Fiddler I can see the request contains “SPAppToken”.
Go to the SPOAuth tab, and it’s empty. Huh?
Go back to the raw view, and notice that the value posted from SharePoint to our app contains the SPAppToken in the body, but the value includes an error message.
This is actually a very common error when debugging SharePoint apps and you are trying to deploy the app. It is saying that the app principal in SharePoint is registered with a different authority than what we are using with our app. This is because the SharePoint tools will automatically create an app principal using the authority “localhost” but our application’s authority is “localhost.fiddler”. The same error can easily occur when your app principal’s authority is “localhost” but you try to deploy to another host such as azurewebsites.net.
There’s not really a clean way to set up Fiddler using IIS Express with SharePoint Online such that you can see all traffic including the incoming context token as well as the outgoing CSOM or REST API calls. If you really need this capability, then set up IIS on your machine and use a host header or machine name for your app’s URL instead of “localhost”. Despite there not being a clean way to see the incoming HTTP POST that contains the context token when using IIS Express, you can still easily see the outbound requests to SharePoint.
For example, I created a new SharePoint provider hosted app and started capturing using Fiddler. I didn’t see the HTTP POST that SharePoint sends to my app using localhost, but I did see the outgoing request from the CSOM call to /_vti_bin/client.svc/ProcessQuery.
And I can go to the SPOAuth tab to inspect the access token values.
I can use the grid view to look at the properties and determine the exact date that the token expires.
I can make some assumptions that if the audience contains “00000003-0000-0ff1-ce00-000000000000”, then this is a token specific to SharePoint apps. Then I can use the third tab marked “Property Values” to show the values that the access token assumes.
In this screen shot, there are a few things that can be useful for troubleshooting. For instance, we can determine the client ID and tenant ID, useful for troubleshooting 401 Unauthorized issues.
In the case of a high-trust SharePoint token, you can glean a little more information. A high-trust token includes the SID for the user in the nameid property when using Windows claims. This is how it identifies the user. Separately, the high trust token must also identify the app, which is why it contains a nested JWT token in its “actortoken” claim. This is how it identifies the app separately from the user.
If you’re interested in knowing more about high-trust SharePoint apps, see my post High Trust SharePoint Apps on Non-Microsoft Platforms.
For More Information
Creating a Fiddler Extension for SharePoint 2013 App Tokens – post that gives the general structure of the code and how to build a Fiddler add-in. Note that the code in that post is outdated, you can obtain the latest code from the GitHub repository.
https://github.com/andrewconnell/SPOAuthFiddlerExt – GitHub repository to obtain the latest source code