1
votes

Authentification des appels HttpClient à partir de .NET Core sur MacOS

Ma question aujourd'hui est:
Comment configurer HttpClient pour qu'il puisse authentifier l'appel sans déranger l'utilisateur sur MacOS?
(Application console .NET Core 2.2 exécutée en tant qu'agent de lancement sur MacOS, appelant une API Web sur IIS avec NTLM et Kerberos activés, via le réseau interne de notre entreprise)

Longue histoire:
J'ai une application .NET Core qui utilise la méthode suivante pour appeler une API Web:

Interop+NetSecurityNative+GssApiException - GSSAPI operation failed with error
The provided name was not a mechanism name. (unknown mech-code 0 for mech unknown).
at Microsoft.Win32.SafeHandles.SafeGssNameHandle.CreatePrincipal(String name)

Lorsque je l'exécute sur ma machine Windows, l'application se connecte facilement et obtient le résultat .
Cependant, lorsque j'exécute ceci sur un Mac, j'obtiens une exception:

var handler = new HttpClientHandler() 
{ 
   UseDefaultCredentials = true 
};

var client = new HttpClient(handler)
{
   BaseAddress = new Uri("https://MyWebAPI.MyCompanyName.com/")
};

string result = client.GetAsync("MyEndpointSubURL")
    .Result.Content.ReadAsStringAsync().Result;

Des idées de ce que je dois changer pour que cela fonctionne?

Nous voulons désespérément éviter de déranger l'utilisateur avec des invites (il s'agit d'un service de synchronisation en arrière-plan).

Rappelez-vous, c'est une application console .NET Core 2.2 exécutée en tant qu'agent de lancement sur MacOS. L'API Web qu'elle appelle est une API Web Asp.NET hébergée avec IIS avec NTLM et Kerberos activés et je n'ai besoin que de dépasser IIS (l'API Web n'utilise aucun mécanisme d'authentification / autorisation par elle-même). L'API n'est exposée que sur le réseau interne de notre entreprise, de sorte que l'utilisateur est déjà connecté au réseau.


0 commentaires

4 Réponses :


0
votes

Essayez ceci: Avec un exemple d'authentification de base.

            var url = "https://MyWebAPI.MyCompanyName.com/";
            using (var httpClient = new HttpClient())
            {
            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "Base64Credetials");

                using (var response = await httpClient.GetAsync(url))
                    if (response.IsSuccessStatusCode)
                    {
                        var strResponse = await response.Content.ReadAsStringAsync();
                        MyObject result = JsonConvert.DeserializeObject<MyObject>(strResponse);
                        if (result != null)
                        {
                            //Your code here
                        }
                    }
            }


1 commentaires

Hé, merci pour la réponse. Juste pour être sûr ... par "Base64Credetials" vous voulez dire littéralement cette phrase, ou est-ce "nom d'utilisateur: mot de passe" encodé en base64? Si c'est le dernier, cela ne fonctionnera pas pour moi, à moins que vous ne suggériez un autre moyen de récupérer le mot de passe de l'utilisateur. Comme indiqué précédemment, je ne veux pas demander le mot de passe à l'utilisateur. Je veux qu'il soit authentifié en fonction de ce qu'il a entré dans l'écran de connexion du Mac, tout comme cela se produit lorsque j'exécute mon code sur une machine Windows.



0
votes

Je ne pense pas que MacOS ait un concept d '"authentification par défaut" de la même manière que Windows. Kerberos et NTLM sont tous deux des concepts Windows. Je soupçonne que sur MacOS, vous devrez utiliser un schéma d'authentification différent (Basic ou Bearer), puis récupérer les informations d'identification d'un endroit comme le trousseau. Une application de l'IIRC peut bénéficier d'un accès en lecture silencieux au porte-clés.


2 commentaires

Merci pour l'idée! Si vous trouvez un moment, j'apprécierais un extrait de la solution ou des liens :)


Je n'ai malheureusement pas de Mac mais ceci est quelque chose que j'ai trouvé qui utilise Xamarin.Security je pense.



1
votes

Essayez d'exécuter kinit @ à partir du terminal, puis exécutez à nouveau votre programme. Vous devrez peut-être configurer votre fichier krb5.conf pour qu'il pointe correctement vers le contrôleur de domaine.

Nous avons des "informations d'identification par défaut" fonctionnant dans notre système sur Mac avec .NET Core 2.1+ en utilisant le même code que vous montrez ici. La configuration de Kerberos via kinit et le fichier conf est le plus grand défi.

D'après ce que je peux dire, .NET n'utilise pas le cache produit en exécutant kinit , mais c'est ce qui configure le principal à utiliser. L'interaction de .NET avec Kerberos est mal documentée. Voir https://github.com/dotnet/corefx/issues/30203#issuecomment -395592407


1 commentaires

Hé, merci pour la réponse. Je suppose que votre confirmation que cela fonctionne pour vous sur Mac est très utile, car nous sommes maintenant assez certains que nos configurations de serveur / réseau sont à blâmer. Nous avons une entreprise très réticente au risque et il semble que trop de précautions aient été prises lors du renforcement de notre infrastructure ^^ '



1
votes

J'ai eu beaucoup de mal à faire fonctionner cela sur macOS avec .NET Core 2.2.

J'ai suivi la documentation en ligne sur la configuration de votre krb5.conf , l'exécution de kinit et klist pour m'assurer que j'avais un billet Kerberos valide.

Après tout cela, Kerberos travaillait avec Azure Data Studio, donc je savais que ma configuration était correcte, mais je ne pouvais pas obtenir HttpClient avec UseDefaultCredentials = true code > travail. Cela a toujours échoué avec la même erreur:

System.ComponentModel.Win32Exception: GSSAPI operation failed with error -  An unsupported mechanism was requested (unknown mech-code 0 for mech unknown).

Cela fonctionnait cependant sur la machine d'un collègue.

Après de nombreuses recherches, nous avons découvert que mon collègue avait installé .NET Core 2.2.7 alors que je n'avais que 2.2.1. La mise à niveau de ma station de travail vers .NET Core 2.2.8 a résolu mon problème. La restauration de notre application pour utiliser la version 2.1.13 a également fonctionné.

J'espère que cela aidera quelqu'un d'autre à l'avenir.


0 commentaires