Flo*_*n K 6 c# asp.net asp.net-mvc owin identityserver3
在我的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);
}
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我能够收到LoginHint,一切正常.
现在,如果我设置LoginHint为大约1000个字符长的东西(同样的情况发生AcrValues),IdentityServer会显示一条错误消息:
确定您要登录的应用程序时出错.返回应用程序,然后重试.
并且日志显示以下消息:
找不到与cookie匹配的登录ID
这仅在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>
Run Code Online (Sandbox Code Playgroud)
InputLengthRestrictions在IdentityServerOptions(再一次的值应该是足够了):
InputLengthRestrictions = new InputLengthRestrictions
{
UserName = 51200,
AcrValues = 51200,
LoginHint = 51200
}
Run Code Online (Sandbox Code Playgroud)
这是此问题的后续问题:将自定义参数发送到外部身份提供商
编辑:
我的客户端收到一个令牌作为查询参数,这可能很长(大约900个字符).
客户端现在使用以下选项重定向到IdentityServer:app.UseOpenIdConnectAuthentication(options);
客户端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);
}
Run Code Online (Sandbox Code Playgroud)
剩下的options就是非常基本的
在我的IdentityServer上,我可以在我的IdServer配置的摘录中配置AuthenticationOptions' IdentityProviders-Property,我也设置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);
Run Code Online (Sandbox Code Playgroud)
然后我配置我的IdentityProviders,我的IdentityProvider使用来自Clients Startup.cs中指定的参数的Token. 这适用于短令牌,所有内容都应该调用.
但如果令牌很长,它甚至都没有那么远.我的猜测是问题的根源在于OpenIdConnectAuthenticationHandler
显然,我的令牌被添加两次到IdentityServer的请求.
由于这个原因,cookie的限制很快就达到了.
客户端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);
}
Run Code Online (Sandbox Code Playgroud)
在这里,我从QueryString中获取令牌.但我在这里错过的是,n.ProtocolMessage包含已经RequestUri包含令牌的状态参数.因此令牌被发送两次到IdentityServer.如果我从state-Parameter中移除令牌(这是正确的事情,因为我在重定向时不需要它)并添加它,因为AcrValue它会按预期将它发送到IdentityServer.
但问题仍然存在.
我不能确定,但是,这听起来可能是最大 cookie 大小问题。在大多数浏览器
中,Cookie 只能存储 4096 字节,如果 Cookie 以 UTF-32 存储,那么 1024 个字符将占用所有空间,并且您的 Cookie 将被截断。
您可能想尝试覆盖AuthenticationOptions中的CookieOptions属性之一。
在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; }
Run Code Online (Sandbox Code Playgroud)
IAuthenticationSessionStoreProvider 没有默认实现,但您可以查看它在AuthenticationSessionStoreWrapper内部的使用方式
AuthenticationSessionStoreWrapper如果您添加提供者,它会被包含在一个内部:
static IAuthenticationSessionStore GetSessionStore(IAuthenticationSessionStoreProvider provider)
{
return provider != null ? new AuthenticationSessionStoreWrapper(provider) : null;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
681 次 |
| 最近记录: |