【问题标题】:Bearer token not working when calling web api in Azure在 Azure 中调用 Web api 时不记名令牌不起作用
【发布时间】:2018-02-01 07:50:45
【问题描述】:

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

  1. 受 Azure AD 身份验证保护的 Asp.Net Core 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. 我调用 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 对我进行身份验证。

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

更新 2 - 详细错误 在尝试获取第三个 api 的令牌时,我遇到了以下异常- “AADSTS50105:应用程序‘源客户端 id guid’未分配给应用程序‘目标客户端 id guid’的角色。”

【问题讨论】:

  • 在提供Authorization Header 和不记名令牌后,您是否能够从 Postman 访问该 API?
  • 不,我做不到。使用上面代码中生成的令牌,我无法使用 Postman 拨打电话。
  • 您是否收到 401 或任何其他错误消息?如果令牌有效,那么您应该可以从 Postman 拨打电话。
  • 我看到 login.microsoftonline.com 发生 302
  • 这可能会有所帮助。 leastprivilege.com/2011/05/31/…

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


【解决方案1】:

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

  1. API 应用身份验证更改

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

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

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

【讨论】:

    猜你喜欢
    • 2020-05-14
    • 2015-08-01
    • 2019-08-08
    • 2021-06-03
    • 2019-07-26
    • 1970-01-01
    • 2019-04-07
    • 2018-06-05
    • 1970-01-01
    相关资源
    最近更新 更多