如何为已完成开发的C# MVC应用集成On-Premise ADFS 2.0认证?
事后接入ADFS 2.0的C# MVC应用集成方案
刚好之前帮几个客户处理过这种开发完成后才接入ADFS的场景,给你一套落地性很强的方案,一步步来就能搞定:
1. 先安装必要的NuGet包
因为是.NET Framework的MVC项目,推荐用OWIN的WsFederation中间件(比传统的WIF更灵活易维护)。打开NuGet包管理器控制台,运行以下命令:
Install-Package Microsoft.Owin.Security.WsFederation Install-Package Microsoft.Owin.Host.SystemWeb Install-Package Owin
2. 配置OWIN Startup类
如果你的项目还没有OWIN Startup类,直接在项目根目录新建一个Startup.cs,然后添加认证配置:
using Microsoft.Owin; using Microsoft.Owin.Security; using Microsoft.Owin.Security.Cookies; using Microsoft.Owin.Security.WsFederation; using Owin; using System.Threading.Tasks; using System.Security.Claims; [assembly: OwinStartup(typeof(YourMvcAppNamespace.Startup))] namespace YourMvcAppNamespace { public class Startup { public void Configuration(IAppBuilder app) { // 启用Cookie认证,用来存储ADFS返回的用户身份 app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = CookieAuthenticationDefaults.AuthenticationType, LoginPath = new PathString("/Account/Login"), // 触发ADFS登录的入口 ExpireTimeSpan = System.TimeSpan.FromHours(8) }); // 配置WsFederation对接ADFS app.UseWsFederationAuthentication(new WsFederationAuthenticationOptions { // ADFS元数据地址,自动获取ADFS的配置信息 MetadataAddress = "https://your-adfs-server/FederationMetadata/2007-06/FederationMetadata.xml", // 必须和ADFS里为你的应用配置的Realm完全一致 Wtrealm = "urn:your-mvc-app-realm", // 回调地址,也要在ADFS的应用注册里配置好 Wreply = "https://your-mvc-app-domain/", AuthenticationType = "WsFederation", // 自定义声明处理的通知事件 Notifications = new WsFederationAuthenticationNotifications { SecurityTokenValidated = context => { // 这里可以根据业务需求处理ADFS返回的声明 var identity = context.AuthenticationTicket.Identity; // 示例:把ADFS的NameIdentifier声明映射为应用内的用户名 var nameClaim = identity.FindFirst(ClaimTypes.NameIdentifier); if (nameClaim != null) { identity.AddClaim(new Claim(ClaimTypes.Name, nameClaim.Value)); } return Task.CompletedTask; } } }); } } }
3. 修改Web.config的认证授权配置
找到<system.web>节点,更新认证模式和默认授权规则:
<system.web> <!-- 禁用Forms认证,交给OWIN处理 --> <authentication mode="None" /> <authorization> <!-- 默认拒绝所有匿名访问,需要认证才能进入应用 --> <deny users="?" /> </authorization> </system.web>
如果有不需要认证的页面(比如首页、静态资源),可以添加<location>节点单独配置:
<location path="Home/Index"> <system.web> <authorization> <allow users="*" /> </authorization> </system.web> </location>
4. 实现ADFS登录触发逻辑
在你的AccountController里添加Login方法,用来触发ADFS的认证流程:
using System.Web; using System.Web.Mvc; using Microsoft.Owin.Security; public class AccountController : Controller { public ActionResult Login(string returnUrl) { if (!Request.IsAuthenticated) { // 触发ADFS登录请求,登录成功后跳转到指定页面 var properties = new AuthenticationProperties { RedirectUri = returnUrl ?? Url.Action("Index", "Home") }; HttpContext.GetOwinContext().Authentication.Challenge(properties, "WsFederation"); return new HttpUnauthorizedResult(); } return RedirectToAction("Index", "Home"); } // 实现登出逻辑,同时通知ADFS注销 public ActionResult Logout() { HttpContext.GetOwinContext().Authentication.SignOut( CookieAuthenticationDefaults.AuthenticationType, "WsFederation"); return RedirectToAction("Index", "Home"); } }
5. 访问和使用ADFS声明
在控制器里,你可以通过User.Identity获取ADFS返回的所有声明,比如在Profile页面展示用户信息:
public ActionResult Profile() { var claimsIdentity = User.Identity as ClaimsIdentity; if (claimsIdentity != null) { var userClaims = claimsIdentity.Claims.ToList(); // 可以把声明传给视图展示,或者用来做业务逻辑判断 return View(userClaims); } return View(); }
如果需要全局处理声明(比如添加角色、转换声明格式),可以自定义ClaimsAuthenticationManager:
public class CustomClaimsManager : ClaimsAuthenticationManager { public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal) { if (!incomingPrincipal.Identity.IsAuthenticated) { return base.Authenticate(resourceName, incomingPrincipal); } var identity = (ClaimsIdentity)incomingPrincipal.Identity; // 示例:根据ADFS的Email声明添加角色 var emailClaim = identity.FindFirst(ClaimTypes.Email); if (emailClaim?.Value == "admin@yourcompany.com") { identity.AddClaim(new Claim(ClaimTypes.Role, "Administrator")); } return new ClaimsPrincipal(identity); } }
然后在Web.config里注册这个管理器:
<system.identityModel> <identityConfiguration> <claimsAuthenticationManager type="YourMvcAppNamespace.CustomClaimsManager, YourMvcAppNamespace" /> </identityConfiguration> </system.identityModel>
6. 必踩坑的注意事项
- ADFS配置必须完全一致:
Wtrealm和Wreply的取值要和ADFS服务器上为你的应用配置的完全相同,包括URL的大小写、是否带斜杠,而且必须是HTTPS(ADFS 2.0强制要求)。 - 元数据地址可访问:确保应用服务器能正常访问ADFS的元数据URL,否则会出现配置加载失败的问题。
- 启用HTTPS:本地开发可以用自签名证书,生产环境必须用正规SSL证书,否则ADFS会拒绝回调请求。
- 调试声明:登录后可以打印所有声明,确认ADFS返回的内容是否符合预期,方便后续业务逻辑对接。
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

