如何使用具有 Azure Active Directory 授权的 Azure REST API 应用

How to consume Azure REST API App with Azure Active Directory authorization On

我已将 API App 部署到 Azure,但如果身份验证(使用 AAD)设置为开,我在创建 API 客户端时遇到问题。

当我尝试生成服务客户端时(当身份验证关闭时),然后生成客户端代码(它是通过 Autorest 完成的)并且代码正在运行,但是当我打开身份验证时(以及请求未执行时要采取的操作) authenticated 设置为 Login with Azure Active Directory),然后

1) 服务调用返回 401 Unauthorized(没有重定向到 AAD 登录页面)

2) 然后我尝试再次生成服务客户端(从项目的上下文菜单 -> 添加 -> REST API 客户端 -> 然后在对话框中我选择 "Select Azure Asset" 并按确定并收到消息 "Failed to download metadata file for Microsoft Azure API App: ...app name..."(和 "no additional information available")

我正在根据本 Azure 手册(使用快速设置)实施 AAD:

https://azure.microsoft.com/en-us/documentation/articles/app-service-mobile-how-to-configure-active-directory-authentication/

我也是按照这个视频工作的,这个视频中显示的一切都工作正常,除了 AAD 没有演示......对我来说它不工作......

https://azure.microsoft.com/en-us/documentation/videos/connect-2015-what-s-new-in-app-service-api-apps/

有什么建议吗?

编辑

1) 如果我在 Web 浏览器中输入请求 url(即 REST API 客户端使用的)- 那么它 returns 有效结果 2) 我发现我正在使用没有凭据的 REST API(我认为在这种情况下应该显示 Azure AD 登录屏幕...但事实并非如此)

编辑 2

我取得了一些进展 - 进入了 AAD 登录屏幕,但在输入凭据后我得到了 bearer token,但是当我尝试查询服务时,我收到一条错误消息:

AADSTS65005: The client application has requested access to resource 'https....azurewebsites.net'. This request has failed because the client has not specified this resource in its requiredResourceAccess list. Trace ID: 4176e... Correlation ID: 1d612d... Timestamp: 2016-11-13 18:28:34Z

这些是我为达到这一步所做的步骤:

0) 添加了 Microsoft.IdentityModel.Clients.ActiveDirectory nuget 包到客户端项目

1) 在 Azure Active Directory 中注册了我的客户端应用程序

2) 从客户端应用程序调用 REST API 时,我添加了 ServiceClientCredentials

3) 创建 ServiceClientCredentials 时我提供了 4 个元素 -authority = this is from AAD App registrations -> Endpoints => Federation Metadata Document vērtība(没有起始部分http://login.windows.net/

-resource => 这是 REST API uri(=> 作为所请求令牌接收者的目标资源的标识符)

-clientId => 这是我在 AAD 中注册客户端应用程序后获得的应用程序 ID -redirect Uri => 因为我的客户端应用程序是本机应用程序,所以这只是任何有效的 url

如何在我的客户端应用程序中指定此资源?

client has not specified this resource in its requiredResourceAccess list

我设法找到了一个关于如何为 Azure REST API 应用程序启用 AAD 授权的解决方案。万一有人遇到同样的挑战,我希望这会有所帮助。

这些是我做的步骤:

1) 在应用服务中 -> Authentication/authorization

  • 应用服务身份验证 => 开启
  • 请求未通过身份验证时采取的操作 => 使用 AAD 登录
  • 使用 Express 设置配置 AAD(您必须在此处创建 Azure AD App for you API App - 即 "App registration" for your service)

2) 在 Azure Active Directory -> 应用程序注册中

  • 为您的客户端应用添加注册
  • 编辑客户端应用程序的清单 - 在 requiredResourceAccess 部分中,您必须添加有关 REST API 应用程序的信息:
    • resourceAppId -> 在此处插入 REST API 应用程序 ID
    • resourceAccess {id} -> REST API 的 OauthPermission id 值(您可以在 REST API 的清单中获取它!)

3) 在您的客户端应用程序中

  • 使用 Autorest(来自解决方案资源管理器:Add\REST API client)生成您的 REST 客户端或手动创建它
  • 添加 Microsoft.IdentityModel.Clients.ActiveDirectory nuget 包
  • 获取并使用令牌访问您的 API,代码类似于:

        //request
        (..)
        var tokenCreds = getToken();
        ServiceClientCredentials credentials = tokenCreds;
    
        using (var client = new YourAPI(credentials)) {
        ...
        }
        (..)
    
        //getting token
    
    private static TokenCredentials getToken()
    {
        //get this from Federation Metadata Document in 
        //Azure Active Directory App registrations -> Endpoints
        var authority = "f1...";
    
        //Identifier of the target resource that is the recipient of the requested token
        var resource = "https://yourapi.azurewebsites.net";
    
        //client application id (see Azure Active Directory App registration
        //for your client app
        var clientId = "a71...";
    
        //return url - not relevant for Native apps (just has to be valid url)
        var redirectUri = "https://just-some-valid-url.net";
    
        AuthenticationContext authContext =
        new AuthenticationContext(string.Format
        ("https://login.windows.net/{0}",
    authority));
    
        AuthenticationResult tokenAuthResult =
        authContext.AcquireTokenAsync(resource,
        clientId,
        new Uri(redirectUri),
        new PlatformParameters(PromptBehavior.Auto)).Result;
    
        return new TokenCredentials(tokenAuthResult.AccessToken);
    }