Bagikan melalui


Pengautentikasi Token

Sampel ini menunjukkan cara menerapkan pengautentikasi token kustom. Pengautentikasi token di Windows Communication Foundation (WCF) digunakan untuk memvalidasi token yang digunakan dengan pesan, memverifikasi bahwa token tersebut konsisten sendiri, dan mengautentikasi identitas yang terkait dengan token.

Pengautentikasi token kustom berguna dalam berbagai kasus, seperti:

  • Saat Anda ingin mengambil alih mekanisme autentikasi default yang terkait dengan token.

  • Saat Anda membangun token kustom.

Sampel ini menunjukkan hal berikut:

  • Bagaimana klien dapat mengautentikasi menggunakan pasangan nama pengguna/kata sandi.

  • Bagaimana server dapat memvalidasi kredensial klien menggunakan pengautentikasi token kustom.

  • Bagaimana kode layanan WCF mengikat dengan pengautentikasi token kustom.

  • Bagaimana server dapat diautentikasi menggunakan sertifikat X.509 server.

Sampel ini juga menunjukkan bagaimana identitas pemanggil dapat diakses dari WCF setelah proses autentikasi token kustom.

Layanan ini mengekspos satu titik akhir untuk berkomunikasi dengan layanan, yang ditentukan menggunakan file konfigurasi App.config. Titik akhir terdiri dari alamat, pengikatan, dan kontrak. Pengikatan dikonfigurasi dengan standar wsHttpBinding, dengan mode keamanan diatur ke mode pesan - mode default dari wsHttpBinding. Sampel ini menetapkan standar wsHttpBinding untuk menggunakan autentikasi nama pengguna klien. Layanan ini juga mengonfigurasi sertifikat layanan menggunakan perilaku serviceCredentials. Perilaku ini securityCredentials memungkinkan Anda menentukan sertifikat layanan. Sertifikat layanan digunakan oleh klien untuk mengautentikasi layanan dan memberikan perlindungan pesan. Konfigurasi berikut mereferensikan sertifikat localhost yang diinstal selama penyiapan sampel seperti yang dijelaskan dalam instruksi penyiapan berikut.

<system.serviceModel>
    <services>
      <service
          name="Microsoft.ServiceModel.Samples.CalculatorService"
          behaviorConfiguration="CalculatorServiceBehavior">
        <host>
          <baseAddresses>
            <!-- configure base address provided by host -->
            <add baseAddress ="http://localhost:8000/servicemodelsamples/service" />
          </baseAddresses>
        </host>
        <!-- use base address provided by host -->
        <endpoint address=""
                  binding="wsHttpBinding"
                  bindingConfiguration="Binding1"
                  contract="Microsoft.ServiceModel.Samples.ICalculator" />
      </service>
    </services>

    <bindings>
      <wsHttpBinding>
        <binding name="Binding1">
          <security mode="Message">
            <message clientCredentialType="UserName" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>

    <behaviors>
      <serviceBehaviors>
        <behavior name="CalculatorServiceBehavior">
          <serviceDebug includeExceptionDetailInFaults="False" />
          <!--
          The serviceCredentials behavior allows one to define a service certificate.
          A service certificate is used by a client to authenticate the service and provide message protection.
          This configuration references the "localhost" certificate installed during the setup instructions.
....        -->
          <serviceCredentials>
            <serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>

  </system.serviceModel>

Konfigurasi titik akhir klien terdiri dari nama konfigurasi, alamat absolut untuk titik akhir layanan, pengikatan, dan kontrak. Pengikatan klien dikonfigurasi dengan Mode dan clientCredentialType yang sesuai.

<system.serviceModel>
    <client>
      <endpoint name=""
                address="http://localhost:8000/servicemodelsamples/service"
                binding="wsHttpBinding"
                bindingConfiguration="Binding1"
                contract="Microsoft.ServiceModel.Samples.ICalculator">
      </endpoint>
    </client>

    <bindings>
      <wsHttpBinding>
        <binding name="Binding1">
          <security mode="Message">
            <message clientCredentialType="UserName" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
  </system.serviceModel>

Implementasi klien mengatur nama pengguna dan kata sandi yang akan digunakan.

static void Main()
{
     ...
     client.ClientCredentials.UserNamePassword.UserName = username;
     client.ClientCredentials.UserNamePassword.Password = password;
     ...
}

Pengesahan Token Kustom

Gunakan langkah-langkah berikut untuk membuat pengautentikasi token kustom:

  1. Tulis pengautentikasi token kustom.

    Sampel mengimplementasikan pengautentikasi token kustom yang memvalidasi bahwa nama pengguna memiliki format email yang valid. Ini berasal dari UserNameSecurityTokenAuthenticator. Metode terpenting dalam kelas ini adalah ValidateUserNamePasswordCore(String, String). Dalam metode ini, pengautentikasi memvalidasi format nama pengguna dan juga bahwa nama host bukan dari domain nakal. Jika kedua kondisi terpenuhi, maka akan mengembalikan koleksi instans IAuthorizationPolicy yang hanya-baca yang kemudian digunakan untuk menyediakan klaim yang mewakili informasi yang disimpan di dalam token nama pengguna.

    protected override ReadOnlyCollection<IAuthorizationPolicy> ValidateUserNamePasswordCore(string userName, string password)
    {
        if (!ValidateUserNameFormat(userName))
            throw new SecurityTokenValidationException("Incorrect UserName format");
    
        ClaimSet claimSet = new DefaultClaimSet(ClaimSet.System, new Claim(ClaimTypes.Name, userName, Rights.PossessProperty));
        List<IIdentity> identities = new List<IIdentity>(1);
        identities.Add(new GenericIdentity(userName));
        List<IAuthorizationPolicy> policies = new List<IAuthorizationPolicy>(1);
        policies.Add(new UnconditionalPolicy(ClaimSet.System, claimSet, DateTime.MaxValue.ToUniversalTime(), identities));
        return policies.AsReadOnly();
    }
    
  2. Berikan kebijakan otorisasi yang dikembalikan oleh pengautentikasi token kustom.

    Sampel ini menyediakan implementasinya sendiri yang IAuthorizationPolicy disebut UnconditionalPolicy yang mengembalikan serangkaian klaim dan identitas yang diteruskan ke dalam konstruktornya.

    class UnconditionalPolicy : IAuthorizationPolicy
    {
        String id = Guid.NewGuid().ToString();
        ClaimSet issuer;
        ClaimSet issuance;
        DateTime expirationTime;
        IList<IIdentity> identities;
    
        public UnconditionalPolicy(ClaimSet issuer, ClaimSet issuance, DateTime expirationTime, IList<IIdentity> identities)
        {
            if (issuer == null)
                throw new ArgumentNullException("issuer");
            if (issuance == null)
                throw new ArgumentNullException("issuance");
    
            this.issuer = issuer;
            this.issuance = issuance;
            this.identities = identities;
            this.expirationTime = expirationTime;
        }
    
        public string Id
        {
            get { return this.id; }
        }
    
        public ClaimSet Issuer
        {
            get { return this.issuer; }
        }
    
        public DateTime ExpirationTime
        {
            get { return this.expirationTime; }
        }
    
        public bool Evaluate(EvaluationContext evaluationContext, ref object state)
        {
            evaluationContext.AddToTarget(this, this.issuance);
    
            if (this.identities != null)
            {
                object value;
                IList<IIdentity> contextIdentities;
                if (!evaluationContext.Properties.TryGetValue("Identities", out value))
                {
                    contextIdentities = new List<IIdentity>(this.identities.Count);
                    evaluationContext.Properties.Add("Identities", contextIdentities);
                }
                else
                {
                    contextIdentities = value as IList<IIdentity>;
                }
                foreach (IIdentity identity in this.identities)
                {
                    contextIdentities.Add(identity);
                }
            }
    
            evaluationContext.RecordExpirationTime(this.expirationTime);
            return true;
        }
    }
    
  3. Tulis manajer token keamanan kustom.

    SecurityTokenManager digunakan untuk membuat SecurityTokenAuthenticator untuk objek tertentu SecurityTokenRequirement yang diteruskan ke metode CreateSecurityTokenAuthenticator. Manajer token keamanan juga digunakan untuk membuat penyedia token dan serializer token, tetapi tidak tercakup oleh sampel ini. Dalam sampel ini, manajer token keamanan kustom mewarisi dari kelas ServiceCredentialsSecurityTokenManager dan menggantikan metode CreateSecurityTokenAuthenticator untuk mengembalikan pengautentikasi token nama pengguna kustom ketika persyaratan token yang diteruskan menunjukkan bahwa pengautentikasi nama pengguna diminta.

    public class MySecurityTokenManager : ServiceCredentialsSecurityTokenManager
    {
        MyUserNameCredential myUserNameCredential;
    
        public MySecurityTokenManager(MyUserNameCredential myUserNameCredential)
            : base(myUserNameCredential)
        {
            this.myUserNameCredential = myUserNameCredential;
        }
    
        public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver)
        {
            if (tokenRequirement.TokenType ==  SecurityTokenTypes.UserName)
            {
                outOfBandTokenResolver = null;
                return new MyTokenAuthenticator();
            }
            else
            {
                return base.CreateSecurityTokenAuthenticator(tokenRequirement, out outOfBandTokenResolver);
            }
        }
    }
    
  4. Tulis kredensial layanan kustom.

    Kelas kredensial layanan digunakan untuk mewakili kredensial yang dikonfigurasi untuk layanan dan membuat manajer token keamanan yang digunakan untuk mendapatkan pengautentikasi token, penyedia token, dan serializer token.

    public class MyUserNameCredential : ServiceCredentials
    {
    
        public MyUserNameCredential()
            : base()
        {
        }
    
        protected override ServiceCredentials CloneCore()
        {
            return new MyUserNameCredential();
        }
    
        public override SecurityTokenManager CreateSecurityTokenManager()
        {
            return new MySecurityTokenManager(this);
        }
    
    }
    
  5. Konfigurasikan layanan untuk menggunakan kredensial layanan kustom.

    Agar layanan dapat menggunakan kredensial layanan kustom, kami menghapus kelas kredensial layanan default setelah menangkap sertifikat layanan yang sudah dikonfigurasi sebelumnya dalam kredensial layanan default, dan mengonfigurasi instans kredensial layanan baru untuk menggunakan sertifikat layanan yang telah dikonfigurasi sebelumnya dan menambahkan instans kredensial layanan baru ini ke perilaku layanan.

    ServiceCredentials sc = serviceHost.Credentials;
    X509Certificate2 cert = sc.ServiceCertificate.Certificate;
    MyUserNameCredential serviceCredential = new MyUserNameCredential();
    serviceCredential.ServiceCertificate.Certificate = cert;
    serviceHost.Description.Behaviors.Remove((typeof(ServiceCredentials)));
    serviceHost.Description.Behaviors.Add(serviceCredential);
    

Untuk menampilkan informasi pemanggil, Anda bisa menggunakan PrimaryIdentity seperti yang diperlihatkan dalam kode berikut. Current berisi informasi klaim tentang pemanggil saat ini.

static void DisplayIdentityInformation()
{
    Console.WriteLine("\t\tSecurity context identity  :  {0}",
            ServiceSecurityContext.Current.PrimaryIdentity.Name);
     return;
}

Saat Anda menjalankan sampel, permintaan dan respons operasi ditampilkan di jendela konsol klien. Tekan ENTER di jendela klien untuk mematikan klien.

Menyiapkan File Batch

File batch Setup.bat yang disertakan dengan sampel ini memungkinkan Anda mengonfigurasi server dengan sertifikat yang relevan untuk menjalankan aplikasi yang dihost sendiri yang memerlukan keamanan berbasis sertifikat server. File batch ini harus dimodifikasi agar berfungsi di berbagai komputer atau tanpa host.

Berikut ini memberikan gambaran singkat tentang berbagai bagian file batch sehingga dapat dimodifikasi untuk dijalankan dalam konfigurasi yang sesuai.

  • Membuat sertifikat server.

    Baris berikut dari file batch Setup.bat membuat sertifikat server yang akan digunakan. Variabel %SERVER_NAME% menentukan nama server. Ubah variabel ini untuk menentukan nama server Anda sendiri. Default dalam file batch ini adalah localhost.

    echo ************
    echo Server cert setup starting
    echo %SERVER_NAME%
    echo ************
    echo making server cert
    echo ************
    makecert.exe -sr LocalMachine -ss MY -a sha1 -n CN=%SERVER_NAME% -sky exchange -pe
    
  • Menginstal sertifikat server ke penyimpanan sertifikat tepercaya klien.

    Baris-baris berikut dalam file batch Setup.bat menyalin sertifikat server ke penyimpanan tepercaya klien. Langkah ini diperlukan karena sertifikat yang dihasilkan oleh Makecert.exe tidak dipercaya secara implisit oleh sistem klien. Jika Anda sudah memiliki sertifikat yang berakar pada sertifikat akar tepercaya klien—misalnya, sertifikat yang dikeluarkan Microsoft—langkah mengisi penyimpanan sertifikat klien dengan sertifikat server tidak diperlukan.

    certmgr.exe -add -r LocalMachine -s My -c -n %SERVER_NAME% -r CurrentUser -s TrustedPeople
    

    Nota

    File batch penyiapan dirancang untuk dijalankan dari prompt perintah Windows SDK. Hal ini mengharuskan variabel lingkungan MSSDK menunjuk ke direktori tempat SDK diinstal. Variabel lingkungan ini secara otomatis diatur dalam Prompt Perintah Windows SDK.

