WsFederation在回调过程中收到错误“无消息”

时间:2019-06-14 16:22:15

标签: asp.net-core ws-federation

我有一个新的.Net Core Razor应用程序,该应用程序使用本地登录名,我正在尝试使用我们公司的IDP(来自Computer Associates的SAML2服务)添加联合身份验证。 IDP不提供MetadabaseAddress,因此我必须手动配置所有内容。我能够单击新的“登录”按钮,并重定向到IDP的登录页面,登录后,我将重定向到我的应用程序的“登录-wsfed”页面,但是出现了“无消息”错误

我已将错误的源归结为WsFederationHandler.cs类here,看来该处理程序无法找到saml令牌,但是,使用浏览器的开发人员工具,我可以看到表单数据包含令牌(看起来像是基数为64的字符串)。

这是我的代码:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

        services.AddIdentity<ApplicationUser, IdentityRole>(options =>
            {
                // Password settings for local accounts
                options.Password.RequireDigit = true;
                options.Password.RequiredLength = 8;
                options.Password.RequiredUniqueChars = 2;
                options.Password.RequireLowercase = true;
                options.Password.RequireNonAlphanumeric = true;
                options.Password.RequireUppercase = true;
                options.User.RequireUniqueEmail = true;
                options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@!$";
            })
            .AddEntityFrameworkStores<ApplicationContext>()
            .AddDefaultTokenProviders();

        // Creating the configuration object for WsFederation so we can access more settings
        // This is used in lieu of retrieving the MetadataBase xml file from the IDP
        var wsfConfig = new WsFederationConfiguration
        {
            TokenEndpoint = Configuration.GetValue<string>("MyAccess:TokenEndpoint"), // This is where the user gets redirected to, provided by the MyAccess team. Example: https://federatetest.smext.faa.gov/affwebservices/public/saml2sso?SPID=https://training.amc.faa.gov
            Issuer = Configuration.GetValue<string>("MyAccess:Issuer") // This is the entityId from the settings Xml file, typically the URI of the application

        };

        // Add the certificate that will be used by the IDP to sign (encrypt) the token; this way we know how to decrypt the token
        // The cert is a base64 encoded string
        wsfConfig.SigningKeys.Add(new X509SecurityKey(new X509Certificate2(Convert.FromBase64String(Configuration.GetValue<string>("MyAccess:Certificate")))));

        services.AddAuthentication(authOptions =>
            {
                authOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                authOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                authOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
            })
            .AddWsFederation(WsFederationDefaults.AuthenticationScheme, "My Access", options =>
            {
                options.Configuration = wsfConfig;
                options.Wreply = Configuration.GetValue<string>("MyAccess:Reply");
                options.Wtrealm = Configuration.GetValue<string>("MyAccess:Realm");
                options.TokenValidationParameters.NameClaimType = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress";
                //options.SkipUnrecognizedRequests = true;
                // Uncomment if IDP requires a wct value
                //options.Events.OnRedirectToIdentityProvider = context =>
                //    {
                //        context.ProtocolMessage.Wct = DateTimeOffset.UtcNow.ToString();
                //        return Task.CompletedTask;
                //    };
            })
            .AddCookie();

        //Configure D I
        services.AddScoped<IEmployeeStore, EmployeeStore>();
        services.AddScoped<IDepartmentStore, DepartmentStore>();

        // Configure additional services
        services.AddMvc();
        // Adds a default in-memory implementation of IDistributedCache.
        services.AddDistributedMemoryCache();

        services.AddSession(options =>
        {
            // Set the session timeout
            options.IdleTimeout = TimeSpan.FromMinutes(45);
            options.Cookie.Name = ".EmployeeTracker.Session";
        });

        // This is where we define our authorization policies
        services.AddAuthorization(options =>
        {
            options.AddPolicy("EmployeeViewer", policy =>
            {
                policy.RequireAuthenticatedUser();
                policy.RequireClaim("Role", "admin");
            });
        });

        services.ConfigureApplicationCookie(options =>
        {
            // Cookie settings
            options.Cookie.HttpOnly = true;
            options.ExpireTimeSpan = TimeSpan.FromMinutes(45);

            options.LoginPath = "/Login/Login";
            options.SlidingExpiration = true;
        });

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }

    // 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, UserManager<ApplicationUser> userManager)
    {
        GlobalDiagnosticsContext.Set("configDir", Configuration.GetSection("AppSettings")["NLogDir"]);
        GlobalDiagnosticsContext.Set("connectionString", Configuration.GetConnectionString("DefaultConnection"));

        if (env.IsDevelopment())
        {
            // Only enable BrowserLink if it's really needed.  It's a resource hog.
            //app.UseBrowserLink();
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            // Configure security settings
            app.UseXContentTypeOptions(); // sets the X-Content-Type-Options to no-sniff
            app.UseReferrerPolicy(opts => opts.NoReferrer());
            app.UseXXssProtection(options => options.EnabledWithBlockMode());
            app.UseXfo(options => options.Deny()); // Block iframes
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts(hsts => hsts.MaxAge(1).IncludeSubdomains());
        }

        // Configure middleware
        app.UseAuthentication();
        app.UseStaticFiles();
        app.UseStatusCodePagesWithReExecute("/Status{0}"); // Status403.cshtml, Status404.cshtml, etc.
        app.UseCookiePolicy();
        app.UseSession();
        app.UseMvc();
    }
}

这是我在开发人员工具中看到的内容: Screen shot of form data in developer tools

由于我必须手动配置事物,因此会遗漏一些东西。另外,只是为了证实我的怀疑,我在SkipUnrecognizedRequests中添加了该选项,并得到了另一个错误。

TIA,为您提供任何帮助。

0 个答案:

没有答案