IdentityServer / IdentityServer3.EntityFramework

EntityFramework persistence layer for IdentityServer3
Apache License 2.0
68 stars 97 forks source link

Property 'Expiry' on class 'Token' returned as string instead of DatetimeOffset on Mono #116

Open afboteros opened 8 years ago

afboteros commented 8 years ago

We are getting the following error when authenticating a client on IdentityServer on Mono:

21:08 [ERR] ()
 Unhandled exception
System.InvalidOperationException: The 'Expiry' property on 'Token' could not be set to a 'System.String' value. You must set this property to a non-null value of type 'System.DateTimeOffset'.
  at System.Data.Entity.Core.Common.Internal.Materialization.Shaper+ErrorHandlingValueReader`1[T].GetValue (System.Data.Common.DbDataReader reader, Int32 ordinal) <0x424021f0 + 0x001bb> in <filename unknown>:0
  at System.Data.Entity.Core.Common.Internal.Materialization.Shaper.GetPropertyValueWithErrorHandling[TProperty] (Int32 ordinal, System.String propertyName, System.String typeName) <0x42401ee0 + 0x0006f> in <filename unknown>:0
  at (wrapper dynamic-method) System.Object:lambda_method (System.Runtime.CompilerServices.Closure,System.Data.Entity.Core.Common.Internal.Materialization.Shaper)
  at System.Data.Entity.Core.Common.Internal.Materialization.Shaper.HandleEntityAppendOnly[TEntity] (System.Func`2 constructEntityDelegate, System.Data.Entity.Core.EntityKey entityKey, System.Data.Entity.Core.Metadata.Edm.EntitySet entitySet) <0x421a38c0 + 0x0012f> in <filename unknown>:0
  at (wrapper dynamic-method) System.Object:lambda_method (System.Runtime.CompilerServices.Closure,System.Data.Entity.Core.Common.Internal.Materialization.Shaper)
  at System.Data.Entity.Core.Common.Internal.Materialization.Coordinator`1[T].ReadNextElement (System.Data.Entity.Core.Common.Internal.Materialization.Shaper shaper) <0x42152370 + 0x00126> in <filename unknown>:0
  at System.Data.Entity.Core.Common.Internal.Materialization.Shaper`1+SimpleEnumerator+<MoveNextAsync>d__4[T].MoveNext () <0x4236e690 + 0x0028e> in <filename unknown>:0
--- End of stack trace from previous location where exception was thrown ---

Looking for the error trace we found that EntityFramework on Mono is returning a nvarchar type when querying the Tokens table of OperationalDbContext that is registered to the factory on Startup instead of a DatetimeOffset type.

Any possible workarround for this?

Thanks.

brockallen commented 8 years ago

Perhaps something on Mono doesn't support/handle DateTimeOffset?

afboteros commented 8 years ago

Is possibly a Mono bug, according to this bug report: https://bugzilla.xamarin.com/show_bug.cgi?id=39116

Any possible workaround on the IdSrv3 side, any possible way to override the functionality related to that Expiry property?

Thanks.

brockallen commented 8 years ago

I know this is not ideal, but you can always build your own implementation of the various IXxxStore interfaces and change to DateTime. Perhaps even search for others that have already done this.

v1ct0rv commented 8 years ago

Hi, any reason to use DateTimeOffset instead of DateTime?

tstone84 commented 8 years ago

We are running into a similar issue when using MySQL as the backend database instead of MSSQL. MySQL doesn't have a corresponding data type for DateTimeOffset. Is there any way to use a different datatype to allow more support across RDBMSs?

"ExceptionMessage": "Schema specified is not valid. Errors: \r\n(79,12) : error 2019: Member Mapping specified is not valid. The type 'Edm.DateTimeOffset[Nullable=True,DefaultValue=,Precision=]' of member 'Expiration' in type 'PowerPlan.IdentityProvider.Models.ClientSecret' is not compatible with 'MySql.timestamp[Nullable=True,DefaultValue=,Precision=0]' of member 'Expiration' in type

brockallen commented 8 years ago

It's most likely because it's a date time offset. Does the EF layer on Mono support that? I don't think MySql does.

tstone84 commented 8 years ago

@brockallen Yes, I understood that, but is there any chance of this being changed to something that is more widely supported?

brockallen commented 8 years ago

We have done that in IdentityServer4: https://github.com/IdentityServer/IdentityServer4/issues/222

As for IdentityServer3 -- it would be a major (breaking) change. In the meantime, the beat approach would be to implement your own stores and map to what your DB supports. I know this is not ideal. If you search around, perhaps someone has already done this.

nicholi commented 8 years ago

I made a fork to handle the DateTimeOffset changes for EF and MySQL. I don't use it with Mono, but I don't see that being an issue.

https://github.com/Nicholi/IdentityServer3.EntityFramework.MySql/tree/mydev There aren't too many modifications, most of the other stuff was just related to updating to newer nuget restore methods. Glad to hear we don't have DateTimeOffset for Ids4.