In previous posts of this series, ASP.NET Core 2.0 Authentication, I talked about local logins, where you have your own identity management solution and also social logins, where you work with social media or third party providers to sign in users in your application. In this one, I am going to talk about Azure Active Directory, which is a cloud based solution for identity management and how you can make this work with your ASP.NET Core 2.0 application.
Source code
Code outlined in this article can be found on my GitHub repository.
What is Azure Active Directory
Azure Active Directory (AD) is a cloud based solution for identity management, which provides a rich suite of features on user, group, application, security and many other features among them into one consolidated solution.
From the official documentation:
Azure Active Directory (Azure AD) is Microsoft’s multi-tenant, cloud-based directory, and identity management service that combines core directory services, application access management, and identity protection into a single solution. Azure AD also offers a rich, standards-based platform that enables developers to deliver access control to their applications, based on centralized policy and rules.
As you can see, this is powerful, it provides lots and lots of identity services and it fits very well in cloud but also in on-premises solutions as well, integrating excellently with enterprise Windows Server Active Directory to manage SaaS application's access. Of course, it plays well with Office 365 applications and Microsoft Dynamics CRM online.
It is a very common scenario, that often companies like to store their users in an active directory and prefer to have applications integrate with that instead of building something custom, like I did in previous posts in this series. It is costly to have in-house solutions for that kind of stuff because you have to manage a lot of things, like the users first of all, their groups, the resources that they can have access (by resources I mean their claims). It becomes a tedious process after some time and I know, because I had to work in a real world application that had this kind of identity management solution. It was error prone, we had been called a lot of times to amend problems with access, or the whole system sometimes was crashing because of various reasons. Especially in the latter scenario, such thing was capable of bringing down lots of applications, including applications we own and the worst part is that this system wasn't ours in the first place, someone else was looking after it, so we had to wait for them to come up with a fix.
Well, you won't find such problems in Azure AD, cause this service is highly reliable, as it is geo-distributed, running in 28 data centers around the world with automated failover. Even if the data center that your service lives in goes down, copies of your directory data live in other regions, so facing downtime would be virtually impossible through Azure.
As a developer I would choose this identity management solution for the single reason that I don't want to mess around with managing identity in the first place. I want to focus on building my application based on the business requirements I have. Security is super important, but it is a detail, in terms of development and it shouldn't get in my way. That's why Azure AD is there, to take that burden away from me, it is battle tested, serving millions of organizations, many of them Fortune-500, around the globe. So why not use it? Plus the application(s) user is going to be happy, as he/she will have to deal with only one login for every application that we own, which is huge, especially in corporate scenarios.
Azure AD has a Free edition in which you can manage your users and groups, utilize the single sign-on features across many SaaS applications and many other. It of course provides three paid capabilities, which include more features.
Application
Before starting, you need an Azure subscription. If you don't have, you can use thefree trial which provides €170 credit to spend for 30 days and 12-month free access to certain Azure services. I am going to use the free version of Azure AD anyways. I will create a new directory from scratch in following example.
After you login in Azure, choose the Azure Active Directory and create a new directory there.
Now enter your organization name and a domain name, it should be unique,
Wait a few moments and it will be ready. If you go to Azure Active Directory blade again, you will be able to switch directory. If it is ready, switch to your new directory and let's add some users. Check the screenshot below to see an overview of users.
I added a user named John Doe with the email of john.doe@thewisecoderdemo.onmicrosoft.com. You can add new users by clicking the New user button that is on top menu and you will be able to include various details for that user, manage his/hers groups and stuff like that.
One last thing before I dive into code, is that I want to register my application with Azure AD, so the directory will be aware of it, so I will be able to login successfully. Go to App registrations and click on New application registration as shown below.
Enter the application name and the sign-on URL, which is the root URL of the application.
One last thing, you will be redirected to the application blade, click on Settings and change the reply URL to be the root URL plus the /auth/signin-callback
path. The reply URL is the callback path.
In Properties, you will need the Application ID, this is the Client Id that we are going to use for the registered application.
Now I am ready to code. Application is kinda similar with previous demos, an ASP.NET Core 2.0 web application, so you have a landing page and a profile page, which is secured. In that page you can view the signed-in user claims.
Azure AD is using the Open Id Connect protocol, so I need to add support for that in the application.
This is the secured profile page, it's just showing the authenticated user and list all of his/hers claims.
The core part is the authentication setup. In Startup.cs you will have to setup the authentication using Open Id Connect, by the AddOpenIdConnect
extension method. So, I first add authentication in the pipeline, then I configure OIDC and finally I am using cookies to sign-in the user. Look at the following configuration and I will go through each setup option.
- Authority. This tells the system where the OIDC endpoint that I want to use is located. The domain is login.microsoftonline.com and then I provide as path my tenant directory, which in this case is thewisecoderdemo.onmicrosoft.com.
- ClientId. This is the Application Id for the registered application (you will find it at the Application Properties in Azure AD).
- ResponseType. The response type that I want to return which is an OIDC Id token in this case.The value of the id_token parameter is the ID Token, which is a signed JWT. Read more here and here.
- CallbackPath. This corresponds to the reply URL (you will find it at the Reply URL blade in Azure AD).
- SignedOutRedirectPath. This the the path where the application will redirect when I logout. I'm using the application root, so this is going to redirect to the home page after I logout.
- TokenValidationParameters.NameClaimType. I am using this option to map the name claim type to have the value of the name claim rather what it has by default. The default username contains the tenant name.
When the user is authenticated, we need to have him logged-in locally using a cookie, so that's why I've added cookie authentication using the AddCookie
extension.
Finally, in AddAuthentication
method, I've added the default schemes for challenge, sign-in and authentication. For the DefaultChallengeScheme
, I am using the OIDC scheme to tell the system to use the OIDC service by default when we need to get a user authenticated. For the rest, I am using the cookie authentication scheme, for sign-in and incoming request authentication.
Next step would be to setup the application to let the users sign-in. I have added a controller named AuthController
, which has SignIn
and SignOut
actions. In SignIn
, I just have to return a Challenge
to the client. The challenge response will then redirect the user to Azure AD. This will be the Authority I've set earlier in configuration. I want also to set the AuthenticationProperties
and more specifically the RedirectURL
to be the root of the application, in order to avoid an endless loop of redirections. If I haven't done that, when the user would be authenticated, he/she would be redirected back here (in /auth/login
) and from here back to Azure AD and so on and so forth.
For the SignOut
action, notice that I sign out the user twice! First, I sign-out the user in the application, by killing the corresponding local browser cookie. Then, I sign-out from the OIDC authentication with Azure AD. I want to be sure that I have killed any potential authentication session that might still exist in the Azure AD end. The latter will cause a redirect back to the home page, using the SignedOutRedirectUri
from the configuration.
See this in action.
Summary
In this post, I showed how to secure your application by using Azure Active Directory to manage access.
Azure AD is a multi-tenant, cloud based directory in which you can manage groups and users in various ways, providing you application access management and security. You need to have an Azure subscription to create a new directory, which inherently is free, but if you want more features you can try the premium version. You can of course integrate your organization's Windows Active Directory there in order to manage cloud-based application access.
To integrate with Azure AD in your ASP.NET Core application, you need to use OIDC and provide the required metadata for the Open Id Connect provider. To sign-in you don't have to do anything but return a Challenge
and sign-in phase will kick in by its own, returning an identity token back to your application, which can be stored in a cookie to keep the user logged-in for subsequent requests.
If you liked this blog, please like and share! For more, follow me on Twitter.
This post is part of the ASP.NET Core 2.0 Authentication series.
- ASP.NET Core 2.0 Cookie Authentication - Local logins
- ASP.NET Core 2.0 Authentication with local logins - Implementing claims transformation
- ASP.NET Core 2.0 Authentication with local logins - Responding to backend changes
- ASP.NET Core 2.0 Authentication with local logins - Implementing custom authorization policies
- ASP.NET Core 2.1 Authentication with social logins
- ASP.NET Core 2.0 Authentication with social logins - Implementing a profile store
- ASP.NET Core 2.0 Authentication with Azure Active Directory
- ASP.NET Core 2.0 Authentication with Azure Active Directory B2C
- ASP.NET Core 2.0 Authentication, IdentityServer4 and Angular
Comments powered by Disqus.