ASP.Net 使用 Cookie 登录核心 WSFederationAuth - 无法访问网站
ASP.Net Core WSFederationAuth Login with Cookie - Site can't be reached
我正在将旧站点升级到 ASP.NET Core 2.1,但仍将 .NET Framework 4.7.2 作为目标框架。
我们正在尝试使用 WSFederation 服务来处理此 Microsoft document 中所述的身份验证。一个单独的站点处理实际登录,然后在 /Federation 端点重定向回我们的站点。
我们的Startup.csclass:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(authOptions =>
{
authOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
authOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
authOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
})
.AddWsFederation(wsOptions =>
{
wsOptions.Wtrealm = Configuration.GetValue<string>("WSFed:Realm");
wsOptions.MetadataAddress = Configuration.GetValue<string>("WSFed:Metadata");
wsOptions.CallbackPath = "/Federation";
})
.AddCookie(cookieOptions =>
{
cookieOptions.Cookie.SameSite = SameSiteMode.None;
});
//Fixes correlation error
services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddHttpsRedirection(options =>
{
options.HttpsPort = 443;
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseDeveloperExceptionPage();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
然后我们将“[Authorize]”属性添加到我们的 Home 控制器。当我 运行 这样做时,我收到“无法访问此站点”错误。位于 https://localhost:44339/ 的网页可能会暂时关闭,也可能已永久移动到新网址。 ERR_HTTP2_PROTOCOL_ERROR
当我在 Chrome 开发工具中查看网络选项卡时,我可以看到正在传递的 cookie 我可以看到传递了正确的声明信息,所以看起来这部分工作正常.
知道可能出了什么问题吗?
更新
我添加了事件 wsOptions.Events.OnSecurityTokenValidated 并在其中放置了一个断点。我可以看到声明值,所以看起来身份验证已经成功,但我仍然得到 ERR_HTTP2_PROTOCOL_ERROR错误。如果我从控制器中删除 [Authorize] 属性,站点 运行s,但我显然不想删除该属性。
更新 2
问题似乎是 Cookie 太大了。目前正在研究解决此问题的方法。
主要问题似乎是 cookie/claim 大小(roles/AD 组太多)。
理想的解决方案似乎是缩小 cookie/claim 的大小,但这对我们现在来说并不现实。
我通过添加一个 OnSecurityTokenValidated 事件并在其中将角色连接成一个声明字符串值并在每个声明字符串值之间使用硬编码分隔符来解决这个问题。这样一来,您就有一个角色声明值,而不是每个角色一个声明值,从而大大减小了大小。
.AddWsFederation(wsOptions =>
{
...
wsOptions.Events.OnSecurityTokenValidated = (context) =>
{
//Condense claim data (roles) - otherwise we get errors for too large of claims
HashSet<Claim> filteredClaims = new HashSet<Claim>();
HashSet<string> groupSet = new HashSet<string>();
foreach(Claim claim in context.Principal.Claims)
{
if(claim.Type != ClaimTypes.Role)
{
filteredClaims.Add(claim);
}
else
{
groupSet.Add(claim.Value);
}
}
filteredClaims.Add(new Claim("<insert new claim key here>", string.Join("zzzsep", groupSet)));
List <ClaimsIdentity> filteredClaimsIdentity = new List<ClaimsIdentity>() { new ClaimsIdentity(filteredClaims, context.Principal.Identity.AuthenticationType) };
ClaimsPrincipal newClaimsPrincipal = new ClaimsPrincipal(filteredClaimsIdentity);
context.Principal = newClaimsPrincipal;
return Task.FromResult(0);
};
})
然后当实际从声明中获取 groups/roles 时,我通过硬编码分隔符拆分字符串以获得值数组。
我正在将旧站点升级到 ASP.NET Core 2.1,但仍将 .NET Framework 4.7.2 作为目标框架。
我们正在尝试使用 WSFederation 服务来处理此 Microsoft document 中所述的身份验证。一个单独的站点处理实际登录,然后在 /Federation 端点重定向回我们的站点。
我们的Startup.csclass:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(authOptions =>
{
authOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
authOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
authOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
})
.AddWsFederation(wsOptions =>
{
wsOptions.Wtrealm = Configuration.GetValue<string>("WSFed:Realm");
wsOptions.MetadataAddress = Configuration.GetValue<string>("WSFed:Metadata");
wsOptions.CallbackPath = "/Federation";
})
.AddCookie(cookieOptions =>
{
cookieOptions.Cookie.SameSite = SameSiteMode.None;
});
//Fixes correlation error
services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddHttpsRedirection(options =>
{
options.HttpsPort = 443;
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseDeveloperExceptionPage();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
然后我们将“[Authorize]”属性添加到我们的 Home 控制器。当我 运行 这样做时,我收到“无法访问此站点”错误。位于 https://localhost:44339/ 的网页可能会暂时关闭,也可能已永久移动到新网址。 ERR_HTTP2_PROTOCOL_ERROR
当我在 Chrome 开发工具中查看网络选项卡时,我可以看到正在传递的 cookie 我可以看到传递了正确的声明信息,所以看起来这部分工作正常.
知道可能出了什么问题吗?
更新
我添加了事件 wsOptions.Events.OnSecurityTokenValidated 并在其中放置了一个断点。我可以看到声明值,所以看起来身份验证已经成功,但我仍然得到 ERR_HTTP2_PROTOCOL_ERROR错误。如果我从控制器中删除 [Authorize] 属性,站点 运行s,但我显然不想删除该属性。
更新 2
问题似乎是 Cookie 太大了。目前正在研究解决此问题的方法。
主要问题似乎是 cookie/claim 大小(roles/AD 组太多)。
理想的解决方案似乎是缩小 cookie/claim 的大小,但这对我们现在来说并不现实。
我通过添加一个 OnSecurityTokenValidated 事件并在其中将角色连接成一个声明字符串值并在每个声明字符串值之间使用硬编码分隔符来解决这个问题。这样一来,您就有一个角色声明值,而不是每个角色一个声明值,从而大大减小了大小。
.AddWsFederation(wsOptions =>
{
...
wsOptions.Events.OnSecurityTokenValidated = (context) =>
{
//Condense claim data (roles) - otherwise we get errors for too large of claims
HashSet<Claim> filteredClaims = new HashSet<Claim>();
HashSet<string> groupSet = new HashSet<string>();
foreach(Claim claim in context.Principal.Claims)
{
if(claim.Type != ClaimTypes.Role)
{
filteredClaims.Add(claim);
}
else
{
groupSet.Add(claim.Value);
}
}
filteredClaims.Add(new Claim("<insert new claim key here>", string.Join("zzzsep", groupSet)));
List <ClaimsIdentity> filteredClaimsIdentity = new List<ClaimsIdentity>() { new ClaimsIdentity(filteredClaims, context.Principal.Identity.AuthenticationType) };
ClaimsPrincipal newClaimsPrincipal = new ClaimsPrincipal(filteredClaimsIdentity);
context.Principal = newClaimsPrincipal;
return Task.FromResult(0);
};
})
然后当实际从声明中获取 groups/roles 时,我通过硬编码分隔符拆分字符串以获得值数组。