2

私は 2 つのプロジェクトを持っています。1 つは API 用で、2 番目は 1 番目のプロジェクトの API を使用してデータを表示および取得するためのものです。どちらも Azure AD 認証を実装しましたが、Bearer トークンを使用して 2 番目のプロジェクト バックエンド (C#) から API を呼び出そうとすると問題が発生しますが、応答するとエラーが発生します。

注:私は、すべてのクラスで [Authorize] Filter を使用し、両方のプロジェクトでメソッドを使用しています。

エラー

AuthenticationFailed: IDX10501: 署名の検証に失敗しました。「子供」と一致できません:「SSQdhI1cKvhQEDSJxE2gGYs40Q0」、トークン:「{"alg":"RS256","typ":"JWT","子供":"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","サブ":"

Start クラスの 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;
        });
    }

Start クラスの Configure メソッド

 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?}");
        });
    }

Bearer Tokenを取得するためのクラス

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 });
        }
    }

何か不足している場合、または間違っている場合はお知らせください。ありがとうございます。

4

2 に答える 2

2

アクションに基づいてGetCustomerGroupAsync、Web サイト バックエンドでクライアント資格情報フローを使用して、Azure AD B2C でセキュリティで保護されたリソース (Web API) にアクセスしています。Azure Active Directory B2Cとして: アプリケーションの種類では、現在の制限セクションに次のように記載されています。

デーモン/サーバー側アプリ

長時間実行されるプロセスを含むアプリや、ユーザーの存在なしで動作するアプリには、Web API などのセキュリティで保護されたリソースにアクセスする方法も必要です。これらのアプリは、(ユーザーの委任された ID ではなく) アプリの ID を使用し、OAuth 2.0 クライアント資格情報フローを使用して、認証し、トークンを取得できます。

このフローは、現在 Azure AD B2C ではサポートされていません。これらのアプリは、インタラクティブなユーザー フローが発生した後にのみトークンを取得できます。

さらに、以下の git サンプルに従って、要件を実装することもできます。

Azure AD B2C を使用した ASP.NET Core 2.0 Web API

Azure AD B2C を使用した ASP.NET Core Web アプリ

于 2018-02-14T06:07:08.420 に答える
0

アクセス トークンを取得する必要があるため、OAuth エンドポイントへの呼び出しである必要があります。以下を試して、Azure AD アクセス トークンを取得してください

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

さらに、承認ヘッダーが有効な形式で構成されていることを確認する必要があります: Bearer

于 2018-02-13T16:39:12.657 に答える