Je souhaite créer une application ASP.NET Core 2.0 utilisant Azure Active Directory comme fournisseur d'identité (pour l'authentification) mais Identité ASP.NET Core pour l'autorisation (par exemple, à l'aide d'attributs de contrôleur tels que '[Authorize (Roles = " Admin ")] '). Dans la solution, je m'attends à ce que la table de base de données d'identité locale AspNetUserLogins contienne des références aux identités Azure Active Directory
Je pense que la solution impliquerait transformation de la revendication pour décorer l'utilisateur authentifié avec les rôles extraits de ASP.NET Core Identity.
Mes problèmes:
Les étapes pour reproduire ma ligne de base ...
Dans portal.Azure.com ...
Créez un projet ASP.NET Core 2.0 à l'aide de Visual Studio 2017 15.4.2 ...
Je suis moins sûr d'ici ...
(J'ai emprunté du code à la solution générée par un modèle avec les "options d'authentification" définies sur "Comptes d'utilisateurs individuels"> "Stocker les comptes d'utilisateurs dans l'application".)
Ajouter les classes suivantes
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<AspNetCoreIdentity.Data.ApplicationDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
}
public class ApplicationUser : IdentityUser
{
}
Ajoutez ce qui suit au début de Startup.ConfigureServices ()
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
Ajouter une chaîne de connexion à appsettings.json (en supposant que l'instance SQL Server par défaut sur la base d'hôte locale et la base d'identité est nommée 'AspNetCoreIdentity')
"ConnectionStrings": {
"DefaultConnection": "Data Source=.\\;Initial Catalog=AspNetCoreIdentity;Integrated Security=True;MultipleActiveResultSets=True"
}
Désormais, lorsque je lance à nouveau l'application, je me retrouve dans une boucle de redirection qui, à mon avis, s'exécute entre mon application et la connexion Azure Active Directory. Traçage montre ...
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization failed for user: (null).
Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker: Information: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
J'ai ensuite essayé d'ajouter des méthodes à AccountController (Login, ExternalLogin) dans l'espoir de pouvoir atteindre un point d'arrêt, mais maintenant, je suis vraiment bloqué.
autres références...
Je pense que cela fonctionne, mais je suis assez nouveau dans ce cadre, donc les critiques de cette méthode sont les bienvenues.
Au démarrage, je devais ajouter deux choses à l'exemple de Microsoft.
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddAzureAd(options => Configuration.Bind("AzureAd", options))
.AddCookie(options =>
{
options.AccessDeniedPath = "/AccessDenied";
});
// Remaining code removed
J'ai ensuite étendu le AzureAdAuthenticationBuilderExtensions > ConfigureAzureOptions class et j'effectue un travail supplémentaire (c'est-à-dire le chargement des rôles d'utilisateur à partir du magasin de rôles) lorsque l'événement de validation de jeton se produit.
AzureAdAuthenticationBuilderExtensions.cs
public void Configure(string name, OpenIdConnectOptions options)
{
options.ClientId = _azureOptions.ClientId;
options.Authority = $"{_azureOptions.Instance}{_azureOptions.TenantId}";
options.UseTokenLifetime = true;
options.CallbackPath = _azureOptions.CallbackPath;
options.RequireHttpsMetadata = false;
options.Events = new OpenIdConnectEvents
{
OnTokenValidated = (context) =>
{
// Load roles from role store here
var roles = new List<string>() { "Admin" };
var claims = new List<Claim>();
foreach (var role in roles) claims.Add(new Claim(ClaimTypes.Role, role));
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
context.Principal.AddIdentity(claimsIdentity);
return Task.CompletedTask;
}
};
}