ComponentSpace

Forums



Custom ISSOSessionStore Issue


Custom ISSOSessionStore Issue

Author
Message
AlanRennick
AlanRennick
New Member
New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)

Group: Forum Members
Posts: 4, Visits: 14
I have implemented a simple custom ISSOSessionStore.
My class inherits from AbstractSSOSessionStore and seems to work as far as saving and loading the session state.

The problem that I am having is when I call InitiateSSO() for the second time.

The first call works because it calls the Save() method of the custom session store.
The second call fails with the below error message. In this instance it calls the Load() method of the custom session store and this seems to return the session state successfully.

Unable to cast object of type 'ComponentSpace.SAML2.Data.IdentityProviderSession' to type 'ComponentSpace.SAML2.Data.SAMLConfigurationState'.

[InvalidCastException: Unable to cast object of type 'ComponentSpace.SAML2.Data.IdentityProviderSession' to type 'ComponentSpace.SAML2.Data.SAMLConfigurationState'.] ComponentSpace.SAML2.SAMLController.LoadSAMLConfigurationState() in C:\Sandboxes\ComponentSpace\SAMLv20\Library\SAMLController.cs:41 ComponentSpace.SAML2.InternalSAMLIdentityProvider..ctor() in C:\Sandboxes\ComponentSpace\SAMLv20\Library\InternalSAMLIdentityProvider.cs:781 ComponentSpace.SAML2.SAMLIdentityProvider.InitiateSSO(HttpResponse httpResponse, String userName, IDictionary`2 attributes, String authnContext, String relayState, String partnerSP, String assertionConsumerServiceUrl) in C:\Sandboxes\ComponentSpace\SAMLv20\Library\SAMLIdentityProvider.cs:638...

Here is my custom session store code (simplified but behaving exactly the same as the full code). Should I be doing something with the 'type' parameter passed into the Load() method?

public class SAML20CustomSessionStore : AbstractSSOSessionStore
  {
   public SAML20CustomSessionStore()
   {
   }

   public override object Load(Type type)
   {
    var sessionSerialized = HttpContext.Current.Session["SAML20CustomSessionStore"];
    if (string.IsNullOrEmpty(sessionSerialized))
    {
      return null;
    }
    return Deserialize(Convert.FromBase64String(sessionSerialized));
   }

   public override void Save(object ssoSession)
   {
    HttpContext.Current.Session["SAML20CustomSessionStore"] = Convert.ToBase64String(Serialize(ssoSession));
   }
  }

Any ideas??
ComponentSpace
ComponentSpace
ComponentSpace Development
ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)

Group: Administrators
Posts: 3.2K, Visits: 11K
I can't see any obvious issues in your code.
Please enable SAML trace and send the generated log file as an email attachment to [email protected] mentioning your forum post.
https://www.componentspace.com/Forums/17/Enabing-SAML-Trace


Regards
ComponentSpace Development
AlanRennick
AlanRennick
New Member
New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)

Group: Forum Members
Posts: 4, Visits: 14
ComponentSpace - 2/20/2019
I can't see any obvious issues in your code.
Please enable SAML trace and send the generated log file as an email attachment to [email protected] mentioning your forum post.
https://www.componentspace.com/Forums/17/Enabing-SAML-Trace

I have sent you an email with the trace log attached as you requested.

I should add that when we use the built in ‘DatabaseSSOSessionStore’ everything works as expected.
Unfortunately we cannot use the ‘DatabaseSSOSessionStore’ in our production environments as the web servers have no direct access to the database servers (due to Corporate Security Directives/Policies).

Regards,
Alan
ComponentSpace
ComponentSpace
ComponentSpace Development
ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)

Group: Administrators
Posts: 3.2K, Visits: 11K
Hi Alan
We received your email but unfortunately there wasn't an attachment. Please send again.
In your custom SSO session store you're saving to the ASP.NET session.
We include a ComponentSpace.SAML2.Data.HttpSSOSessionStore class that stores SAML SSO session state in the ASP.NET session.
Perhaps you could use this instead of the custom store.

Regards
ComponentSpace Development
AlanRennick
AlanRennick
New Member
New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)

Group: Forum Members
Posts: 4, Visits: 14
ComponentSpace - 2/21/2019
Hi Alan
We received your email but unfortunately there wasn't an attachment. Please send again.
In your custom SSO session store you're saving to the ASP.NET session.
We include a ComponentSpace.SAML2.Data.HttpSSOSessionStore class that stores SAML SSO session state in the ASP.NET session.
Perhaps you could use this instead of the custom store.

Email resent.

We did try the 'HttpSSOSessionStore' but this doesn't work either (possibly due to our custom ASP.NET Session Provider which uses a centralized session database). With the 'HttpSSOSessionStore' we get the following error on the second call to 'InitiateSSO()';

Unable to cast object of type 'System.String' to type 'ComponentSpace.SAML2.Data.IdentityProviderSession'.

[InvalidCastException: Unable to cast object of type 'System.String' to type 'ComponentSpace.SAML2.Data.IdentityProviderSession'.] ComponentSpace.SAML2.InternalSAMLIdentityProvider.LoadIdentityProviderSession() in C:\Sandboxes\ComponentSpace\SAMLv20\Library\InternalSAMLIdentityProvider.cs:175 ComponentSpace.SAML2.SAMLIdentityProvider.InitiateSSO(HttpResponse httpResponse, String userName, IDictionary`2 attributes, String authnContext, String relayState, String partnerSP, String assertionConsumerServiceUrl) in C:\Sandboxes\ComponentSpace\SAMLv20\Library\SAMLIdentityProvider.cs:638

