Reputation: 11895
I have two websites, a "customer" website that contains local users stored in Identity tables in a SQL Server database, and a "management" website the logs in users via our Azure AD. Both websites share a common view of the SQL database (I put the migrations and DbContext in a shared library).
My management website wants to automatically redirect users to Azure AD if they are not authenticated. This is done in Startup.cs via:
// Use AzureAD for authentication
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
So far, so good... The above code causes the website to automatically log in via my Azure AD.
Now for the complication: Code in the the management website wants to manipulate "Identity" users created by the "customer" website. To do this, the management website needs UserManager
and RoleManager
instances. But the only way I know to wire up a UserManager
or a 'RoleManager' is to call AddIdentity
or AddDefaultIdentity
, like this:
// Configure Identity
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
// Use AzureAD for authentication
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
This allows me to use DI to get a UserManager
or RoleManager
instance elsewhere in the code, but it turns off the automatic login via Azure AD and tries to redirect to the Identity login page (which, in my "management" website, doesn't exist).
How can I configure Identity while retaining the automatic Azure AD login behavior?
EDIT:
Microsoft tech support is working on this. I'll post the answer when I get it from them.
Upvotes: 1
Views: 2066
Reputation: 56
Use AddIdentityCore and inject UserManager and RoleManager separately like below
services.AddIdentityCore<AppUser>(options =>
options.SignIn.RequireConfirmedAccount = false)
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<AppUserContext>();
services.AddScoped<UserManager<AppUser>>();
services.AddScoped<RoleManager<IdentityRole>>();
services.AddScoped<IRoleStore<IdentityRole>, RoleStore<IdentityRole, ApplicationDbContext>>();
Difference between AddIdentity and AddIdentityCore Refer
Github sample here
Upvotes: 3
Reputation: 168
It seems that Identitys authentication theme Identity.Application
is used in the default authorization policy for your authorized controllers. Try to explicitly set the default authorization policy to use the AzureAD authentication theme, e.g.:
services.AddAuthorization(options =>
{
options.DefaultPolicy = new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(AzureADDefaults.AuthenticationScheme)
.RequireAuthenticatedUser()
.Build();
});
Edit:
Have a look at the AddIdentity
extension method in IdentityServiceCollectionExtensions.cs on GitHub, within that method AddAuthentication is called:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})
Perhaps you have to overwrite these settings with the corresponding constants from the AzureADDefaults
in the AddAuthentication
call on which you call AddAzureAd
like:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = AzureADDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = AzureADDefaults.AuthenticationScheme;
options.DefaultSignInScheme = AzureADDefaults.CookieScheme; // not sure
})
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
Upvotes: 0