Problem
How to implement Azure AD authentication in ASP.NET Core 2.0.
Solution
In previous posts, we have seen how to secure our applications using:
In this and the next post, I’ll demonstrate how to use Azure AD to delegate identity and access management to Azure, simplifying our application.
Configure Azure AD
Create Azure subscription (start for free, gives you credit to play).
Create new resource and search for ‘azure active directory
’:
Create new instance:
Enter details, including the unique ‘initial domain name’, this will become the Tenant Name that will be used in your application, e.g., below the tenant name will be fiverad.onmicrosoft.com
:
Once directory is created, we need to register our application:
Enter details for your application, including the URL to your application home/sign-in page:
Once the application is created, you’ll see ‘Application ID’ in the list. This will be used in our application later as ‘Client ID’:
Click on application and ‘Reply URLs, enter URL where Azure AD will redirect user after authentication (https://localhost:44308/security/signin-callback):
Next, we’ll create a user in Azure AD:
Note that username is based on our directory’s domain name, i.e., @fiverad.onmicrosoft.com
also makes a note of the temporary password, you’ll be required to change it on first login:
So far, you have:
- Created Azure AD
- Registered your application
- Added a user
Next, we’ll setup our application and use Azure AD to authenticate users.
Configure Application
Create an empty project and update Startup
to configure services and middleware for MVC and Authentication:
public class Startup
{
private readonly string TenantName = "";
private readonly string ClientId = "";
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme =
CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme =
CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme =
OpenIdConnectDefaults.AuthenticationScheme;
}).AddOpenIdConnect(options =>
{
options.Authority = "https://login.microsoftonline.com/" +
this.TenantName;
options.ClientId = this.ClientId;
options.ResponseType = OpenIdConnectResponseType.IdToken;
options.CallbackPath = "/security/signin-callback";
options.SignedOutRedirectUri = "https://localhost:44308/";
}).AddCookie();
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseAuthentication();
app.UseMvcWithDefaultRoute();
}
}
Here, we are setting up Open ID Connect authentication middleware services with:
Authority
: path to the Azure AD tenant that we’ve setup as authentication server ClientId
: application identifier that Azure AD provides for our application ResponseType
: value that determines authorization flow used and parameters returned from server. We are interested only in authorization token for now. CallbackPath
: path where server will redirect after authentication. We don’t need to create this in our application, the middleware will handle this. SignedOutRedirectUri
: path where server will redirect after signing out. This is the path to our application home page, for instance.
Also, when configuring authentication middleware, we’ve specified Open ID Connect as challenge scheme. This is the middleware ASP.NET Core will use for users who have not been signed in.
Once signed in, we want to store their identity in a cookie, instead of redirecting to authentication server for every request. For this reason, we’ve added cookie authentication middleware and are using that as default sign-in scheme. If the cookie is missing, users will be ‘challenged’ for their identity.
Add a controller to implement login/logout actions:
public class SecurityController : Controller
{
public IActionResult Login()
{
return Challenge(new AuthenticationProperties { RedirectUri = "/" });
}
[HttpPost]
public async Task Logout()
{
await HttpContext.SignOutAsync(
CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignOutAsync(
OpenIdConnectDefaults.AuthenticationScheme);
}
}
When logging out, it is important to sign-out from authentication server (Azure AD) and also remove the cookie by signing out from cookie authentication scheme.
Secure controllers (or their actions) using [Authorize]
attribute:
[Authorize]
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
}
Run the application and you’ll be redirected to Azure for authentication.