Hi,
we created a small MVC project to host a saml 2.0 “fake” identity provider to run tests against. We are using this “fake” idp to tests our service provider implementation. Our “fake” IDP is based on the example project that came with the installation of the Saml Component.
Running the fake IDP project on localhost (IIS 7.5) is working (most of the time) however when deploying it to one of our development servers and testing against it we get the following exception regularly. The fake IDP seems to work for one or two requests however then it only throws these exception:
Server Error in ‘/sso-saml’ Application.
The attribute value type System.String cannot be serialized.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: ComponentSpace.SAML2.Exceptions.SAMLSerializationException: The attribute value type System.String cannot be serialized.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below. |
Stack Trace: [SAMLSerializationException: The attribute value type System.String cannot be serialized.] ComponentSpace.SAML2.Assertions.XmlAttributeValueSerializer.Serialize(XmlElement parentElement, Object attributeValue) +417 ComponentSpace.SAML2.Assertions.AttributeValue.ToXml(XmlDocument xmlDocument, IAttributeValueSerializer attributeValueSerializer) +804 ComponentSpace.SAML2.Assertions.AttributeType.ToXml(XmlElement xmlElement) +326 ComponentSpace.SAML2.Assertions.SAMLAttribute.ToXml(XmlDocument xmlDocument) +82 ComponentSpace.SAML2.Assertions.AttributeStatement.ToXml(XmlDocument xmlDocument) +210 ComponentSpace.SAML2.Assertions.SAMLAssertion.ToXml(XmlDocument xmlDocument) +840 ComponentSpace.SAML2.InternalSAMLIdentityProvider.CreateSAMLResponse(String userName, SAMLAttribute[] attributes, String statusCode, String statusMessage) +333 ComponentSpace.SAML2.InternalSAMLIdentityProvider.SendSSO(HttpResponseBase httpResponse, String userName, SAMLAttribute[] attributes, String statusCode, String statusMessage) +238 ComponentSpace.SAML2.InternalSAMLIdentityProvider.SendSSO(HttpResponseBase httpResponse, String userName, SAMLAttribute[] attributes) +27 companyname.TestServices.SSO.Saml.Controllers.SingleSignOnController.SendSamlResponse(Dictionary userAttributes, String userName) in c:\SourceCode\development\BackEnd<font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif ">companyname.TestServices.SSO.Saml\Controllers\SingleSignOnController.cs:52 companyname.TestServices.SSO.Saml.Controllers.SingleSignOnController.LoadUser(String userName) in c:\SourceCode\development\BackEnd<font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif ">companyname.TestServices.SSO.Saml\Controllers\SingleSignOnController.cs:66 lambda_method(Closure , ControllerBase , Object[] ) +127 System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary parameters) +242 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary parameters) +39 System.Web.Mvc.Async.AsyncControllerActionInvoker.b__36(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +12 System.Web.Mvc.Async.WrappedAsyncResult.CallEndDelegate(IAsyncResult asyncResult) +139 System.Web.Mvc.Async.AsyncInvocationWithFilters.b__3c() +112 System.Web.Mvc.Async.<>c__DisplayClass45.b__3e() +452 System.Web.Mvc.Async.<>c__DisplayClass30.b__2f(IAsyncResult asyncResult) +15 System.Web.Mvc.Async.<>c__DisplayClass28.b__19() +37 System.Web.Mvc.Async.<>c__DisplayClass1e.b__1b(IAsyncResult asyncResult) +241 System.Web.Mvc.Controller.b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +29 System.Web.Mvc.Async.WrappedAsyncVoid.CallEndDelegate(IAsyncResult asyncResult) +111 System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +53 System.Web.Mvc.Async.WrappedAsyncVoid.CallEndDelegate(IAsyncResult asyncResult) +19 System.Web.Mvc.MvcHandler.b__4(IAsyncResult asyncResult, ProcessRequestState innerState) +51 System.Web.Mvc.Async.WrappedAsyncVoid.CallEndDelegate(IAsyncResult asyncResult) +111 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +606 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +288 |
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.34237
We experienced the same problem on localhost already as well - however the problem is very seldom there.
It seems the component does not come along with the data in Dictionary<string, string> although we are sending the same test data in the dictionary. Sometimes it is working, sometimes not. Please help.
unfortunately i can not edit my post above to show the stacktrace in a better way.
here it is again:
[SAMLSerializationException: The attribute value type System.String cannot be serialized.]
ComponentSpace.SAML2.Assertions.XmlAttributeValueSerializer.Serialize(XmlElement parentElement, Object attributeValue) in c:\Sandboxes\ComponentSpace\SAMLv20\Library\Assertions\XmlAttributeValueSerializer.cs:39
ComponentSpace.SAML2.Assertions.AttributeValue.ToXml(XmlDocument xmlDocument, IAttributeValueSerializer attributeValueSerializer) in c:\Sandboxes\ComponentSpace\SAMLv20\Library\Assertions\AttributeValue.cs:222
ComponentSpace.SAML2.Assertions.AttributeType.ToXml(XmlElement xmlElement) in c:\Sandboxes\ComponentSpace\SAMLv20\Library\Assertions\AttributeType.cs:323
ComponentSpace.SAML2.Assertions.SAMLAttribute.ToXml(XmlDocument xmlDocument) in c:\Sandboxes\ComponentSpace\SAMLv20\Library\Assertions\SAMLAttribute.cs:117
ComponentSpace.SAML2.Assertions.AttributeStatement.ToXml(XmlDocument xmlDocument) in c:\Sandboxes\ComponentSpace\SAMLv20\Library\Assertions\AttributeStatement.cs:136
ComponentSpace.SAML2.Assertions.SAMLAssertion.ToXml(XmlDocument xmlDocument) in c:\Sandboxes\ComponentSpace\SAMLv20\Library\Assertions\SAMLAssertion.cs:659
ComponentSpace.SAML2.InternalSAMLIdentityProvider.CreateSAMLResponse(String userName, SAMLAttribute[] attributes, String statusCode, String statusMessage) in c:\Sandboxes\ComponentSpace\SAMLv20\Library\InternalSAMLIdentityProvider.cs:493
ComponentSpace.SAML2.InternalSAMLIdentityProvider.SendSSO(HttpResponseBase httpResponse, String userName, SAMLAttribute[] attributes, String statusCode, String statusMessage) in c:\Sandboxes\ComponentSpace\SAMLv20\Library\InternalSAMLIdentityProvider.cs:275
ComponentSpace.SAML2.InternalSAMLIdentityProvider.SendSSO(HttpResponseBase httpResponse, String userName, SAMLAttribute[] attributes) in c:\Sandboxes\ComponentSpace\SAMLv20\Library\InternalSAMLIdentityProvider.cs:683
companyname.TestServices.SSO.Saml.Controllers.SingleSignOnController.SendSamlResponse(Dictionary userAttributes, String userName) in c:\SourceCode\development\BackEnd\companyname.TestServices.SSO.Saml\Controllers\SingleSignOnController.cs:52
companyname.TestServices.SSO.Saml.Controllers.SingleSignOnController.LoadUser(String userName) in c:\SourceCode\development\BackEnd\companyname.TestServices.SSO.Saml\Controllers\SingleSignOnController.cs:66
lambda_method(Closure , ControllerBase , Object[] ) +127
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary parameters) +242
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary parameters) +39
System.Web.Mvc.Async.AsyncControllerActionInvoker.b__36(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +12
System.Web.Mvc.Async.WrappedAsyncResult.CallEndDelegate(IAsyncResult asyncResult) +139
System.Web.Mvc.Async.AsyncInvocationWithFilters.b__3c() +112
System.Web.Mvc.Async.<>c__DisplayClass45.b__3e() +452
System.Web.Mvc.Async.<>c__DisplayClass30.b__2f(IAsyncResult asyncResult) +15
System.Web.Mvc.Async.<>c__DisplayClass28.b__19() +37
System.Web.Mvc.Async.<>c__DisplayClass1e.b__1b(IAsyncResult asyncResult) +241
System.Web.Mvc.Controller.b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +29
System.Web.Mvc.Async.WrappedAsyncVoid.CallEndDelegate(IAsyncResult asyncResult) +111
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +53
System.Web.Mvc.Async.WrappedAsyncVoid.CallEndDelegate(IAsyncResult asyncResult) +19
System.Web.Mvc.MvcHandler.b__4(IAsyncResult asyncResult, ProcessRequestState innerState) +51
System.Web.Mvc.Async.WrappedAsyncVoid.CallEndDelegate(IAsyncResult asyncResult) +111
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +606
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +288
it seems that i could fix the problem.
unfortunately the dictionary<string, string> that you can pass to SendSSO
does not check its attributes really.
i now pass a SAMLAttributes attray, specifing the type: xs-anyType explicitlyto get its value written in between cdata tags
Could you tell me what attribute values you had in the Dictionary which produced this issue? I’d like to reproduce the issue. Thanks.
public class UserContacts
{
private const string CompanyName = “companyName”;
private const string FirstName = “firstName”;
private const string LastName = “lastName”;
private const string Address1 = “address1”;
private const string Address2 = “address2”;
private const string CountryCode = “countryCode”;
private const string Country = “country”;
private const string City = “city”;
private const string Email = “email”;
private const string RegionCode = “regionCode”;
private const string PostalCode = “postalCode”;
private const string Phone = “phone”;
private const string UpdateDateEpoch = “updateDateEpoch”;
private const string IsNewAccount = “isNewAccount”;
private const string SomeId = “someId”;
private const string ShipPrefix = “ship_”;
public static Dictionary<string, string> GetUserAttributes(string userName)
{
switch (userName.ToLower())
{
case “kalle”:
return GetKalle();
case “tobi”:
return GetTobi();
case “john”:
return GetJohnDoe();
case “hacker”:
return GetHacker();
case “blank”:
return GetBlank();
default:
return GetKalle();
}
}
private static Dictionary<string, string> GetKalle()
{
var userAttribute = new Dictionary<string, string>();
userAttribute[FirstName] = “Kalle”;
userAttribute[LastName] = “Kabowski”;
userAttribute[Address1] = “Somewherestrasse 2”;
userAttribute[CountryCode] = “DE”;
userAttribute[Country] = “Deutschland”;
userAttribute[Email] = “kalle@companyname.com”;
return userAttribute;
}
private static Dictionary<string, string> GetTobi()
{
var userAttribute = new Dictionary<string, string>();
userAttribute[SomeId] = “1234567”;
userAttribute[Email] = “krawallbruder@companyname.com”;
userAttribute[CompanyName] = “companyname”;
userAttribute[FirstName] = “Tobi”;
userAttribute[LastName] = “Krawallbruder”;
userAttribute[Address1] = “Somewherestrasse 2”;
userAttribute[Address2] = “3 Etage”;
userAttribute[RegionCode] = “IL”;
userAttribute[PostalCode] = “50935”;
userAttribute[CountryCode] = “US”;
userAttribute[Country] = “United States”;
userAttribute[City] = “Chicago”;
userAttribute[Phone] = “0221 1234556”;
userAttribute[UpdateDateEpoch] = DateTime.Now.ToString();
userAttribute[IsNewAccount] = “false”;
userAttribute[ShipPrefix + CompanyName] = “companyname 2.0”;
userAttribute[ShipPrefix + FirstName] = “Tobi 2.0”;
userAttribute[ShipPrefix + LastName] = “Krawallbruder 2.0”;
userAttribute[ShipPrefix + Address1] = “Somewherestrasse 2.0”;
userAttribute[ShipPrefix + Address2] = string.Empty;
userAttribute[ShipPrefix + RegionCode] = “ON”;
userAttribute[ShipPrefix + City] = “Ontario”;
userAttribute[ShipPrefix + PostalCode] = “50920”;
userAttribute[ShipPrefix + CountryCode] = “CA”;
userAttribute[ShipPrefix + Country] = “Canada”;
return userAttribute;
}
private static Dictionary<string, string> GetJohnDoe()
{
var userAttribute = new Dictionary<string, string>();
userAttribute[SomeId] = “1234568”;
userAttribute[Email] = “TestUser@companyname.com”;
userAttribute[CompanyName] = “companyname”;
userAttribute[FirstName] = “John”;
userAttribute[LastName] = “Doe”;
userAttribute[Address1] = “114 Long Beach Blvd”;
userAttribute[Address2] = “3 Etage”;
userAttribute[RegionCode] = “CA”;
userAttribute[City] = “Long Beach”;
userAttribute[PostalCode] = “90802”;
userAttribute[CountryCode] = “US”;
userAttribute[Country] = “United States”;
userAttribute[Phone] = “0221 1234556”;
userAttribute[UpdateDateEpoch] = DateTime.Now.ToString();
userAttribute[IsNewAccount] = “false”;
return userAttribute;
}
private static Dictionary<string, string> GetHacker()
{
var userAttribute = new Dictionary<string, string>();
userAttribute[SomeId] = “<script type="text/javascript">alert(‘someId’);”;
userAttribute[Email] = “<script type="text/javascript">alert(‘email’);”;
userAttribute[CompanyName] = “<script type="text/javascript">alert(‘company’);”;
userAttribute[FirstName] = “<script type="text/javascript">alert(‘firstname’);”;
userAttribute[LastName] = “<script type="text/javascript">alert(‘lastname’);”;
userAttribute[Address1] = “<script type="text/javascript">alert(‘address1’);”;
userAttribute[Address2] = “<script type="text/javascript">alert(‘address2’);”;
userAttribute[RegionCode] = “<script type="text/javascript">alert(‘region’);”;
userAttribute[City] = “<script type="text/javascript">alert(‘region’);”;
userAttribute[PostalCode] = “<script type="text/javascript">alert(‘postalcode’);”;
userAttribute[CountryCode] = “<script type="text/javascript">alert(‘countrycode’);”;
userAttribute[Country] = “<script type="text/javascript">alert(‘country’);”;
userAttribute[Phone] = “<script type="text/javascript">alert(‘phone’);”;
userAttribute[UpdateDateEpoch] = DateTime.Now.ToString();
userAttribute[IsNewAccount] = “false”;
return userAttribute;
}
private static Dictionary<string, string> GetBlank()
{
var userAttribute = new Dictionary<string, string>();
userAttribute[SomeId] = String.Empty;
userAttribute[Email] = String.Empty;
userAttribute[CompanyName] = String.Empty;
userAttribute[FirstName] = String.Empty;
userAttribute[LastName] = String.Empty;
userAttribute[Address1] = String.Empty;
userAttribute[Address2] = String.Empty;
userAttribute[City] = String.Empty;
userAttribute[RegionCode] = String.Empty;
userAttribute[PostalCode] = String.Empty;
userAttribute[CountryCode] = String.Empty;
userAttribute[Country] = String.Empty;
userAttribute[Phone] = String.Empty;
userAttribute[UpdateDateEpoch] = DateTime.Now.ToString();
userAttribute[IsNewAccount] = “false”;
return userAttribute;
}
}