I am currently working on a login system where a user has the option to login with either their organization email (AD authentication) or regular email and password as shown below:
Before adding Identity, I was able to successfully sign in and out with AD authentication. And here's how I achieve that:
Program.cs
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(config.GetRequiredSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi(
["user.read"]
)
.AddInMemoryTokenCaches();
builder.Services.Configure<OpenIdConnectOptions>(
OpenIdConnectDefaults.AuthenticationScheme,
options =>
{
options.SignedOutCallbackPath = "/signout-callback-oidc";
options.SignedOutRedirectUri = "/Identity/Account/SignOut";
}
);
AccountController.cs
[Route("SignIn")]
[Route("[area]/[controller]/[action]")]
public IActionResult SignIn()
{
var redirect = Url.Action("Overview", "DashboardView", new { area = "Events" });
var scheme = OpenIdConnectDefaults.AuthenticationScheme;
return Challenge(
new AuthenticationProperties { RedirectUri = redirect },
scheme
);
}
[Route("SignOut")]
[Route("[area]/[controller]/[action]")]
public new IActionResult SignOut()
{
var callbackUrl = Url.Action("LogIn", "Account", new { area = "Identity" }, protocol: Request.Scheme);
return SignOut(new AuthenticationProperties { RedirectUri = callbackUrl },
CookieAuthenticationDefaults.AuthenticationScheme,
OpenIdConnectDefaults.AuthenticationScheme);
}
The problem started to arise when I incorporate Asp.net Identity
Program.cs
builder.Services.AddIdentity<IdentityUser, IdentityRole>()
.AddEntityFrameworkStores<ActraContext>()
.AddDefaultTokenProviders();
// Updated AddAuthentication for Identity
builder.Services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddMicrosoftIdentityWebApp(config.GetRequiredSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi(
["user.read"]
)
.AddInMemoryTokenCaches();
builder.Services.ConfigureApplicationCookie(options => {
options.LoginPath = "/Identity/Account/SignIn";
options.LogoutPath = "/Identity/Account/SignOut";
options.AccessDeniedPath = "";
options.ReturnUrlParameter = "returnUrl";
});
The code above will create infinite redirect to the action method SignIn and ultimately prevent the user to login with Entra Authentication.
I haven't started on the second part of the authentication (email and password authentication yet.
I read this documentation to incorporate identity and identity entity models Link To Docs
I read this documentation to sign a user in and out with AD authentication Link To Docs
I found the answer by reading this thread
Here's the updated code
builder.Services.AddAuthentication(options => {
options.DefaultScheme = IdentityConstants.ApplicationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddMicrosoftIdentityWebApp(config.GetRequiredSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi(["user.read"])
.AddInMemoryTokenCaches()
.AddMicrosoftGraph();
builder.Services.Configure<OpenIdConnectOptions>(
OpenIdConnectDefaults.AuthenticationScheme,
options =>
{
options.SignInScheme = IdentityConstants.ApplicationScheme;
options.SignedOutCallbackPath = "/signout-callback-oidc";
options.SignedOutRedirectUri = "/Identity/Account/SignOut";
}
);