使用Sustainsys.Saml2时特定IdP访问ACS URL返回500错误如何排查?
Sustainsys.Saml2 ACS端点500无日志问题排查方案
1. 优先调整中间件顺序并配置全局异常捕获
Sustainsys.Saml2的中间件如果注册在异常处理中间件之前,处理过程中抛出的异常不会被默认异常机制捕获,直接返回500且无日志,调整步骤如下:
- 自定义全局异常中间件,捕获所有未处理异常,同时记录ACS接口收到的原始请求内容,代码示例:
// 自定义全局异常中间件 public class GlobalExceptionMiddleware { private readonly RequestDelegate _next; private readonly ILogger<GlobalExceptionMiddleware> _logger; public GlobalExceptionMiddleware(RequestDelegate next, ILogger<GlobalExceptionMiddleware> logger) { _next = next; _logger = logger; } public async Task InvokeAsync(HttpContext context) { try { // 启用请求体可重读,避免读取后SAML中间件无法获取内容 context.Request.EnableBuffering(); await _next(context); } catch (Exception ex) { var requestContent = string.Empty; // 读取ACS接口的POST表单内容 if (context.Request.Path.Equals("/KM/Acs", StringComparison.OrdinalIgnoreCase) && context.Request.ContentType != null && context.Request.ContentType.Contains("application/x-www-form-urlencoded")) { var formData = await context.Request.ReadFormAsync(); requestContent = System.Text.Json.JsonSerializer.Serialize(formData); context.Request.Body.Position = 0; } _logger.LogError(ex, "ACS接口抛出未处理异常,请求内容:{RequestContent}", requestContent); context.Response.StatusCode = StatusCodes.Status500InternalServerError; await context.Response.WriteAsync("服务异常"); } } }
- 在Startup的
Configure方法最开头注册该中间件,确保优先级高于Saml2中间件和MVC中间件:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { // 全局异常中间件必须放在所有业务中间件最前面 app.UseMiddleware<GlobalExceptionMiddleware>(); // 再注册Saml2中间件 app.UseSaml2(); app.UseMvc(); }
2. 启用Sustainsys.Saml2内置日志与事件回调
Sustainsys.Saml2本身内置了完整的处理日志和异常回调,默认未开启所以无输出:
- 调整日志配置,将Sustainsys.Saml2的日志级别调整为Trace,在
appsettings.json中修改:
{ "Logging": { "LogLevel": { "Default": "Information", "Sustainsys.Saml2": "Trace" } } }
- 配置SAML认证失败事件回调,直接捕获SAML处理流程中的所有异常和原始请求报文,在
ConfigureServices的Saml2配置中添加:
services.AddSaml2(options => { // 原有SAML配置保持不变 // 注册认证失败事件回调 options.Events.OnAuthenticationFailed = context => { var logger = context.HttpContext.RequestServices.GetRequiredService<ILogger<Saml2Options>>(); var samlResponse = context.HttpContext.Request.Form["SAMLResponse"].FirstOrDefault(); logger.LogError(context.Exception, "SAML认证流程异常,原始SAML响应:{SamlResponse}", samlResponse); return Task.CompletedTask; }; });
3. 异常报文排查方向
拿到日志中记录的SAMLResponse后,可通过以下方向排查:
- 对base64编码的SAMLResponse解码得到原始XML,校验XML签名是否和你配置的IdP公钥匹配
- 确认XML中Issuer字段和你配置的IdP实体ID完全一致
- 校验断言中的时间范围
NotBefore、NotOnOrAfter和你服务器的当前时间差是否在允许的时钟偏移范围内,默认是5分钟,如果客户服务器时间偏差大可调整options.AllowedClockSkew属性验证 - 确认断言中指定的
AssertionConsumerServiceURL和你的ACS地址https://localhost:5000/KM/Acs完全匹配
内容的提问来源于stack exchange,提问作者Deepali D
相关产品推荐
相关产品推荐

