2017-02-12 8 views
1

OpenIdictを使用してOpenIdConnect/Oauth2サーバーを実装して、.NETコアAPIアプリケーションを保護したいとします。私が見たほとんどの例は、これらを別々のプロジェクトとして実装しています。OpenIddict - 同じプロジェクトでサーバーとWeb APIリソースをホストしています

クライアントアプリケーションはSPAであり、私たちは暗黙のフローを使用しています。

私はここにOpenIddictサンプルに示すコードで私のソリューションをベースとしている:私はそれに取り組んでいたプロジェクトについては https://github.com/openiddict/openiddict-samples

は、理想的には、同じポートを使用するように認証サーバとAPIを持っており、中になります同じプロジェクト(お客様の要件の1つは、APIリソースを所有しているため別のサーバーを設定したくないということです)。

私はOpenIddictを設定し、APIプロジェクトと組み合わせました。 APIエンドポイントは[Authorize]属性で保護され、保護されたAPIエンドポイントへのアクセスを防止します。ただし、APIリソースが保護されている場合は、401 Unauthorized HTTPステータスコードを返す代わりに、Authサーバー自体のHTML Loginページが返されます。

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
    { 
     loggerFactory.AddConsole(Configuration.GetSection("Logging")); 
     loggerFactory.AddDebug(); 

     app.UseApplicationInsightsRequestTelemetry(); 

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

     app.UseApplicationInsightsExceptionTelemetry(); 

     app.UseStaticFiles(); 

     app.UseIdentity(); 

     app.UseCors("AllowAll"); 
     //app.UseCors(builder => 
     //{ 
     // builder.AllowAnyOrigin();//)WithOrigins("http://localhost:9000"); 
     // builder.WithMethods("GET","POST", "PUT", "DELETE", "OPTIONS"); 
     // builder.WithHeaders("Authorization"); 
     //}); 

     app.UseWhen(context => !context.Request.Path.StartsWithSegments("/api"), branch => 
     { 
      branch.UseIdentity(); 
     }); 

     app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), branch => 
     { 
      branch.UseOAuthValidation(); 

     }); 

     app.UseOpenIddict(); 


     #region Adding resource config here (api) 
     // Add external authentication middleware below. To configure them please see http://go.microsoft.com/fwlink/?LinkID=532715 

     app.UseOAuthIntrospection(options => 
     { 
      options.AutomaticAuthenticate = true; 
      options.AutomaticChallenge = true; 
      options.Authority = "http://localhost:5000"; 
      options.Audiences.Add("resource-server-1"); 
      options.ClientId = "resource-server-1"; 
      options.ClientSecret = "846B62D0-DEF9-4215-A99D-86E6B8DAB342"; 
     }); 

     //app.UseCors(builder => { 
     // builder.WithOrigins("http://localhost:9000"); 
     // builder.WithMethods("GET"); 
     // builder.WithHeaders("Authorization"); 
     //}); 
     #endregion 


     app.UseMvcWithDefaultRoute(); 

     // Seed the database with the sample applications. 
     // Note: in a real world application, this step should be part of a setup script. 
     InitializeAsync(app.ApplicationServices, CancellationToken.None).GetAwaiter().GetResult(); 

    } 

private async Task InitializeAsync(IServiceProvider services, CancellationToken cancellationToken) 
    { 
     // Create a new service scope to ensure the database context is correctly disposed when this methods returns. 
     using (var scope = services.GetRequiredService<IServiceScopeFactory>().CreateScope()) 
     { 
      var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>(); 
      //await context.Database.EnsureCreatedAsync(); 

      var manager = scope.ServiceProvider.GetRequiredService<OpenIddictApplicationManager<OpenIddictApplication>>(); 

      if (await manager.FindByClientIdAsync("MySPA", cancellationToken) == null) 
      { 
       var application = new OpenIddictApplication 
       { 
        ClientId = "MySPA", 
        DisplayName = "MySPA", 
        LogoutRedirectUri = "http://localhost:9000/signout-oidc", 
        RedirectUri = "http://localhost:9000/signin-oidc" 
       }; 

       await manager.CreateAsync(application, cancellationToken); 
      } 

      if (await manager.FindByClientIdAsync("resource-server-1", cancellationToken) == null) 
      { 
       var application = new OpenIddictApplication 
       { 
        ClientId = "resource-server-1" 
       }; 

       await manager.CreateAsync(application, "846B62D0-DEF9-4215-A99D-86E6B8DAB342", cancellationToken); 
      } 

     } 
    } 

同じプロジェクトに並んでこれらの側面の両方を実装する方法をわからない:

は、ここに私のStartup.csファイル内の関連するセットアップコードです。 APIを除き、「働く」ことのすべてを述べたように、所望のHTTPステータス

答えて

1

app.UseIdentity();をHTMLログインページを返すとされていないことはあなたのパイプラインの2倍存在している、app.UseWhen()分岐ビルダーでbranch.UseIdentity()を使用しての全体の目的に反している(すなわち作りますIdentityによって登録されたクッキーミドルウェアがAPIエンドポイントで呼び出されていないことを確認してください)。

最初のオカレンスを削除しても問題はありません。

+1

ありがとうございました!それは問題でした - 今の魅力のように動作します:) – user1750537

0

AutomaticChallengeをtrueに設定します。 documentation

によると、このフラグは、認証が失敗したときミドルウェアがLOGINPATHまたはAccessDeniedPathにブラウザをリダイレクトする必要があることを示します。

これをfalseに設定すると、ログインにリダイレクトされません。

関連する問題