In my OpenIdConnectAuthenticationOptions
I set the OpenIdConnectAuthenticationNotifications
RedirectToIdentityProvider
It looks like this:
RedirectToIdentityProvider = n =>
{
if (n.ProtocolMessage.RequestType == Microsoft.IdentityModel.Protocols.OpenIdConnectRequestType.AuthenticationRequest)
{
n.ProtocolMessage.LoginHint = "LoginHint";
n.ProtocolMessage.AcrValues = "idp:CustomIdProvider";
}
return Task.FromResult(0);
}
In this example I am able to receive the LoginHint and everything works fine.
Now if I set the LoginHint
to something that is about 1000 characters long
(The same happens for AcrValues
), the IdentityServer shows an error message:
There is an error determining which application you are signing into. Return to the application and try again.
and the logs show this message:
No cookie matching signin id found
This only happens when the LoginHint
(or AcrValues
) reach a certain size
It seems there is a problem when storing the cookies or reading the cookies maybe they are to big
Web Config for both, client and server (according to this answer all these values should be high enough, I will reduce them to appropriate values when it's working):
<system.web>
<httpRuntime targetFramework="4.6.1" maxUrlLength="109990" maxQueryStringLength="100000" maxRequestLength="256000" />
</system.web>
<!--...-->
<requestFiltering>
<requestLimits maxQueryString="100000" maxAllowedContentLength="1073741824" />
</requestFiltering>
InputLengthRestrictions in the IdentityServerOptions
(again the values should be sufficient):
InputLengthRestrictions = new InputLengthRestrictions
{
UserName = 51200,
AcrValues = 51200,
LoginHint = 51200
}
This is a follow up question for this one: Send a custom parameter to an external identity provider
EDIT:
My client receives a token as queryparameter which can be very long(about 900 chars).
The client now redirects to the IdentityServer using following options for: 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);
}
The rest of the options
is pretty basic
On my IdentityServer I configure the AuthenticationOptions
' IdentityProviders
-Property as you can see in this excerpt of my IdServer Configuration and I also set the InputLengthRestrictions
to a high value, just to be safe:
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);
Then I configure my IdentityProviders, my IdentityProvider uses the Token from the parameter specified in the Clients Startup.cs This works fine for a short token, everything is called as it should be.
But if the token is to long it doesn't even get that far. My guess is that the root of the problem lies in the OpenIdConnectAuthenticationHandler
Apparently my token is added twice to the request to the IdentityServer.
Because of this reason the limit for the cookie is reached pretty fast.
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);
}
Here I take the token from the QueryString. But what I missed here is,
the n.ProtocolMessage
contains already the RequestUri
as State parameter which contains the token.
So the token is sent twice to the IdentityServer. If I remove the token from the state
-Parameter (which is the right thing to do, as I don't need it on redirecting back) and add it as AcrValue
it does send it to the IdentityServer as expected.
But still the question remains.
I can't be sure, but, this sounds like it may be a max cookie size problem.
Cookies can only store 4096 bytes in most browsers, and if cookies are stored in UTF-32 for example, then 1024 characters would take up all of that space and your cookie would be truncated.
You may want to try overriding one of the CookieOptions properties in the AuthenticationOptions.
In the CookieOptions
class you can provide an IAuthenticationSessionStoreProvider. According to the comment on the property it may be the solution you are looking for, at the very least you may be able to debug what is going wrong.
/// <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; }
There is no default implementation for IAuthenticationSessionStoreProvider but you can look at how it is used inside AuthenticationSessionStoreWrapper
It is wrapped up inside an AuthenticationSessionStoreWrapper
if you add a provider:
static IAuthenticationSessionStore GetSessionStore(IAuthenticationSessionStoreProvider provider)
{
return provider != null ? new AuthenticationSessionStoreWrapper(provider) : null;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With