没有对话框提示的ADAL身份验证

Ale*_*gas 5 dynamics-crm azure dynamics-crm-online azure-active-directory adal

我在Azure AD中注册了一个连接到CRM Online的控制台应用程序(使用这些步骤配置).它查询Web API.

应用程序需要在没有用户交互的情况下运行...但不幸的是,调用AcquireTokenSilentAsync总是失败并且只能AcquireTokenAsync运行.这会使用户登录对话框出现,但无法满足用户交互要求!

有没有办法阻止这个提示,要么通过在客户端机器上保存登录(到目前为止没有工作)或者可能使用证书(但你怎么做?)或其他什么?

我正在使用ADAL for .NET v3.10.305110106版本.以下代码用于验证:

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);
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*gas 5

感谢@aravind,他指出了active-directory-dotnet-native-headless示例.

该示例包含一个继承自的FileCache类Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache.该类管理将凭据缓存到磁盘上的加密文件.这意味着首次运行时只有一个提示,之后凭据在本地存储.

最后一块拼图是:

  1. AuthenticationContext使用FileCache 调用不同的构造函数签名进行初始化:

    _authInfo.Context = new AuthenticationContext(
        _authInfo.AuthorityUrl, false, new FileCache());
    
    Run Code Online (Sandbox Code Playgroud)
  2. 从用户获取凭据到Microsoft.IdentityModel.Clients.ActiveDirectory.UserPasswordCredential对象中(请参阅TextualPrompt() 示例中的方法)

  3. 将凭据传递给其他方法签名AcquireTokenAsync():

    authResult = await _authInfo.Context.AcquireTokenAsync(
        _authInfo.Resource, _authInfo.ClientId, userCredential);
    
    Run Code Online (Sandbox Code Playgroud)