1
votes

Dotnet Core 2.2 - Azure AD Auth fonctionne mais la base de rôles renvoie l'accès refusé

J'essaie de faire fonctionner les rôles dans .Net Core 2.2 et aucune des autres solutions n'a fonctionné.

Dans le Startup.cs , Microsoft génère ce code dans un nouveau .Net 2.2 qui ne fonctionne pas pour une raison quelconque, mais le fait de faire fonctionner ce bloc n'est pas le sujet, mais il serait bien de savoir pourquoi ce n'est pas le cas. Dit "Aucun authenticationScheme n'a été spécifié et aucun DefaultChallengeScheme n'a été trouvé." Mais c'est ce que Microsoft a généré.

services.AddAuthentication(sharedOptions =>
            {
                sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
            })
            .AddAzureAd(options => Configuration.Bind("AzureAd", options))
            .AddCookie();

Dans mon vrai Startup.cs , j'ai dû utiliser ce qui est ci-dessous

services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
                .AddAzureAd(options => Configuration.Bind("AzureAd", options));

Donc, ce qui précède est le seul moyen pour qu'Azure AD fonctionne avec l'attribut [Authorize] . Le problème est que lorsque j'essaie d'autoriser avec des rôles. J'ai essayé de nombreuses suggestions mais je n'ai eu aucun succès. Chaque fois que j'ai un [Authorize (Roles = "")] , je suis redirigé vers la méthode AccessDenied () dans le AccountController que Microsoft a généré pour Azure AD, essentiellement accès refusé. J'utilise des rôles que j'ai créés dans AD, j'ai également créé un groupe dans Azure AD, en utilisant également un rôle appelé "Utilisateurs du domaine" qui est essentiellement donné à chaque employé de l'entreprise et est l'autorisation la plus élémentaire dont dispose chaque employé . Si les "utilisateurs du domaine" obtiennent un "accès refusé", je n'ai aucune idée de ce que je ne comprends pas ici.

J'ai suivi la documentation Microsoft pour les rôles, mais il n'y a rien là-dedans qui me demande d'en ajouter plus. les options services.AddAuthentication () .


0 commentaires

3 Réponses :


1
votes

Vous devez configurer le manifeste d'application dans AzureAD pour recevoir les rôles AD.

Remplacez la valeur "groupMembershipClaims" dans le manifeste par "Tous".

Notez que si vous avez un grand nombre de groupes, vous pouvez finir par rendre la réponse trop grande, donc tout le monde voudra peut-être être réduit aux seuls groupes que vous souhaitez réellement regrouper.


10 commentaires

Je l'ai changé en "tout" mais je ne reçois rien de différent en retour. Aucun rôle ou groupe. Comment réduiriez-vous les valeurs que vous souhaitez également? Je ne pouvais pas spécifier les types de rôles que je voulais, a déclaré des valeurs invalides. Je n'en avais toujours pas.


À ce stade, je ne peux pointer que vers la documentation AzureAD, github.com/ Azure-Samples /…


Est-ce pour .Net Core?


Oui, malheureusement, c'est pour .Net, nous recherchons la solution pour .Net Core qui est différente.


L'écoulement des groupes devrait toujours se produire avec les indicateurs, ce qui n'est pas spécifique à la version. Ajoutez un point d'arrêt et voyez si l'utilisateur contient des revendications de rôle. Si ce n'est pas le cas, il s'agit probablement d'un problème de configuration AAD.


J'ai ajouté un point d'arrêt et j'ai cherché assez fort tout ce qui n'était pas là avant. Je n'ai rien vu sur les rôles car il aurait dû y en avoir beaucoup. Si cela fonctionnait, les rôles devraient-ils apparaître dans les revendications?


Oui, les rôles sont essentiellement des revendications de type de rôle.


Peut-être que cela a pris un moment pour filtrer mais oui maintenant je vois une tonne d'entrées de groupe! Cela pourrait être un gagnant! En inspectant les groupes, je ne vois rien sur le nom de ce groupe. Je suppose que je pourrais essayer de m'authentifier à nouveau avec les rôles et voir si cela fonctionne maintenant mais je ne vois pas les noms des groupes donc je ne sais pas. Savez-vous si les rôles et les groupes sont la même chose?


Une fois que je pourrai demander à quelqu'un d'accorder l'autorisation de groupe que je demande, je verrai si ma déclaration ci-dessus change. Savez-vous si je commence à extraire correctement des groupes que l'attribut [Authorize (Roles = "role")] fonctionnera?


N'oubliez pas que les groupes ne seront pas dans le jeton s'il y en a trop. Par exemple, 200 est le maximum pour un JWT.



1
votes

Veuillez d'abord confirmer que vous obtenez les groupes sous forme de jeton, après avoir changé la valeur "groupMembershipClaims" dans le manifeste en "All", vous pouvez mettre le code ci-dessous dans le contrôleur:

services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
    .AddAzureAD(options => Configuration.Bind("AzureAd", options));

Après l'utilisateur est authentifié dans l'application, vous devriez obtenir les revendications groupes :

 entrez la description de l'image ici

Ensuite, vous pouvez utiliser un attribut avec une stratégie nommée, puis vous définissez la stratégie au démarrage pour exiger une revendication de groupe et définir l'ID de groupe autorisé:

[Authorize(Policy = "CanAccessGroup")]
public IActionResult About()
{
    return View();
}

Dans le contrôleur:

services.AddAuthorization(options =>
{
    options.AddPolicy(
        "CanAccessGroup",
        policyBuilder => policyBuilder.RequireClaim("groups", "0c71eab2-6618-4c53-bcce-806xxxxxx"));
});


4 commentaires

Je suppose que c'est la meilleure façon que j'ai vue jusqu'à présent. J'espérais faire fonctionner l'attribut [Authorize (Roles = ""] , ne pouvons-nous pas faire cela avec des groupes? Quand j'utilise le code services.AddAuthentication qu'ils ont généré dans les modèles, c'est ce que j'obtiens.


Cela fonctionne, mais le problème est que je récupère des centaines de groupes. La seule option pour le réduire est d'utiliser la valeur "Security Groups" qui me laisse encore à 100s. Je suppose qu'il n'y a pas d'autre moyen de réduire cela. Mais la requête / réponse est trop volumineuse et affiche Bad Request .


@DanielJackson, alors vous ne devez pas utiliser de groupes, utiliser des rôles, vous pouvez définir les rôles dans votre application dans le manifeste de l'application, puis leur attribuer des utilisateurs. Une fois que vous avez fait ces deux choses, il y aura une revendication appelée «rôles» dans le JWT que vous obtenez, qui contient le rôle de l'utilisateur.


Oui, vous avez raison, il a fallu un moment pour que l'effet soit filtré, mais je reçois maintenant le rôle d'application dans le code et [Authorize (Roles = "role")] fonctionne! Merci pour l'aide.



2
votes

Voici ce qui fonctionne pour moi, Application Web .Net Core 2.2 utilisant des rôles.

Manifeste d'application modifié pour inclure des rôles, par exemple

public class AccountController : Controller
{
    [HttpGet]
    public IActionResult SignIn()
    {
        var redirectUrl = Url.Action(nameof(HomeController.Index), "Home");
        return Challenge(
            new AuthenticationProperties { RedirectUri = redirectUrl },
            OpenIdConnectDefaults.AuthenticationScheme);
    }

    [HttpGet]
    public IActionResult SignOut()
    {
        var callbackUrl = Url.Action(nameof(SignedOut), "Account", values: null, protocol: Request.Scheme);
        return SignOut(
            new AuthenticationProperties { RedirectUri = callbackUrl },
            CookieAuthenticationDefaults.AuthenticationScheme,
            OpenIdConnectDefaults.AuthenticationScheme);
    }

    [HttpGet]
    public IActionResult SignedOut()
    {
        if (User.Identity.IsAuthenticated)
        {
            // Redirect to home page if the user is authenticated.
            return RedirectToAction(nameof(HomeController.Index), "Home");
        }

        return View();
    }

    [HttpGet]
    public IActionResult AccessDenied()
    {
        return View();
    }
}

Startup.cs p >

[Authorize(Roles = "Writer")]

Ajoutez des extensions pour contourner le problème que vous avez mentionné, dans votre "bloc supérieur" de code.

AzureAdAuthenticationBuilderExtensions.cs

public class AzureAdOptions
{
    public string ClientId { get; set; }
    public string ClientSecret { get; set; }
    public string Instance { get; set; }
    public string Domain { get; set; }
    public string TenantId { get; set; }
    public string CallbackPath { get; set; }

    //manually added
    public string TargetApiAppId { get; set; }
}


2 commentaires

C'est à peu près ce que j'ai découvert aussi. Vous devez utiliser les rôles d'application définis dans le manifeste de l'application. Ce qui est bien, c'est qu'un rôle peut être créé dans notre AD sur site habituel qui apparaîtra dans Azure AD. Ce rôle peut être attribué à l'application avec l'un des rôles créés dans le manifeste de l'application. Ensuite, chaque fois que vous ajoutez un utilisateur à l'AD sur site, il obtiendra automatiquement l'accès une fois qu'il sera synchronisé avec Azure AD.


Cool en effet! Je fais cela dans une autre application Web, combinez-le avec l'authentification basée sur des règles et cela devient assez puissant. Par exemple. services.AddAuthorization (options => {options.AddPolicy ("Analyst", policy => policy.RequireRole ("DataAnalyst")); options.AddPolicy ("Reader", policy => policy.RequireAssertion (context => context.User.HasClaim (ClaimTypes.Role, "DataAnalyst") || context.User.HasClaim (ClaimTypes.Role, "DataReader")));});