zoukankan      html  css  js  c++  java
  • 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:Securityencryption.pfx";
            string encryptionCertificatePassword = "123456";//证书密码
    
            X509Certificate2 encryptionX509Certificate = new X509Certificate2(encryptionCertificatePath, encryptionCertificatePassword);
            SecurityKey encryptionSecurityKey = new X509SecurityKey(encryptionX509Certificate);
    
            //验证Issuer的公钥证书(.cer证书文件,只包含公钥,不包含私钥)
            string issuerCertificatePath = @"C:Securityissuer.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 中的用户进行身份验证

  • 相关阅读:
    招聘.NET开发人员
    SQL 2005 SSIS 导入数据效率问题
    用户控件使用事件与调用页面交互
    使用sql语句删除标识列属性
    poj1520
    poj1476
    poj1363
    poj1477
    poj1312
    大端法小端法与union
  • 原文地址:https://www.cnblogs.com/OpenCoder/p/10627443.html
Copyright © 2011-2022 走看看