Untuk menyiapkan dan membangun sampel

  1. Pastikan Anda telah melakukan Prosedur Penyiapan One-Time untuk Sampel Windows Communication Foundation.

  2. Untuk membangun solusi, ikuti instruksi dalam Membangun Sampel Windows Communication Foundation.

Untuk menjalankan sampel pada komputer yang sama

  1. Jalankan Setup.bat dari folder penginstalan sampel di dalam prompt perintah Visual Studio yang dibuka dengan hak istimewa administrator. Ini menginstal semua sertifikat yang diperlukan untuk menjalankan sampel.

    Nota

    File batch Setup.bat dirancang untuk dijalankan dari Visual Studio Command Prompt. Variabel lingkungan PATH yang diatur dalam Prompt Perintah Visual Studio menunjuk ke direktori yang berisi executable yang diperlukan oleh skrip Setup.bat.

  2. Luncurkan service.exe dari service\bin.

  3. Luncurkan client.exe dari \client\bin. Aktivitas klien ditampilkan pada aplikasi konsol klien.

  4. Jika klien dan layanan tidak dapat berkomunikasi, lihat Tips Pemecahan Masalah untuk Sampel WCF.

Untuk menjalankan contoh program di berbagai komputer

  1. Buat direktori di komputer layanan untuk biner layanan.

  2. Salin file program layanan ke direktori layanan pada komputer layanan. Salin juga file Setup.bat dan Cleanup.bat ke komputer layanan.

  3. Anda harus memiliki sertifikat server dengan nama subjek yang berisi nama domain komputer yang sepenuhnya memenuhi syarat. File App.config layanan harus diperbarui untuk mencerminkan nama sertifikat baru ini. Anda dapat membuatnya dengan menggunakan Setup.bat jika Anda mengatur variabel %SERVER_NAME% ke nama host lengkap komputer di mana layanan akan berjalan. Perhatikan bahwa file setup.bat harus dijalankan dari Developer Command Prompt untuk Visual Studio yang dibuka dengan hak administratif.

  4. Salin sertifikat server ke penyimpanan CurrentUser-TrustedPeople klien. Anda tidak perlu melakukan ini kecuali ketika sertifikat server dikeluarkan oleh penerbit tepercaya klien.

  5. Dalam file App.config di komputer layanan, ubah nilai alamat dasar untuk menentukan nama komputer yang sepenuhnya memenuhi syarat alih-alih localhost.

  6. Pada komputer servis, jalankan service.exe dari command prompt.

  7. Salin file program klien dari folder \client\bin\, di bawah folder khusus bahasa, ke komputer klien.

  8. Dalam file Client.exe.config di komputer klien, ubah nilai alamat titik akhir agar sesuai dengan alamat baru layanan Anda.

  9. Di komputer klien, jalankan Client.exe dari jendela perintah.

  10. Jika klien dan layanan tidak dapat berkomunikasi, lihat Tips Pemecahan Masalah untuk Sampel WCF.

Untuk membersihkan setelah pengujian sampel

  1. Jalankan Cleanup.bat di folder sampel setelah Anda selesai menjalankan sampel.