在Azure中调用web api时,不记名令牌不起作用

时间:2017-08-23 16:00:44

标签: azure asp.net-web-api azure-api-apps

我在使用Azure中的Web App从API应用程序调用工作时遇到问题。这是事情的结构 -

  1. 受Azure AD身份验证保护的Asp.Net Core 1.1 Web App - 使用Kestrel在本地运行
  2. Web应用程序的StartUp.cs具有以下用于将令牌发送到Web API的代码

            app.UseCookieAuthentication(); 
            app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
            {
                ClientId = ClientId, //Client Id of my current web app
                ClientSecret = ClientSecret, //ClientSecret of my current web app
                Authority = "https://login.microsoftonline.com/tenantguid",                CallbackPath = Configuration[Constants.ApplicationProxyCallbackPath],
                ResponseType = OpenIdConnectResponseType.CodeIdToken,
                Events = new OpenIdConnectEvents
                {
                    OnAuthorizationCodeReceived = OnAuthorizationCodeReceived,
                    OnRemoteFailure = OnAuthenticationFailed
                }
            });
    

    对于OnAuthorizationCodeReceived方法,这是我的代码

    private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context)
        {
            string userObjectId = (context.Ticket.Principal.FindFirst(Constants.ClaimsSchemaUri))?.Value;
            ClientCredential clientCred = new ClientCredential(ClientId, ClientSecret);
            AuthenticationContext authContext = new AuthenticationContext(Authority, new NaiveSessionCache(userObjectId, context.HttpContext.Session));
            AuthenticationResult authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
                context.ProtocolMessage.Code,
                new Uri(context.Properties.Items[OpenIdConnectDefaults.RedirectUriForCodePropertiesKey]),
                clientCred,
                WebAPIClientId);        
         }
    

    使用上面的代码我可以成功获得持票人令牌。

    1. 我调用WebApi的控制器类

          Task<string> results = null;
          string resultSet = String.Empty;
          AuthenticationResult authResult = null;
      
          string userObjectID = (currentUser.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier"))?.Value;
          AuthenticationContext authContext = new AuthenticationContext(Startup.Authority, new NaiveSessionCache(userObjectID, current.Session));
          ClientCredential credential = new ClientCredential(Startup.ClientId, Startup.ClientSecret);
          authResult = await authContext.AcquireTokenSilentAsync(Startup.SearchAPIClientId, credential, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));
      
          //var callerIdentity = currentUser.Identity as WindowsIdentity;
          HttpClientHandler handler = null;
      
          //Setup async action
          Action action = () => {
      
              handler = new HttpClientHandler() { AllowAutoRedirect = true };
      
              //Setup for windows authentication
              var client = new HttpClient(handler);
      
              //Add common http headers
              client.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
              client.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate");
              client.DefaultRequestHeaders.Add("Accept-Language", "en-US,en;q=0.8");
              client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36");
              client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
      
              results = client.GetStringAsync("https://myapi.azurewebsites.net/api/search/");
          };
      
          action.Invoke();
      
          resultSet = await results as string;
      
    2. 对API的调用被重定向到login.microsftonline.com,这意味着我的令牌不被理解。

      1. 使用代码中的OpenIdConnect程序包,使用Azure身份验证保护Web API,就像上面的Web应用程序代码一样
      2. 我看过几个相关的帖子,但没有什么工作正常。

        更新1 - 更新了Web API以使用JWTBearer身份验证 现在,我在Web App中获取的持有者令牌能够成功验证我的Web API。

        我的Web API应该调用另一个也受Azure AD身份验证保护的自定义API。我希望获得相同的令牌,但为了启动我在使用获取令牌进行额外的自定义API时遇到问题。它在没有消息的情况下抛出内部服务器500。有什么想法吗?

        更新2 - 详细错误 在尝试获取第三个api的令牌时,我得到以下异常 - &#34; AADSTS50105:应用程序&#39;源客户端ID guid&#39;未分配给应用程序&#39;目标客户端ID guid&#39;的角色。&#34;

1 个答案:

答案 0 :(得分:0)

这个问题已得到解决,这就是我必须要做的事情。

  1. API App身份验证更改

    • 将身份验证方案更改为通过JWTBearer
    • 这允许我从Web App接受持有人令牌,现在Web App到Api App身份验证可以根据需要使用
  2. API应用代码更改

    • 当API应用程序调用另一个下游API应用程序时,我不得不使用AcquireTokenAsync传递以下详细信息 - 早先从Web App收到的ClientId,ClienCredentials和Access Token。此标记用于构造UserAssertion
  3. 通过上述更改来自Web App - &gt; API应用程序 - &gt;下游API应用程序工作正常。