Azure AD授权AuthenticationFailed错误:IDX10501:签名验证失败。无法匹配'孩子'

时间:2018-02-13 13:17:37

标签: c# azure .net-core azure-active-directory azure-authentication

我有2个项目,一个用于API,第二个用于通过使用第一个项目的API来查看和获取数据。对于这两者我已经实现了Azure AD身份验证,但我的问题是当尝试使用Bearer令牌从第二个项目后端(C#)调用API时,但作为响应我遇到了错误。

  

注意:我在项目的每个班级和方法中都使用了[授权]过滤器。

错误

  

AuthenticationFailed:IDX10501:签名验证失败。无法匹配'kid':'SSQdhI1cKvhQEDSJxE2gGYs40Q0',   token:'{“alg”:“RS256”,“typ”:“JWT”,“kid”:“SSQdhI1cKvhQEDSJxE2gGYs40Q0”}。{“aud”:“1e615ddb-ad4d-4e65-98de-c6f5db1ae08a”,“iss”: “https://login.microsoftonline.com/5c58f0d9-2f98-4eb0-91f2-ec6afd4242f8/v2.0”, “IAT”:1518520450, “NBF”:1518520450, “EXP”:1518524350 “AIO”: “Y2NgYHiknfZAIvPElucJpgeZzRa5AAA =”, “AZP”: “1e615ddb-ad4d-4e65-98de-c6f5db1ae08a” “azpacr”: “1”, “e_exp”:262800, “OID”: “159f0ec6-c5b9-4bfc-88d0-77924bd40b3f”, “子”: “159f0ec6-c5b9-4bfc-88d0-77924bd40b3f”, “TID” : “5c58f0d9-2f98-4eb0-91f2-ec6afd4242f8”, “UTI”: “t8CU6YtsHE-5M9TbQm4aAA”, “版本”: “2.0”}”

启动类ConfigureServices方法

public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

        services.AddAuthentication(sharedOptions =>
        {
            sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
        })
        .AddAzureAdB2C(options =>  Configuration.Bind("Authentication:AzureAdB2C", options))           
        .AddCookie();

        // Add framework services.
        services.AddMvc();

        // Adds a default in-memory implementation of IDistributedCache.
        services.AddDistributedMemoryCache();
        services.AddSession(options =>
        {
            options.IdleTimeout = TimeSpan.FromHours(1);
            options.CookieHttpOnly = true;
        });
    }

启动类配置方法

 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseBrowserLink();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseStaticFiles();

        app.UseSession();

        app.UseAuthentication();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }

获取承载令牌的类

public class ServicePrincipal
{        
    static string authority = "https://login.microsoftonline.com/{TenantID}/{Policy}/v2.0/";  
    static string clientId = "XXX"; 
    static string clientSecret = "XXX"; 
    static string resource = "XXX"; 

    static public async Task<Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationResult> GetS2SAccessTokenForProdMSAAsync()
    {
        return await GetS2SAccessToken(authority, resource, clientId, clientSecret);
    }

    static async Task<Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationResult> GetS2SAccessToken(string authority, string resource, string clientId, string clientSecret)
    {
        var clientCredential = new Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential(clientId, clientSecret);
        AuthenticationContext context = new AuthenticationContext(authority, false);
        Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationResult authenticationResult = await context.AcquireTokenAsync(resource,clientCredential);  
        return authenticationResult;
    }
}

我试图调用第一个项目API的控制器方法

public async Task<IActionResult> GetCustomerGroupAsync()
    {
        try
        {

            var token = await ServicePrincipal.GetS2SAccessTokenForProdMSAAsync();                
            _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken);
            HttpResponseMessage response = await _client.GetAsync("http://localhost:49942/api/customermodule/v0.3/customergroup");
            response.EnsureSuccessStatusCode();
            string receiveStream = await response.Content.ReadAsStringAsync();
            return null;
        }
        catch (Exception e)
        {
            return Json(new { Error = e.Message });
        }
    }

如果我遗漏了什么或者我做错了,请告诉我?,谢谢。

2 个答案:

答案 0 :(得分:2)

根据您的GetCustomerGroupAsync操作,您正在使用网站后端中的客户端凭据流来访问Azure AD B2C的安全资源(Web API)。正如Azure Active Directory B2C: Types of applications在“当前限制”部分中提到的如下:

  

守护程序/服务器端应用

     

包含长时间运行流程或在没有用户在场的情况下运行的应用程序还需要一种方法来访问安全资源,例如Web API。这些应用程序可以使用应用程序的标识(而不是用户的委派身份)以及使用OAuth 2.0客户端凭据流来验证和获取令牌。

     

Azure AD B2C目前不支持此流。只有在发生交互式用户流后,这些应用才能获得令牌。

此外,您可以按照下面的git示例来实现您的要求:

An ASP.NET Core 2.0 web API with Azure AD B2C

An ASP.NET Core web app with Azure AD B2C

答案 1 :(得分:0)

因为您需要检索访问令牌,所以它必须是对OAuth端点的调用。尝试使用以下内容获取Azure AD访问令牌

https://login.microsoftonline.com/{TenantID}/oauth2/token

更重要的是,只需要确保授权标头以有效格式构建:Bearer