我正在尝试访问我在 Azure 上托管并使用 Azure AD 保护的 API 应用程序。
对于 API 应用程序,我设置了应用程序服务身份验证 = Azure Active Directory“Express”管理模式。
在“经典”门户中,我在 AD 下创建了几个应用程序。一个用于 API 应用程序,另一个用于 Web 应用程序。对于 Web 应用程序,我在 API 应用程序的“其他应用程序的权限”下添加了一个条目(尽管我不确定我是否需要此条目,因为 API 应用程序的“访问应用程序所需的用户分配”已关闭)。我还为 Web 应用程序生成了 key 。
按照此处给出的示例代码 - https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-oauth2-appidentity ...
我可以使用以下代码成功获取不记名 token :
private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
private static string tenant = ConfigurationManager.AppSettings["ida:Tenant"];
private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
private static string appKey = ConfigurationManager.AppSettings["ida:AppKey"];
static string authority = String.Format(CultureInfo.InvariantCulture, aadInstance, tenant);
private static string ApiId = ConfigurationManager.AppSettings["ApiId"];
private static AuthenticationContext authContext = new AuthenticationContext(authority);
private static ClientCredential clientCredential = new ClientCredential(clientId, appKey);
...
AuthenticationResult result = null;
int retryCount = 0;
bool retry = false;
do
{
retry = false;
try
{
// ADAL includes an in memory cache, so this call will only send a message to the server if the cached token is expired.
result = await authContext.AcquireTokenAsync(ApiId, clientCredential);
}
catch (AdalException ex)
{
if (ex.ErrorCode == "temporarily_unavailable")
{
retry = true;
retryCount++;
Thread.Sleep(3000);
}
}
} while ((retry == true) && (retryCount < 3));
if (result == null)
return Request.CreateResponse(HttpStatusCode.InternalServerError, "Could not authenticate against API.");
但是当我将不记名 token 与从 Web 应用程序到 API 应用程序的请求一起使用时,我总是收到 401 未经授权的响应:
StatusCode: 401, ReasonPhrase: 'Unauthorized', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
Date: Wed, 13 Jul 2016 08:43:09 GMT
Server: Microsoft-IIS/8.0
WWW-Authenticate: Bearer realm="MY-API-APP-ID-IS-HERE"
X-Powered-By: ASP.NET
Content-Length: 58
Content-Type: text/html
}
这是我用来发出失败并出现 401 错误的请求的代码:
var apiUri = new Uri(ConfigurationManager.AppSettings["ApiUrl"] + "/api/MethodImCalling");
var client = new RestClient(apiUri.GetLeftPart(UriPartial.Authority));
var request = new RestRequest(apiUri, Method.GET);
request.AddHeader("Authorization", "Bearer " + result.AccessToken);
request.AddParameter("something", somevalue);
var response = client.Execute(request);
if (response.StatusCode != HttpStatusCode.OK)
return Request.CreateResponse(response.StatusCode); // Relay non-successful response
有什么想法我可能做错或遗漏了什么吗?提前致谢!
我已经在 Azure 中拥有逻辑应用程序,可以毫无问题地访问 API 应用程序,但我注意到逻辑应用程序 json 中的身份验证凭据包含一个“audience”参数。上面的代码没有使用“观众”,所以这可能是谜题中缺失的部分,如果是,我该如何添加它?
最佳答案
您收到 401 响应的原因是您只授予了应用程序委派权限,但您正在使用需要应用程序权限的客户端凭据流程。
您可以更改代码以使用授权代码流程,也可以将应用程序权限从您的网络应用授予您的网络 API。
要使用授权代码流程,您需要更改代码以使用 AcquireTokenByAuthorizationCodeAsync。
您可以在此处找到有关这两种不同方法的更多信息: https://azure.microsoft.com/en-us/documentation/articles/active-directory-authentication-scenarios/#web-application-to-web-api
关于azure - 使用 Azure AD 不记名 token 对 API 应用程序验证 Web 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38347451/