You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core中ADFS认证授权实现及相关技术问题咨询

.NET Core中ADFS认证与Claims相关问题

现有实现代码

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");

builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));

builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddAuthentication(sharedOptions =>
    {
        sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
    })
    .AddWsFederation(options =>
    {
        options.Wtrealm = "urn:DevTest";
        options.MetadataAddress = "https://example.com/FederationMetadata/2007-06/FederationMetadata.xml";
        options.Wreply = "https://localhost:44341/Home/Index/";

    })
    .AddCookie();

核心问题

  1. 如果需要使用Claims,ASP.NET Identity是否是必需项?(当前获取Claims的代码如下)
ClaimsIdentity id = ((ClaimsIdentity)User.Identity);
var claim = id.FindFirst(ClaimTypes.Email);
  1. 遇到IsAuthenticated返回false的问题:
    • 相同配置在另一ASP.NET MVC应用中正常工作
    • 排查发现ADFS服务器未配置NameID claim,是否会导致认证失败?
    • ClaimsIdentity的IsAuthenticated属性基于AuthenticationType值判断,当前该值为null,是否因缺少NameID claim导致?(ClaimsIdentity源码如下)
public virtual bool IsAuthenticated
{
    get { return !string.IsNullOrEmpty(_authenticationType); }
}
  1. 能否提供ADFS认证与基于Claims的授权的示例实现?

问题1:使用Claims是否必须依赖ASP.NET Identity?

不需要。ASP.NET Identity是一套包含用户存储、角色管理的用户管理系统,但Claims是ASP.NET Core认证系统的核心组成部分,所有基于标准认证协议(如WsFederation、OpenID Connect)的认证方式都会自动生成ClaimsIdentity,完全无需依赖ASP.NET Identity。

你当前代码中同时添加了ASP.NET Identity和WsFederation认证,两者可以共存,但如果只需要ADFS认证和Claims操作,完全可以移除AddDefaultIdentity相关代码,不会影响Claims的获取与使用。

问题2:IsAuthenticated返回false的原因分析

(1)NameID claim缺失是否导致认证失败?

NameID是ADFS默认的用户唯一标识Claim,但它不会直接导致认证失败——ADFS仍会完成认证流程,只是返回的Claims集合中没有NameID。部分认证中间件可能期望存在唯一标识用户的Claim,可能影响后续Cookie生成,但不是IsAuthenticated为false的直接原因。

(2)AuthenticationType为null的原因

IsAuthenticated返回false的直接原因是AuthenticationType为null,这通常是因为认证中间件未正确设置ClaimsIdentity的认证类型。在WsFederation认证流程中,中间件应自动将AuthenticationType设置为WsFederationDefaults.AuthenticationScheme(即"WsFederation")。

常见触发原因:

  • WsFederation配置错误:比如MetadataAddress无法访问、Wtrealm与ADFS中信赖方标识符不匹配
  • 认证流程未完整执行:用户未完成ADFS登录跳转,或回调后中间件未正确处理响应生成ClaimsIdentity
  • 配置冲突:代码中重复调用AddCookie,WsFederation已隐式依赖Cookie处理,单独调用可能导致配置冲突

问题3:ADFS认证与基于Claims授权的示例实现

(1)简化认证配置(移除ASP.NET Identity)

builder.Services.AddAuthentication(sharedOptions =>
{
    sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
})
.AddWsFederation(options =>
{
    options.Wtrealm = "urn:DevTest"; // 必须与ADFS中信赖方标识符完全一致
    options.MetadataAddress = "https://your-adfs-server/FederationMetadata/2007-06/FederationMetadata.xml";
    // 回调地址可选,默认使用/signin-wsfed,若自定义需确保ADFS同步配置
    // options.Wreply = "https://localhost:44341/signin-wsfed";
})
.AddCookie(); // 如需自定义Cookie配置可在此调整,WsFederation已依赖Cookie处理

(2)获取Claims并处理

在Controller中获取Claims:

public IActionResult Index()
{
    if (User.Identity is ClaimsIdentity claimsIdentity)
    {
        var emailClaim = claimsIdentity.FindFirst(ClaimTypes.Email);
        var nameClaim = claimsIdentity.FindFirst(ClaimTypes.Name);
        // 业务逻辑处理
    }
    return View();
}

(3)基于Claims的授权策略配置

在Program.cs中定义授权策略:

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("RequireEmail", policy =>
        policy.RequireClaim(ClaimTypes.Email));
    
    options.AddPolicy("AdminOnly", policy =>
        policy.RequireClaim("Role", "Admin")); // 需确保ADFS返回对应Role类型Claim
});

在Controller/Action上应用策略:

[Authorize(Policy = "RequireEmail")]
public IActionResult SecurePage()
{
    return View();
}

[Authorize(Policy = "AdminOnly")]
public IActionResult AdminPanel()
{
    return View();
}

(4)ADFS端配置注意事项

  • 确保信赖方标识符与代码中Wtrealm完全匹配
  • 配置ADFS向信赖方发送必要的Claims(如Email、Name、Role等)
  • 确保ADFS元数据地址可被应用正常访问

针对当前问题的排查建议

  1. 移除代码中多余的AddDefaultIdentity和单独的AddCookie调用,简化认证配置
  2. 核对ADFS中信赖方的配置:Wtrealm是否匹配,是否配置了要发送的Claims
  3. 开启认证日志排查中间件执行过程:
builder.Logging.AddFilter("Microsoft.AspNetCore.Authentication", LogLevel.Debug);
  1. 确认用户完成ADFS登录流程,回调地址与ADFS配置一致

内容的提问来源于stack exchange,提问作者Nina

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 18:45:01