In fact the only stores that work are the 'DatabaseSSOSessionStore' (which we cannot use it for the reason stated in my previous post) and the 'InMemorySSOSessionStore' which we are using for now but our Solutions Architect prefers the use of our centralized session database.

Regards,
Alan


ComponentSpace
ComponentSpace
ComponentSpace Development
ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)

Group: Administrators
Posts: 3.2K, Visits: 11K
Thanks. The log was received.
This is strange. I tried the HttpSSOSessionStore without any issues.
It's possible your custom ASP.NET session provider is causing us issues but you would hope that's sufficiently abstracted away by ASP.NET to not be the case.
The HttpSSOSessionStore certainly works if the ASP.NET session is stored in a SQL Server database (ie SQLServer mode rather than InProc mode).
I may have to send you an update with more debug logging.
I'll contact you by email.
I do see an issue with your custom implementation which explains why you're getting an InvalidCastException.
The "SAML20CustomSessionStore" session key is being use to store all types of SAML session objects.
Instead of using this directly, you should call the CreateSessionIDForType method in the base class.
This combines your session ID (in your case "SAML20CustomSessionStore") with the object type.
Therefore SAML session objects have unique session keys.

Regards
ComponentSpace Development
AlanRennick
AlanRennick
New Member
New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)New Member (5 reputation)

Group: Forum Members
Posts: 4, Visits: 14
ComponentSpace - 2/23/2019
Thanks. The log was received.
This is strange. I tried the HttpSSOSessionStore without any issues.
It's possible your custom ASP.NET session provider is causing us issues but you would hope that's sufficiently abstracted away by ASP.NET to not be the case.
The HttpSSOSessionStore certainly works if the ASP.NET session is stored in a SQL Server database (ie SQLServer mode rather than InProc mode).
I may have to send you an update with more debug logging.
I'll contact you by email.
I do see an issue with your custom implementation which explains why you're getting an InvalidCastException.
The "SAML20CustomSessionStore" session key is being use to store all types of SAML session objects.
Instead of using this directly, you should call the CreateSessionIDForType method in the base class.
This combines your session ID (in your case "SAML20CustomSessionStore") with the object type.
Therefore SAML session objects have unique session keys.

Thanks Mitchell,

That’s exactly what I was looking for.
I knew it had to have something to do with Type but I couldn’t find any reference to using ‘ssoSession.GetType()’ in the Save method or how to use ‘type’ in the Load method.
The custom SSO session store is now functioning correctly. My modified code is as follows;

  public override object Load(Type type)
   {
    string sessionObjectKey = CreateSessionIDForType(type);
    var sessionSerialized = Guard.GetValue(HttpContext.Current.Session[sessionObjectKey], string.Empty);
    return string.IsNullOrEmpty(sessionSerialized) ? null : Deserialize(Convert.FromBase64String(sessionSerialized));
   }

   public override void Save(object ssoSession)
   {
    string sessionObjectKey = CreateSessionIDForType(ssoSession.GetType());
    HttpContext.Current.Session[sessionObjectKey] = Convert.ToBase64String(Serialize(ssoSession));
   }

Regards,
Alan 


ComponentSpace
ComponentSpace
ComponentSpace Development
ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)

Group: Administrators
Posts: 3.2K, Visits: 11K
Thanks Alan for the update. I’m glad it’s now working.

Regards
ComponentSpace Development
GO


Similar Topics


Execution: 0.000. 2 queries. Compression Enabled.
Login
Existing Account
Email Address:


Password:


Select a Forum....












Forums, Documentation & Knowledge Base - ComponentSpace


Search