Pertanyaan Saluran otentikasi OWIN, dan bagaimana cara menggunakan Katana middleware dengan benar?


Saya baru saja mulai melihat kerangka kerja Identitas ASP.Net baru dan middleware Katana, ada sejumlah kode dan dokumentasi yang mengejutkan di luar sana, tetapi saya melihat apa yang tampaknya menjadi banyak informasi yang saling bertentangan, yang saya kira adalah hasil dari meningkatnya frekuensi pembaruan kode.

Saya mencari untuk menggunakan Autentikasi WsFederasi terhadap layanan internal ADFS 2, tetapi cara kerja pipa otentikasi OWIN membuat saya sedikit bingung dan saya berharap seseorang dapat menawarkan beberapa definitif informasi.

Secara khusus, saya tertarik pada urutan di mana middleware harus terhubung dan modul yang diperlukan dalam berbagai skenario, saya ingin menyingkirkan apa pun yang tidak perlu ada di sana dan pada saat yang sama memastikan bahwa proses seaman mungkin.

Misalnya, akan muncul itu UseWsFederationAuthentication harus digunakan bersama UseCookieAuthentication, tapi saya tidak yakin apa yang benar AuthenticationType akan menjadi (ini posting menunjukkan bahwa itu hanya string identifier, tetapi apakah itu signifikan?) atau bahkan jika kita masih perlu menggunakannya SetDefaultSignInAsAuthenticationType.

Saya juga memperhatikan ini utas pada papan diskusi Proyek Katana, di mana Tratcher menyebutkan kesalahan umum, tetapi tidak terlalu spesifik mengenai bagian mana dari kode yang salah.

Secara pribadi, saya sekarang menggunakan yang berikut ini (dengan penangan SAML Token khusus untuk membaca string token menjadi dokumen XML yang valid), ini bekerja untuk saya, tetapi apakah itu optimal?

var appURI = ConfigurationManager.AppSettings["app:URI"];
var fedPassiveTokenEndpoint = ConfigurationManager.AppSettings["wsFederation:PassiveTokenEndpoint"];
var fedIssuerURI = ConfigurationManager.AppSettings["wsFederation:IssuerURI"];
var fedCertificateThumbprint = ConfigurationManager.AppSettings["wsFederation:CertificateThumbprint"];

var audienceRestriction = new AudienceRestriction(AudienceUriMode.Always);

audienceRestriction.AllowedAudienceUris.Add(new Uri(appURI));

var issuerRegistry = new ConfigurationBasedIssuerNameRegistry();

issuerRegistry.AddTrustedIssuer(fedCertificateThumbprint, fedIssuerURI);

app.UseCookieAuthentication(
    new CookieAuthenticationOptions
    {
        AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType // "Federation"
    }
);

app.UseWsFederationAuthentication(
    new WsFederationAuthenticationOptions
    {
        Wtrealm = appURI,
        SignOutWreply = appURI,
        Configuration = new WsFederationConfiguration
        {
            TokenEndpoint = fedPassiveTokenEndpoint
        },
        TokenValidationParameters = new TokenValidationParameters
        {
            AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType
        },
        SecurityTokenHandlers = new SecurityTokenHandlerCollection
        {                        
            new SamlSecurityTokenHandlerEx
            {
                CertificateValidator = X509CertificateValidator.None,
                Configuration = new SecurityTokenHandlerConfiguration
                {
                    AudienceRestriction = audienceRestriction,
                    IssuerNameRegistry = issuerRegistry
                }
            }
        }
    }
);

Terima kasih banyak atas apa pun yang dapat Anda tawarkan untuk membantu menjernihkan kebingungan ini bagi saya.


32
2017-09-04 10:59


asal


Jawaban:


Seperti kata @Tratcher, the AuthenticationType parameter digunakan oleh Microsoft.Owin.Security sebagai kunci untuk melakukan pencarian contoh otentikasi middleware.

Kode di bawah ini akan menggunakan metode pembantu sederhana berikut untuk mewajibkannya semua permintaan dikonfirmasi. Dalam prakteknya Anda lebih cenderung menggunakan [Authorize] atribut pada pengendali sensitif, tetapi saya menginginkan contoh yang tidak bergantung pada kerangka kerja apa pun:

private static void AuthenticateAllRequests(IAppBuilder app, params string[] authenticationTypes)
{
    app.Use((context, continuation) =>
    {
        if (context.Authentication.User != null &&
            context.Authentication.User.Identity != null &&
            context.Authentication.User.Identity.IsAuthenticated)
        {
            return continuation();
        }
        else
        {
            context.Authentication.Challenge(authenticationTypes);
            return Task.Delay(0);
        }
    });
}

Itu context.Authentication.Challenge(authenticationTypes) panggilan akan mengeluarkan tantangan otentikasi dari masing-masing jenis otentikasi yang disediakan. Kami hanya akan menyediakan satu, jenis otentikasi WS-Federasi kami.

Kode yang benar

