背景资料 .
我有一个应用程序(MS Teams Bot),我在Microsoft Azure中作为"App Service"托管 . 这个应用程序 . 此应用程序具有自己的应用程序ID . 在其"Settings"中,我修改了"Authentication/Authorization",因为这样,
因此,我在Azure中的现有应用服务中创建了一个新的Azure Active Directory应用程序 . 现在这个应用程序有自己的应用程序ID和密钥 . 已启用多租户功能 .
此应用程序具有以下权限,
应用权限 .
委派权限 .
问题 .
我在Azure中有2个不相关的环境 . 一个(我们可以称之为Azure A),用于托管测试应用程序,另一个(Azure B)用于托管实时应用程序,并且是我们的实时活动目录的主机 . 我的bot应用程序位于Azure A中,但是当Azure B中的用户使用bot时,bot会尝试根据它来自的活动目录对用户进行身份验证,但是无法执行此操作 . 我的机器人应用程序获得了一个访问令牌,以便对它成功获取的api“https://graph.microsoft.com”进行运行 . 这里我有一个类,它为我的bot应用程序获取一个访问令牌来运行,
class AzureAuthenticationProvider : IAuthenticationProvider
{
public async Task AuthenticateRequestAsync(HttpRequestMessage request)
{
string clientId = "client-id"; // azure ad app id
string clientSecret = "client-secret"; // azure ad app secret
string authority = "https://login.microsoftonline.com/tenant-id"; // Authentication URI. tenant-id taken from Azure B
AuthenticationContext authContext = new AuthenticationContext(authority);
ClientCredential creds = new ClientCredential(clientId, clientSecret);
AuthenticationResult authResult = await authContext.AcquireTokenAsync("https://graph.microsoft.com/", creds);
request.Headers.Add("Authorization", "Bearer " + authResult.AccessToken);
}
}
然后我运行以下命令尝试从Azure B访问用户信息,
GraphServiceClient client = new GraphServiceClient(new AzureAuthenticationProvider());
string userId = user object id from Azure B;
User user = await client.Users[userId].Request().GetAsync();
然后我收到以下错误,
Microsoft.Graph.ServiceException: Code: Authorization_IdentityNotFound Message: The identity of the calling application could not be established.
所以我的问题是,
i)AuthenticateRequestAsync()中使用的客户端ID和密码应该是Azure Active Directory应用程序还是应该从我的bot应用程序中获取?这两个在Azure A中的相同应用服务中运行 .
ii)如果Azure Active Directory应用程序为其启用了多租户,它是否能够从我的域外部的活动目录中对用户进行身份验证?
iii)我怀疑身份验证URI必须包含用户所在位置的租户ID(Azure B),而不是托管应用程序所在位置的租户ID(Azure A),这是正确的吗?
1 回答
从AAD注册:
clientid
= AAD应用程序的应用程序ID .clientSecret
= AAD应用程序的生成密钥 .是的,这是多租户解决方案的用例之一 .
在这种情况下,您要使用/common endpoint(
https://login.microsoftonline.com/common
) . 这将针对他们所居住的租户对用户进行身份验证 .如果是单租户应用程序,则使用
/{tenant-id}
代替/common
. 另请注意client_credential
OAuth流不支持/common
endpoints .