5

Mam zarejestrowaną aplikację konsoli w usłudze Azure AD, która łączy się z usługą CRM Online (skonfigurowaną przy użyciu these steps). Pyta on Web API.Autoryzacja ADAL bez pytania w oknie dialogowym

Aplikacja musi działać bez interakcji użytkownika ... ale niestety połączenie z AcquireTokenSilentAsync zawsze kończy się niepowodzeniem i działa tylko AcquireTokenAsync. To sprawia, że ​​pojawia się okno dialogowe logowania użytkownika, które nie spełnia wymagań interakcji użytkownika!

Czy istnieje sposób, aby zapobiec wyświetleniu monitu, zapisując login gdzieś na komputerze klienta (który nie działał do tej pory) lub używając certyfikatu (ale jak to zrobić?) Lub coś takiego jeszcze?

Używam ADAL dla wydania .NET v3.10.305110106. Poniższy kod służy do uwierzytelniania:

private static async Task PerformOnlineAuthentication() 
{ 
    _authInfo = new AuthInfo(); // This is just a simple class of parameters 

    Console.Write("URL (include /api/data/v8.x): "); 
    var url = Console.ReadLine(); 

    BaseUri = new Uri(url); 
    var absoluteUri = BaseUri.AbsoluteUri; 
    _authInfo.Resource = absoluteUri; 

    Console.Write("ClientId: "); 
    var clientId = Console.ReadLine(); 
    _authInfo.ClientId = clientId; 

    Console.Write("RedirectUri: "); 
    var redirectUri = Console.ReadLine(); 
    _authInfo.RedirectUri = new Uri(redirectUri); 

    var authResourceUrl = new Uri($"{_authInfo.Resource}/api/data/"); 
    var authenticationParameters = await AuthenticationParameters.CreateFromResourceUrlAsync(authResourceUrl); 

    _authInfo.AuthorityUrl = authenticationParameters.Authority; 
    _authInfo.Resource = authenticationParameters.Resource; 

    _authInfo.Context = new AuthenticationContext(_authInfo.AuthorityUrl, false); 
} 

private static async Task RefreshAccessToken() 
{ 
    if (!IsCrmOnline()) 
     return; 

    Console.WriteLine($"Acquiring token from: {_authInfo.Resource}"); 
    AuthenticationResult authResult; 
    try 
    { 
     authResult = await _authInfo.Context.AcquireTokenSilentAsync(_authInfo.Resource, _authInfo.ClientId); 
    } 
    catch (AdalSilentTokenAcquisitionException astae) 
    { 
     Console.WriteLine(astae.Message); 
     authResult = await _authInfo.Context.AcquireTokenAsync(_authInfo.Resource, _authInfo.ClientId, _authInfo.RedirectUri, new PlatformParameters(PromptBehavior.RefreshSession)); 
    } 

    HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken); 
} 
+0

hi, pan sprawdzić ten jeden https://github.com/Azure-Samples/active-directory-dotnet-native-headless? ma jednorazową nazwę użytkownika - tylko pwd. – Aravind

Odpowiedz

5

Dzięki @aravind który wskazał próbkę active-directory-dotnet-native-headless.

Próbka zawiera FileCache class, która dziedziczy po Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache. Ta klasa zarządza buforowaniem poświadczeń do zaszyfrowanego pliku na dysku. Oznacza to, że przy pierwszym uruchomieniu istnieje tylko jeden monit, a po tym dane uwierzytelniające są przechowywane lokalnie.

The końcowych kawałków układanki są:

  1. Wywołanie inny podpis konstruktora zainicjować AuthenticationContext z FileCache:

    _authInfo.Context = new AuthenticationContext(
        _authInfo.AuthorityUrl, false, new FileCache()); 
    
  2. Uzyskanie poświadczenia od użytkownika do Microsoft.IdentityModel.Clients.ActiveDirectory.UserPasswordCredential obiektu (patrz Przechodząc poświadczenia do innego podpisu metody na AcquireTokenAsync():

    authResult = await _authInfo.Context.AcquireTokenAsync(
        _authInfo.Resource, _authInfo.ClientId, userCredential); 
    
0

Jeśli „aplikacja musi uruchomić bez interakcji z użytkownikiem” Zastosowanie ClientCredential płynąć np

public static string GetAccessTokenUsingClientCredentialFlow(Credential cred) {   

     AuthenticationContext ac = new AuthenticationContext(cred.Authority); 
     AuthenticationResult r = ac.AcquireTokenAsync(cred.ResourceId, new ClientCredential(cred.ClientId, cred.ClientSecret)).Result; 
     return r.AccessToken; 
    }