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

Bearer token not working when calling web api in Azure

我在从 Azure 中的 Web 应用程序获取 API 应用程序调用时遇到问题。这是事物的结构 -

  1. Asp.Net 受 Azure AD 身份验证保护的核心 1.1 Web 应用程序 - 运行 在本地使用 Kestrel
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. Controller class 我调用 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;
    

对 API 的调用被重定向到 login.microsftonline.com,这意味着我的令牌不被理解。

  1. Web API 使用代码中的 OpenIdConnect 包通过 Azure 身份验证进行保护,就像上面的 Web 应用程序代码一样

我看了几个相关的帖子,但没有任何效果。

更新 1 - 更新 Web API 以使用 JWTBearer 身份验证 现在,我在 Web App 中获取的不记名令牌能够成功地向 Web API 验证我的身份。

我的网站 API 预计会调用另一个自定义 API,该自定义 API 也受 Azure AD 身份验证保护。我正在寻找相同的令牌,但为了启动我在为其他自定义 API 使用获取令牌时遇到问题。它在没有任何消息的情况下抛出 Internal Server 500。有什么想法吗?

更新 2 - 详细错误 在尝试为第三个 api 获取令牌时,出现以下异常 - "AADSTS50105: Application 'source client id guid' is not assigned to a role for the application 'target client id guid'."

问题已解决,这是我必须做的。

  1. API 应用程序身份验证更改

    • 将身份验证方案更改为通过 JWTBearer
    • 这让我可以接受来自 Web 应用程序的不记名令牌,现在 Web 应用程序可以根据需要进行应用程序身份验证Api
  2. API 应用程序代码更改

    • 由于 API 应用程序正在调用另一个下游 API 应用程序,我不得不使用 AcquireTokenAsync 传递以下详细信息 - ClientId、ClienCredentials 和先前从 Web 应用程序收到的访问令牌。此令牌用于构造 UserAssertion

通过上述更改,从 Web 应用程序调用 --> API 应用程序 --> 下游 API 应用程序工作正常。