如何扩展/修改ADFS 4.0(2016)响应以实现中间重定向需求?
扩展ADFS 4.0(2016版)行为以满足特殊业务需求
当前流程
- 依赖方(WS-FED、SAML或OAuth服务提供商)向作为IdP的ADFS发送AuthnRequest。
- 用户通过表单、Windows登录或其他联合认证提供商完成认证。
- 通过声明规则提供姓名等信息,同时包含名为redirect claim的特殊声明,作为服务提供商的标识。
- 声明返回至请求的依赖方,应用需停止认证流程并根据该声明重定向至指定地址。
- 用户在重定向页面完成任务(如选择配置文件、同意条款等)。
- 用户被重定向回请求应用,自动重启认证流程。
- 第二次认证基于SSO无需用户交互,返回不含redirect claim的完整响应。
痛点
该流程虽可行,但要求所有服务提供商在工作流中支持该特殊声明。目前我们有约300个应用,其中多为第三方开发,需协调大量厂商适配,成本极高。
期望的替代流程
希望ADFS能直接根据特定声明进行重定向,寻求扩展其行为的方法,优先考虑原生功能,也接受变通方案:
- 考虑过自定义透明代理拦截ADFS响应并检测redirect claim;
- 考虑过用C#编写OAuth2代理,但需处理SLO、IdP配置等协议细节,工作量大;
- 疑问ADFS是否提供请求/响应过滤器;
- 是否有现成易适配的软件(如Keycloak),优先C#实现。
已尝试方案
尝试过编写自定义MFA扩展ADFS登录行为,但受限于SSO:仅在首次登录生效,禁用SSO则需重复认证,无法满足需求。
现有想法
考虑用C#编写自定义OAuth代理,作为服务提供商的IdP,同时作为ADFS的依赖方。该方案对OAuth的可控性较高,而SAML因加密等细节工作量过大。
可行方案建议
方案1:ADFS原生自定义声明转换模块
ADFS 4.0支持用C#编写自定义Claims Transformation模块,可在声明发放阶段插入重定向逻辑:
- 编写DLL实现
IClaimsTransformation接口,在Transform方法中检测redirect claim的存在; - 若存在,构造302重定向响应并终止当前认证流程,重定向时携带原始请求的RelayState、依赖方ID等上下文参数;
- 用户完成任务后,利用ADFS的SSO会话直接发起二次认证,无需用户交互,最终返回无redirect claim的响应;
- 将该模块注册到ADFS的声明规则中,对所有依赖方生效,完全无需修改应用代码。
方案2:Web Application Proxy(WAP)层拦截扩展
如果已部署WAP,可在WAP上添加自定义HTTP模块实现透明拦截:
- 拦截ADFS返回给依赖方的响应,解析SAML断言、WS-FED令牌或OAuth响应体;
- 检测redirect claim,若存在则将响应替换为302重定向,携带必要的上下文参数;
- 用户完成任务后,重定向回WAP,由WAP转发原始认证请求到ADFS,利用SSO会话完成后续流程;
- 该方案对ADFS核心无侵入,适配所有协议类型,依赖方完全感知不到中间逻辑。
方案3:轻量级C#多协议代理网关
优先C#实现的话,构建轻量级代理网关是平衡可控性和工作量的选择:
- 网关作为所有应用的IdP,同时配置为ADFS的Relying Party;
- 应用的AuthnRequest先发送到网关,网关转发至ADFS完成用户认证;
- 网关接收ADFS返回的断言/令牌,检测redirect claim;
- 若存在,触发重定向到任务页面,完成后网关利用用户的SSO会话向ADFS发起二次认证,获取无特殊声明的响应后返回给应用;
- 针对SAML协议,使用.NET自带的
System.IdentityModel.Tokens.Saml库简化断言解析和转发,避免手动处理加密、签名等复杂细节; - 网关只需维护与ADFS的单一RPT配置,所有应用的适配工作集中在网关层,大幅降低协调成本。
方案4:Keycloak中间层(低适配成本备选)
如果允许非C#方案,Keycloak可快速落地需求:
- 将Keycloak配置为ADFS的联邦依赖方(通过SAML或OAuth 2.0),同时作为所有应用的IdP;
- 在Keycloak的认证流程中添加自定义执行步骤,检测ADFS返回的redirect claim;
- 触发重定向到任务页面,完成后继续认证流程,向应用返回无特殊声明的响应;
- Keycloak原生支持多协议,批量导入应用配置的效率远高于逐个协调第三方厂商。
内容的提问来源于stack exchange,提问作者DominikAmon
相关产品推荐
相关产品推荐