Pertama, berikut ini contoh konfigurasi "Owin Startup" yang optimal untuk situs yang hanya menggunakan WS-Federation, seperti Anda:

public void Configuration(IAppBuilder app)
{
    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

    app.UseCookieAuthentication(new CookieAuthenticationOptions());

    app.UseWsFederationAuthentication(new WsFederationAuthenticationOptions
    {
        AuthenticationType = "WS-Fed Auth (Primary)",
        Wtrealm = ConfigurationManager.AppSettings["app:URI"],
        MetadataAddress = ConfigurationManager.AppSettings["wsFederation:MetadataEndpoint"]
    });

    AuthenticateAllRequests(app, "WS-Fed Auth (Primary)");

    app.UseWelcomePage();
}

Perhatikan penggunaan "WS-Fed Auth (Primary)"  AuthenticationType untuk secara unik mengidentifikasi contoh middleware WS-Federation yang telah kami konfigurasikan. Ini berarti Anda dapat, misalnya, menggunakan a "WS-Fed Auth (Secondary)" dengan server WS-Federation terpisah sebagai fallback, jika Anda memiliki persyaratan itu.

Konfigurasi ini akan melakukan hal berikut:

  1. Pertama, beri tahu saluran keamanan Owin bahwa secara default kami ingin mengautentikasi permintaan dengan nilai standar CookeAuthentication AthenticationType. (Itu hanya string konstan pada itu CookieAuthenticationDefaults kelas, dan itu nilai default yang digunakan oleh CookieAuthenticationOptions.AuthenticationTypemilik.)
  2. Selanjutnya, daftarkan contoh middleware autentikasi cookie dengan semua opsi default, jadi ini sesuai dengan AuthenticationType kunci yang kita setel sebagai default pada langkah 1.
  3. Selanjutnya, daftarkan contoh middleware autentikasi WS-Federation dengan opsi yang kami definisikan di file Web.config, dan dengan nilai AuthenticationType khusus sehingga kami dapat merujuknya nanti.
  4. Setelah semua registrasi middleware otentikasi selesai, kami memberi tahu pipa untuk mengotentikasi semua permintaan (melalui metode pembantu kustom kami yang memanggil Microsoft.Owin.Security metode untuk mengeluarkan tantangan terhadap permintaan yang tidak diautentikasi)
  5. Akhirnya, jika pengguna telah diautentikasi, perlihatkan halaman selamat datang!

Salah kode

Jadi ada beberapa cara Anda bisa salah di sini.

Tidak menyediakan tipe otentikasi default

Untuk bereksperimen, saya mencoba melakukan ini, dan Anda akan segera melihat apa masalahnya:

public void Configuration(IAppBuilder app)
{
    var x = app.GetDefaultSignInAsAuthenticationType();

    app.SetDefaultSignInAsAuthenticationType(x);
}

Panggilan pertama itu akan memberi Anda pengecualian yang Anda sebutkan di komentar pertama Anda:

"Nilai default untuk SignInAsAuthenticationType tidak ditemukan di IAppBuilder Properties. Ini dapat terjadi jika middleware otentikasi Anda ditambahkan dalam urutan yang salah, atau jika ada yang hilang."

Benar - karena secara default Microsoft.Owin.Security pipa tidak mengasumsikan apa pun tentang middleware yang akan Anda gunakan (yaitu, Microsoft.Owin.Security.Cookies bahkan tidak diketahui untuk hadir), jadi tidak tahu apa yang seharusnya menjadi default.

Menggunakan jenis otentikasi default yang salah

Ini membuat saya menghabiskan banyak waktu hari ini karena saya tidak benar-benar tahu apa yang saya lakukan:

public void Configuration(IAppBuilder app)
{
    app.SetDefaultSignInAsAuthenticationType("WS-Fed AAD Auth");

    // ... remainder of configuration
}

Jadi, itu akan terus mencoba mengotentikasi penelepon dengan WS-Federation di setiap panggilan. Bukannya itu super mahal, tapi sebenarnya middleware WS-Federation berikan tantangan pada setiap permintaan. Jadi Anda tidak akan pernah bisa masuk, dan Anda melihat banyak sekali URL masuk yang melewati Anda. : P

Kemungkinan

Jadi apa yang hebat tentang memiliki semua fleksibilitas dalam saluran ini adalah Anda dapat melakukan beberapa hal yang sangat keren. Sebagai contoh, saya memiliki domain dengan dua aplikasi web berbeda di dalamnya, berjalan di bawah sub-sub jalur yang berbeda seperti: example.com/foo dan example.com/bar. Anda dapat menggunakan fungsi pemetaan Owin (seperti pada app.Map(...)) untuk membuat saluran otentikasi yang benar-benar berbeda untuk masing-masing aplikasi tersebut. Dalam kasus saya, seseorang menggunakan WS-Federation, sementara yang lain menggunakan sertifikat klien. Mencoba melakukannya dalam monolitik System.Web kerangka kerja akan menjadi mengerikan. : P


46
2017-10-08 20:23