web-dev-qa-db-ja.com

ASP.NETコアWebAPI認証属性が404エラーを返し、リダイレクトを強制する

私は次のプロジェクトを含むasp.netコア2.0ソリューションを持っています:

  • データ:EFコードのクラスライブラリ
  • OAuth:IdentityServer4コードのWebアプリケーションプロジェクトとして
  • Api:空のWebプロジェクトとして作成されたAPIの場合

これで、OAuthプロジェクトはaspnetidentityで構成され、正常に機能します。認証後にトークンを取得できます。これは、そのスタートアップコードです。

public void ConfigureServices(IServiceCollection services)
{
    // connect with normal database
    services.AddDbContext<MCareContext>(options => options.UseSqlServer(Configuration
              .GetConnectionString("MCareConnection")));

    services.AddIdentity<User, IdentityRole>()
        .AddEntityFrameworkStores<MCareContext>()
        .AddDefaultTokenProviders();


    services.AddMvc();

    // IS configurations database
    var dbConnectionString = Configuration.GetConnectionString("MCareConnection.OAuth");
    var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;

    services.AddIdentityServer()
         .AddConfigurationStore(options =>
         {
            options.ConfigureDbContext = builder =>
                builder.UseSqlServer(dbConnectionString,
                    sql => sql.MigrationsAssembly(migrationsAssembly));
         })

        .AddOperationalStore(options =>
        {
            options.ConfigureDbContext = builder =>
                builder.UseSqlServer(dbConnectionString,
                    sql => sql.MigrationsAssembly(migrationsAssembly));
        })

        .AddAspNetIdentity<User>()
        .AddDeveloperSigningCredential(); 
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    DatabaseInitializer.InitializeDatabase(app);

    loggerFactory.AddConsole();

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseIdentityServer();

    app.UseStaticFiles();
    app.UseMvcWithDefaultRoute();
}

APIプロジェクトの問題ですが、承認されたコントローラー/アクションを開くと、404エラーが発生し、これがスタートアップコードになります。

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<MCareContext>(options => options.UseSqlServer(Configuration
      .GetConnectionString("MCareConnection")));

    services.AddIdentity<User, IdentityRole>()
        .AddEntityFrameworkStores<MCareContext>()
        .AddDefaultTokenProviders();

    services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
     .AddIdentityServerAuthentication(options =>
     {
         options.Authority = "http://localhost:60415";
         options.ApiName = "mCareApi";
         options.RequireHttpsMetadata = false;
     });

    services.AddMvc();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole();

    app.UseAuthentication();

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseDefaultFiles();
    app.UseStaticFiles();            

    app.UseMvcWithDefaultRoute();
}

上記のコードでこの部分を閉じると:

//services.AddIdentity<User, IdentityRole>()
    //.AddEntityFrameworkStores<MCareContext>()
    //.AddDefaultTokenProviders();

次に、Authorize属性は期待どおりに機能しますが、別の新しい問題として、コンストラクターでUserManageruserManagerを期待するAccountControllerなどのコントローラーを開くと、500の内部サーバーエラーが表示されます。

InvalidOperationException:MCare.Api.Controllers.AccountsControllerをアクティブ化しようとしているときに、タイプMicrosoft.AspNetCore.Identity.UserManager`1 [MCare.Data.Entities.User]のサービスを解決できません。

私が見たすべてのプロジェクトは1つのプロジェクトで両方を混合しているため、IdentityServer4プロジェクトをAPIプロジェクトと混合せずに、なぜこれが発生しているのか、この問題を解決する方法を知りたいです。

7
Wajdy Essam

DefaultChallengeSchemeが、404を引き起こす可能性のあるauthorize属性に遭遇したときに、ログインページなどの存在しないページにリダイレクトしている可能性はありますか?

未承認を返すJwtスキーマにデフォルトのチャレンジを設定してみてください。

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddIdentityServerAuthentication(options =>
{
    options.Authority = "http://localhost:60415";
    options.ApiName = "mCareApi";
    options.RequireHttpsMetadata = false;
});

または、イベントのハンドラーを提供して、以下の記事で説明した方法を試すこともできます。

services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(options =>
{
    options.JwtBearerEvents = new JwtBearerEvents
    {
        OnChallenge = context =>
        {
            context.Response.StatusCode = 401;
            return Task.CompletedTask;
        }
    };
    options.Authority = "http://localhost:60415";
    options.ApiName = "mCareApi";
    options.RequireHttpsMetadata = false;
});
17
Geekn

addControllers()行の後にAddAuthentication行を追加する必要があるかもしれません

0
dkokkinos