IdentityServer外部登录:长LoginHint/AcrValues触发失败
问题排查与解决方案:长参数导致OIDC登录流程失败
这个问题我之前帮同行排查过类似场景,核心矛盾其实是浏览器URL长度限制加上OpenIdConnectAuthenticationHandler的Cookie处理逻辑冲突,咱们一步步拆解解决:
问题根源拆解
- 浏览器URL长度硬限制:虽然你已经调大了IdentityServer的
InputLengthRestrictions,但主流浏览器(Chrome/Firefox等)对URL的长度限制普遍在2000-2048字符左右。当你把1000字符的token+OIDC自带参数拼到重定向URL里,很容易触发截断,导致IdentityServer收到不完整的请求,找不到对应的signin会话Cookie,就会抛出No cookie matching signin id found,进而显示“无法确定您要登录的应用程序”。 - 参数重复追加恶性循环:你提到的“token被重复添加到请求中”,是因为
RedirectToIdentityProvider通知逻辑里没有判断参数是否已存在——如果重定向因URL过长被截断重试,每次触发都会从Query里取token再追加,进一步拉长URL,最终触发Cookie长度限制。
针对性修复方案
1. 核心修复:用短索引替代长参数传递(避免URL超限)
OIDC的LoginHint/AcrValues都是URL参数,天生不适合存超长内容。建议把长token存到客户端临时存储,只传递短索引到IdentityServer:
RedirectToIdentityProvider = n => { if (n.ProtocolMessage.RequestType == Microsoft.IdentityModel.Protocols.OpenIdConnectRequestType.AuthenticationRequest) { var token = n.Request.Query.Get("token"); if (token != null) { // 生成唯一短索引,把长token存入Owin Session var tokenIndex = Guid.NewGuid().ToString("N"); n.OwinContext.Session[tokenIndex] = token; // 仅传递短索引到IdentityServer n.ProtocolMessage.Parameters.Add("tokenIndex", tokenIndex); n.ProtocolMessage.AcrValues = "idp:CustomIdP"; } } return Task.CompletedTask; }
之后在IdentityServer端,通过这个tokenIndex从共享Session(或分布式缓存)中取出原token即可。如果是同域部署,也可以用临时Cookie传递索引。
2. 修复参数重复追加问题
在添加参数前先做存在性判断,避免重复追加:
if (token != null && !n.ProtocolMessage.Parameters.ContainsKey("token")) { // 这里替换为上面的索引传递逻辑,或保留原逻辑但做存在性校验 n.ProtocolMessage.Parameters.Add("token", token); }
3. 兜底配置:确保服务器端支持长URL
虽然浏览器限制是主因,但还是要确认服务器端配置到位:
- 客户端和IdentityServer的
Web.config中,调大请求长度和Query字符串限制:
<system.web> <httpRuntime maxRequestLength="102400" /> <!-- 允许100MB请求 --> </system.web> <system.webServer> <security> <requestFiltering> <requestLimits maxQueryString="32768" /> <!-- 允许32KB Query字符串 --> <requestLimits maxUrl="32768" /> </requestFiltering> </security> </system.webServer>
- 若参数含特殊字符,需开启
allowDoubleEscaping:
<system.webServer> <security> <requestFiltering allowDoubleEscaping="true" /> </security> </system.webServer>
4. 调整OIDC Cookie配置
确保客户端OIDC中间件的Cookie大小限制足够,避免会话Cookie超限:
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions { // 其他核心配置... CookieAuthenticationOptions = new CookieAuthenticationOptions { CookieSizeLimit = 32768, // 调整为32KB(默认4KB) SessionStore = new MemoryCacheSessionStore() // 若用分布式Session需对应配置 }, Notifications = new OpenIdConnectAuthenticationNotifications { RedirectToIdentityProvider = n => { // 你的逻辑... return Task.CompletedTask; } } });
验证步骤
- 先修复参数重复追加问题,测试长token是否还会被重复添加;
- 替换为短索引传递逻辑,测试登录流程是否正常;
- 用Chrome开发者工具的Network面板抓包,确认重定向URL长度未超过2000字符;
- 查看IdentityServer日志,确认收到的请求参数完整。
内容的提问来源于stack exchange,提问作者Florian K
相关产品推荐
相关产品推荐

