将x509证书上传到Azure ADD或Microsoft注册门户上的Application Manifest

时间:2018-07-09 15:14:03

标签: asp.net-mvc azure outlook microsoft-graph

对同一问题的多篇帖子表示抱歉!

我正在尝试将自签名证书上载到在Microsoft注册门户上创建的应用程序清单中,但是我有一些我无法完全理解的问题,根据此answer,很有可能上载使用 DELEGATED PERMISSIONS 的证书,但是我不明白为什么不能使用 Application Permissions 的原因,因为我只需要AccessToken,并且我通过client_credential授予流程来获得该证书,

下面是我尝试过的代码,但是当使用client_credential授予流检索令牌时,我陷入了var application = activeDirectoryClient.Applications["ApplicationObjectId"].ExecuteAsync().Result;

并且尝试使用Tom Sung在上一篇文章中提供给我的代码时,应用程序退出,错误为“请求主体中必须具有client_credentil或client_assertion”

这是我尝试过的代码:

 private static async Task<string> GetAppTokenAsync(string graphResourceId, string tenantId, string clientId, string userId)
    {

        string aadInstance = "https://login.microsoftonline.com/" + tenantId + "/oauth2/token";
        var clientCredential = new ClientCredential(clientId, clientSecret);
        AuthenticationContext authenticationContextt =
            new AuthenticationContext($"https://login.microsoftonline.com/{tenantId}/oauth2/token");
        AuthenticationResult result =
            await authenticationContextt.AcquireTokenAsync(graphResourceId,
                clientCredential);
        //token is acquiered and gets stuck 
        var e = result.AccessToken;


        //Tom Suns code
        IPlatformParameters parameters = new PlatformParameters(PromptBehavior.SelectAccount);
        AuthenticationContext authenticationContext = new AuthenticationContext(aadInstance);
        var authenticationResult = await authenticationContext.AcquireTokenAsync(graphResourceId, clientId, new Uri("http://localhost"), parameters, new UserIdentifier(userId, UserIdentifierType.UniqueId));
        //exits with error
        return authenticationResult.AccessToken;
    }


try
 {          
    var graphResourceId = "https://graph.windows.net";
    var userId = "****";
    //used to test if token is acquired
    //var tokennn = await GetAppTokenAsync(graphResourceId, tenantID, ClientId, userId);
    var servicePointUri = new Uri(graphResourceId);
    var serviceRoot = new Uri(servicePointUri, tenant);
    var activeDirectoryClient = new ActiveDirectoryClient(serviceRoot, async () => await GetAppTokenAsync(graphResourceId, tenantID, ClientId, userId));
    AsymmetricKeyParameter myCAprivateKey = null;
    //generate a root CA cert and obtain the privateKey
    X509Certificate2 MyRootCAcert = CreateCertificateAuthorityCertificate("CN=OutlookIntegration", out myCAprivateKey);
    //add CA cert to store
    addCertToStore(MyRootCAcert, StoreName.Root, StoreLocation.LocalMachine);
    var expirationDate = DateTime.Parse(MyRootCAcert.GetExpirationDateString()).ToUniversalTime();
    var startDate = DateTime.Parse(MyRootCAcert.GetEffectiveDateString()).ToUniversalTime();
    var binCert = MyRootCAcert.GetRawCertData();
    var keyCredential = new KeyCredential
        {
           CustomKeyIdentifier = MyRootCAcert.GetCertHash(),
           EndDate = expirationDate,
           KeyId = Guid.NewGuid(),
           StartDate = startDate,
           Type = "AsymmetricX509Cert",
           Usage = "Verify",
           Value = binCert
         };
     //gets stuck here when using clientsecret grant type
     var application = activeDirectoryClient.Applications["ApplicationObjectId"].ExecuteAsync().Result;
                application.KeyCredentials.Add(keyCredential);
                application.UpdateAsync().Wait();
}
catch (Exception exception)
{
   Console.WriteLine(exception);
   throw;
}

我现在完全陷入困境,任何人都知道为什么它不能使用应用程序权限,或者为什么会陷入var application = activeDirectoryClient.Applications["ApplicationObjectId"].ExecuteAsync().Result;

编辑1 是因为我将我的应用程序作为使用用户名和密码进行身份验证的Web应用程序/ API?

1 个答案:

答案 0 :(得分:1)

根据我的测试,如果我们要更改 keyCredential ,则需要DELEGATED PERMISSIONS

如果要更新Azure AD应用程序的其他属性,则可以使用应用程序权限。

参考:

Azure Active Directory developer glossary

  •   

    “委派”权限(使用登录资源所有者的委派授权指定基于作用域的访问)在运行时作为客户端访问令牌中的“ scp”声明提供给资源。

  •   

    “应用程序”权限(使用客户端应用程序的凭据/身份指定基于角色的访问)在运行时作为资源显示在资源中,作为客户端访问令牌中的“角色”声明。