I have created few demo applications by following Microsoft Documentation and published blog articles as well. While working on those demo applications, I faced some difficulties.
Incorrect API Scope
This is the mistake I did while configuring the API scopes in the web applications which were using those secured APIs.
When I was reading about MSAL, I saw every sample was using
User.Read scope. So I assumed something which I should not have assumed.
If we publish the APIs in the Azure AD, we need to create the scopes. The applications can then use these scopes to get right tokens which can be used with APIs. So, I created the scope for API and scope name and I specified only the scope name (
access_as_user) in the code.
When I tried to call the API, I got below error.
When we specify the scopes of our APIs, make sure we specify complete URI. So specify
api://ee971e5c-a661-4d82-ba97-935480492129/access_as_user instead of just
No Client Secret
And I thought, that’s it. Now, if I write code to make call to the secured API, I should get successful result. But NO, it was not sufficient. I was getting below error.
From the error, I could guess that I had to specify some certificate somewhere in the configuration.
As I mentioned earlier, I was not aware of what is Confidential client application.
A client application is the application which calls the API. If that client application is distributed to devices (imagine, WPF client or mobile app calling web API), then it is Public Client Application.
If the client application is hosted at one place and the executable are not distributed to the people(e.g. web app – not SPA, web API, background jobs running on servers), then it is Confidential Client Application. They’re considered difficult to access, and for that reason capable of keeping an application secret.
Azure provides two ways for identifying that only allowed applications are calling the APIs, – Certificates and Client Secrets. The client secret is a secret key (imagine string), that is used to make sure that only allowed app is calling the API.
As you might already have guessed, the fix was simple, I just had to add the client secret in the configuration of web application and the API call was successful.
Razors App and Logout Redirection
The fix here was very simple and I am not sure if this should be called as an issue. I would consider this as an issue as I could not find anything related to this in documentation. I have also mentioned this in my previous blog about securing web application.
I created Razor views web application in .NET Core and performed all the steps to make it secured using Azure AD. When I tried to access application, I was correctly redirected to login page.
But when I tried the logout, it was appearing as if logout click is not doing anything. I was expecting logout click to redirect user to Azure AD and then back to application but it did not happen.
It took a lot of time for me to know what was going wrong. This was mostly because I could not find any example on MSAL using Razor views. Most of the examples were MVC examples. Also, I figured out that the internal implementation is also using controllers for performing sign out.
So I tried adding MVC route to my startup and as I was hoping, it worked. Sign out was redirecting users out of application.
|// Logout redirection does not work without this MVC route|
|// Default razor endpoints|
SPA Visual Studio Templates
This is really not an issue, but an important point to note while working on SPA visual studio templates. The single page application temples in visual studio, allow to have both APIs and the SPA in the same project.
I personally prefer having separate projects for API and SPA. That way, we can update both the applications independent of others. Again, this is my opinion and many of us might not agree with this. Many people might be using the Visual Studio template where the APIs and SPA UI are part of same project.
In the past, I have published blog about how to secure the .NET Core Angular Web application which used the Visual Studio template. I have explained all the steps to secure the Angular application. But if we have APIs in the same project, then you can easily figure out that APIs can be called anonymously. Just try putting the GET APIs URL in browser and you will get response.
Be Aware !!!
So, if you have APIs and SPA in same project, and if you want to secure the APIs as well as SPA, make sure of two things:
- Right configurations in SPA layer using MSAL.js
- Right middleware configurations in Startup.cs to protect the APIs.
Social Logins and MSAL
- Facebook / Google identity providers are configured in Azure AD B2C.
- MSAL is used for login and logout
In my previous blog post, I have explained how to enable Facebook and Google identity providers in Azure AD B2C. I was testing below flow:
- Navigate to my Azure App Service URL, which protected using Azure AD B2C
- On login page, select login with Google.
- Login is successful and I can see homepage.
- Then click on Logout.
- Logout is successful and I was redirected to login page.
I was happy to see everything is working as expected. But I tried this flow with the same account which was administrator account in Google Developers Console. So, now, I wanted to try Google login with any other account to make sure that any person with google account can login.
So, I clicked on login with Google button and to my surprise, I was directly logged in, without entering any credentials. I was thinking was I doing anything wrong in Sign out. I checked that all cookies and tokens generated by my App Service were being removed from browser’s cache.
Same issue if you use Facebook login instead of Google.
No Resolution (Yet)
So why login screen directly allowed me ? The reason was the SSO cookie added by Google in my browser was not getting removed. And because of this cookie, the Google was not asking me credentials again.
We can write script to clear browser cache or ask user to close the browser to resolve this up to certain extent. I personally did not like any of this alternative, because of unpleasant side effects.
For ex. clearing browser cache using code might clear other cookies which our application is not using causing user to logout from those applications. Also, if I have performed logout and I am still asked to close the window, as a user I may not like your suggestion because I have 15 other tabs open in browser and I do not want to close them yet.
I could not find any resolution to this yet. As I pointed out earlier, I am following the issue on GitHub for this.
When you are working on the MSAL and your applications, you may change the parameters like scope or code very frequently. So, when you run the application again after making the changes, you may face below error –
No account or login hint was passed....
The error occurs because of the old token which was generated with old code and configurations which is not valid now. You can easily fix this by clearing the browser cache and then refreshing the page or rerun the application.
I hope this compilation helps you. Let me know your thoughts.