在我 OpenIdConnectAuthenticationOptions
我设置 OpenIdConnectAuthenticationNotifications
RedirectToIdentityProvider
它看起来像这样:
RedirectToIdentityProvider = n =>
{
if (n.ProtocolMessage.RequestType == Microsoft.IdentityModel.Protocols.OpenIdConnectRequestType.AuthenticationRequest)
{
n.ProtocolMessage.LoginHint = "LoginHint";
n.ProtocolMessage.AcrValues = "idp:CustomIdProvider";
}
return Task.FromResult(0);
}
在这个例子中,我能够收到LoginHint,一切正常 .
现在,如果我将 LoginHint
设置为大约1000个字符长的内容(对于 AcrValues
也是如此),IdentityServer会显示一条错误消息:
确定您要登录的应用程序时出错 . 返回应用程序,然后重试 .
和 logs 显示此消息:
找不到与cookie匹配的登录ID
仅当 LoginHint
(或 AcrValues
)达到一定大小时才会发生这种情况
在存储cookie或阅读cookie时似乎存在问题,可能它们很大
我已尝试/配置的内容:
对于客户端和服务器都是 Web Config (according to this answer所有这些值应该足够高,我会在它工作时将它们减少到适当的值):
<system.web>
<httpRuntime targetFramework="4.6.1" maxUrlLength="109990" maxQueryStringLength="100000" maxRequestLength="256000" />
</system.web>
<!--...-->
<requestFiltering>
<requestLimits maxQueryString="100000" maxAllowedContentLength="1073741824" />
</requestFiltering>
InputLengthRestrictions 中的 InputLengthRestrictions (再次值应该足够):
InputLengthRestrictions = new InputLengthRestrictions
{
UserName = 51200,
AcrValues = 51200,
LoginHint = 51200
}
这是此问题的后续问题:将自定义参数发送到外部身份提供商
EDIT:
有关我的结构的更多信息:
我的客户端收到一个令牌作为查询参数,这可能很长(大约900个字符) .
客户端现在使用以下选项重定向到IdentityServer: app.UseOpenIdConnectAuthentication(options);
Clients Startup.cs:
RedirectToIdentityProvider = n =>
{
if (n.ProtocolMessage.RequestType == Microsoft.IdentityModel.Protocols.OpenIdConnectRequestType.AuthenticationRequest)
{
var token = n.Request.Query.Get("token");
if (token != null)
{
n.ProtocolMessage.Parameters.Add("token", token);
n.ProtocolMessage.AcrValues = "idp:CustomIdP";
}
}
return Task.FromResult(0);
}
options
的其余部分非常基本
在我的IdentityServer上,我配置了 AuthenticationOptions
' IdentityProviders
-Property,正如您在我的IdServer配置的摘录中所看到的那样,我还将 InputLengthRestrictions
设置为一个较高的值,只是为了安全:
IdentityServer Startup.cs:
IdentityServerOptions options = new IdentityServerOptions
{
InputLengthRestrictions = new InputLengthRestrictions
{
RedirectUri = 51200,
AcrValues = 51200,
LoginHint = 51200
},
AuthenticationOptions = new AuthenticationOptions {
CookieOptions = new IdentityServer3.Core.Configuration.CookieOptions
{
SessionStoreProvider = new SessionStoreProvider()
},
IdentityProviders = ConfigureIdentityProviders,
}
};
idsrvApp.UseIdentityServer(options);
然后我配置我的IdentityProviders,我的IdentityProvider使用来自 Clients Startup.cs 中指定的参数的令牌 . 这适用于短令牌,所有内容都应该被调用 .
But 如果令牌很长,它甚至都没有那么远 . 我的猜测是问题的根源在于 OpenIdConnectAuthenticationHandler
编辑2
为什么限制命中如此之快:
显然,我的令牌被添加两次到IdentityServer的请求 .
由于这个原因,cookie的限制很快就达到了 .
Clients Startup.cs:
RedirectToIdentityProvider = n =>
{
if (n.ProtocolMessage.RequestType == Microsoft.IdentityModel.Protocols.OpenIdConnectRequestType.AuthenticationRequest)
{
var token = n.Request.Query.Get("token");
if (token != null)
{
n.ProtocolMessage.Parameters.Add("token", token);
n.ProtocolMessage.AcrValues = "idp:CustomIdP";
}
}
return Task.FromResult(0);
}
在这里,我从QueryString中获取 token . 但我在这里错过的是, n.ProtocolMessage
已包含 RequestUri
作为State参数,其中包含 token . 因此令牌被发送两次到IdentityServer . 如果我从 state
-Parameter中移除令牌(这是正确的事情,因为我在重定向时不需要它)并将其添加为 AcrValue
它会按预期将其发送到IdentityServer .
但问题仍然存在 .
1 回答
我不能确定,但是,这听起来可能是最大的cookie大小问题 .
Cookie只能在most browsers中存储4096个字节,如果cookie以UTF-32存储,那么1024个字符将会take up all of that space并且您的cookie将被截断 .
您可能想尝试覆盖AuthenticationOptions中的一个CookieOptions属性 .
在
CookieOptions
类中,您可以提供IAuthenticationSessionStoreProvider . 根据对该属性的评论,它可能是您正在寻找的解决方案,至少您可以调试出错的地方 .IAuthenticationSessionStoreProvider没有默认实现,但您可以查看它在AuthenticationSessionStoreWrapper中的使用方式
如果添加提供程序,它将被包含在
AuthenticationSessionStoreWrapper
中: