ASP.NET Core如何使用WSFederation身份認證集成ADFS


如果要在ASP.NET Core項目中使用WSFederation身份認證,首先需要在項目中引入NuGet包:

Microsoft.AspNetCore.Authentication.WsFederation

 

 

不使用證書驗證Issuer,也不使用證書加密ADFS的認證信息


 

如果你的ASP.NET Core項目,不需要證書來驗證ADFS的Issuer信息,也不需要證書來加密ADFS的認證信息,那么只需要在ASP.NET Core的Startup類中設置和啟用WsFederation中間件即可,代碼如下所示:

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(sharedOptions =>
    {
        sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
    })
    .AddWsFederation(options =>
    {
        // MetadataAddress represents the Active Directory instance used to authenticate users.
        options.MetadataAddress = "https://www.contoso.com/FederationMetadata/2007-06/FederationMetadata.xml";

        // Wtrealm is the app's identifier in the Active Directory instance.
        options.Wtrealm = "https://localhost:44307/";

        //用戶在ADFS登錄頁成功登錄后,跳轉回ASP.NET Core站點的URL地址
        options.Wreply = "https://localhost:44307/signin";

        //用於解析從ADFS登錄頁傳回ASP.NET Core站點的認證信息的URL地址,ASP.NET Core會使用該URL地址將ADFS認證信息解析為Claim,並存儲在Cookie中
        options.CallbackPath = "/signin";

        //設置WsFederation認證中間件與遠程ADFS認證服務器的網絡通信連接超時時間為1分鍾
        options.BackchannelTimeout = TimeSpan.FromMinutes(1);

        //設置完成整個ADFS認證流程的超時時間為15分鍾
        options.RemoteAuthenticationTimeout = TimeSpan.FromMinutes(15);
    })
    .AddCookie();

    services.AddMvc();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseBrowserLink();
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseStaticFiles();
    app.UseAuthentication();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

上面的代碼中有兩個屬性需要注意:

  • options.Wreply,是用戶在ADFS登錄頁成功登錄后,跳轉回ASP.NET Core站點的URL地址
  • options.CallbackPath,是用於解析從ADFS登錄頁傳回ASP.NET Core站點的認證信息的URL地址,ASP.NET Core會使用該URL地址將ADFS認證信息解析為Claim,並存儲在用戶瀏覽器的Cookie中

因此options.CallbackPath的地址必須要和options.Wreply的地址保持一致,例如上面我們設置了options.Wreply為"https://localhost:44307/signin",那么options.CallbackPath必須是options.Wreply中以"/"開頭的絕對路徑URL地址,也就是"/signin"(注意options.CallbackPath不能設置為帶主機域名的完全URL地址,只能是以"/"開頭的絕對路徑URL地址)。這樣當用戶從ADFS登錄頁成功登錄后,跳轉回我們的ASP.NET Core站點時,ASP.NET Core才能成功解析ADFS的認證信息。

 

上面代碼中還有兩個關於超時的屬性:

  • options.BackchannelTimeout,是WsFederation認證中間件與遠程ADFS認證服務器的網絡通信連接超時時間
  • options.RemoteAuthenticationTimeout,是完成整個ADFS認證流程的超時時間

這兩個超時屬性如果時間設置得太小,可能會造成認證超時而拋出異常,實際上這兩個屬性屬於RemoteAuthenticationOptions類,WsFederationOptions類繼承於RemoteAuthenticationOptions類,所有繼承RemoteAuthenticationOptions的類都可以設置這兩個超時屬性。

 

 

使用證書驗證Issuer,並使用證書加密ADFS的認證信息


 

由於接下來本文中我們要在WSFederation認證中用到X509證書,所以你需要先申請一個.pfx證書文件,用於加密和解密ADFS的認證信息,將該.pfx文件使用certlm.msc命令,來導入ASP.NET Core站點服務器certlm中的"Trusted Root Certification Authorities"和"Personal"文件夾中,如下所示:

運行certlm.msc命令:

在左邊列表中,找到"Trusted Root Certification Authorities"文件夾,然后在下面的"Certificates"文件夾上點擊鼠標右鍵,通過右鍵菜單選擇"All Tasks",然后點擊"Import":

然后通過導入向導,導入你的.pfx證書文件到certlm中"Trusted Root Certification Authorities"文件夾:

再在certlm.msc左邊列表中,找到"Personal"文件夾,然后在下面的"Certificates"文件夾上點擊鼠標右鍵,通過右鍵菜單選擇"All Tasks",然后點擊"Import":

然后同樣通過導入向導,導入你的.pfx證書文件到certlm中"Personal"文件夾:

 

接下來,你還要確保服務器IIS中,已經在ASP.NET Core項目站點使用的應用程序池上,設置了Load User Profile屬性為True。

 

然后按照下面的代碼,在ASP.NET Core的Startup類中設置和啟用WsFederation中間件:

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(sharedOptions =>
    {
        sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
    })
    .AddWsFederation(options =>
    {
        // MetadataAddress represents the Active Directory instance used to authenticate users.
        options.MetadataAddress = "https://www.contoso.com/FederationMetadata/2007-06/FederationMetadata.xml";

        // Wtrealm is the app's identifier in the Active Directory instance.
        options.Wtrealm = "https://localhost:44307/";

        //用戶在ADFS登錄頁成功登錄后,跳轉回ASP.NET Core站點的URL地址
        options.Wreply = "https://localhost:44307/signin";

        //用於解析從ADFS登錄頁傳回ASP.NET Core站點的認證信息的URL地址,ASP.NET Core會使用該URL地址將ADFS認證信息解析為Claim,並存儲在Cookie中
        options.CallbackPath = "/signin";

        //設置WsFederation認證中間件與遠程ADFS認證服務器的網絡通信連接超時時間為1分鍾
        options.BackchannelTimeout = TimeSpan.FromMinutes(1);

        //設置完成整個ADFS認證流程的超時時間為15分鍾
        options.RemoteAuthenticationTimeout = TimeSpan.FromMinutes(15);

        //ADFS認證信息的加密和解密證書(.pfx證書文件,既包含公鑰,又包含私鑰)
        string encryptionCertificatePath = @"C:\Security\encryption.pfx";
        string encryptionCertificatePassword = "123456";//證書密碼

        X509Certificate2 encryptionX509Certificate = new X509Certificate2(encryptionCertificatePath, encryptionCertificatePassword);
        SecurityKey encryptionSecurityKey = new X509SecurityKey(encryptionX509Certificate);

        //驗證Issuer的公鑰證書(.cer證書文件,只包含公鑰,不包含私鑰)
        string issuerCertificatePath = @"C:\Security\issuer.cer";

        X509Certificate2 issuerX509Certificate = new X509Certificate2(issuerCertificatePath);
        SecurityKey issuerSecurityKey = new X509SecurityKey(issuerX509Certificate);

        options.TokenValidationParameters = new TokenValidationParameters
        {
            AuthenticationType = CookieAuthenticationDefaults.AuthenticationScheme,
            TokenDecryptionKey = encryptionSecurityKey,//設置解密ADFS認證信息的證書
            IssuerSigningKey = issuerSecurityKey,//設置驗證Issuer的公鑰證書
            ValidateIssuerSigningKey = true,
            ValidateActor = false,
            ValidateTokenReplay = false,
            ValidateAudience = false,
            ValidateLifetime = false,
            ValidateIssuer = true
        };
    })
    .AddCookie();

    services.AddMvc();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseBrowserLink();
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseStaticFiles();
    app.UseAuthentication();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

注意上面代碼中:

  • encryption.pfx證書文件,既包含公鑰,又包含私鑰,它用於在ADFS登錄頁上加密ADFS認證信息,並且在我們的ASP.NET Core站點中解密ADFS認證信息。
  • issuer.cer證書文件,只包含公鑰,不包含私鑰,它用於驗證ADFS認證信息的頒發者(Issuer)的身份是否屬實。

 

 

參考文獻:

使用 WS 聯合身份驗證在 ASP.NET Core 中的用戶進行身份驗證

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM