在我的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显示错误消息:
确定您要登录的应用程序时出错。返回应用程序并重试。
并且日志会显示以下消息:
找不到符合登录ID的Cookie
这仅在LoginHint
(或AcrValues
)达到特定尺寸
存储Cookie或阅读Cookie时似乎存在问题 也许他们是大的
Web配置,所有这些值都应该足够高,我会在它工作时将它们减少到适当的值:
<system.web>
<httpRuntime targetFramework="4.6.1" maxUrlLength="109990" maxQueryStringLength="100000" maxRequestLength="256000" />
</system.web>
<!--...-->
<requestFiltering>
<requestLimits maxQueryString="100000" maxAllowedContentLength="1073741824" />
</requestFiltering>
IdentityServerOptions
中的InputLengthRestrictions (同样值也应该足够):
InputLengthRestrictions = new InputLengthRestrictions
{
UserName = 51200,
AcrValues = 51200,
LoginHint = 51200
}
以下是对此问题的跟进问题:Send a custom parameter to an external identity provider
修改
我的客户端收到一个令牌作为查询参数,可能很长(约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
&#39; IdentityProviders
- 您在我的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 中指定的参数的Token 这适用于短令牌,所有内容都应该被调用。
但如果令牌很长,它甚至不会那么远。我的猜测是问题的根源在于OpenIdConnectAuthenticationHandler
显然我的令牌被添加两次到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中获取标记。但我在这里错过的是,
n.ProtocolMessage
已包含RequestUri
状态参数,其中包含令牌。
因此令牌被发送两次到IdentityServer。如果我从state
- 参数中移除令牌(这是正确的事情,因为我不需要重定向回来)并将其添加为AcrValue
它会将其发送到IdentityServer按预期方式。
但问题仍然存在。
答案 0 :(得分:1)
我无法确定,但是,这听起来可能是最大的cookie大小问题 Cookies只能在most browsers中存储4096个字节,如果cookie以UTF-32存储,那么1024个字符将take up all of that space,并且您的cookie将被截断。
您可能想尝试覆盖CookieOptions中的AuthenticationOptions个属性之一。
在CookieOptions
课程中,您可以提供IAuthenticationSessionStoreProvider。根据对该属性的评论,它可能是您正在寻找的解决方案,至少您可以调试出错的地方。
/// <summary>
/// An optional container in which to store the identity across requests.
/// When used, only a session identifier is sent
/// to the client. This can be used to mitigate potential problems
/// with very large identities.
/// </summary>
public IAuthenticationSessionStoreProvider SessionStoreProvider { get; set; }
IAuthenticationSessionStoreProvider没有默认实现,但您可以查看它在AuthenticationSessionStoreWrapper中的使用方式
如果您添加提供商,它将被包含在AuthenticationSessionStoreWrapper
内:
static IAuthenticationSessionStore GetSessionStore(IAuthenticationSessionStoreProvider provider)
{
return provider != null ? new AuthenticationSessionStoreWrapper(provider) : null;
}