Refresh Flow with Guid for key of Identity entities
See original GitHub issueHi, I used the same approach as described in example here https://github.com/openiddict/openiddict-samples/tree/dev/samples/RefreshFlow, but instead of string key of Identity entity I have Guid:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, IdentityRole<Guid>, Guid, IdentityUserClaim<Guid>, ApplicationUserRole, IdentityUserLogin<Guid>, IdentityRoleClaim<Guid>, IdentityUserToken<Guid>>
{
public ApplicationDbContext(DbContextOptions options) : base(options)
{
}
}
My configuration looks like:
services.AddIdentity<ApplicationUser, IdentityRole<Guid>>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.Configure<IdentityOptions>(options =>
{
options.User.RequireUniqueEmail = true;
options.Password.RequireDigit = true;
options.Password.RequiredLength = 6;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = true;
options.Password.RequireLowercase = true;
options.ClaimsIdentity.UserNameClaimType = OpenIdConnectConstants.Claims.Email;
options.ClaimsIdentity.UserIdClaimType = OpenIdConnectConstants.Claims.Subject;
options.ClaimsIdentity.RoleClaimType = OpenIdConnectConstants.Claims.Role;
});
services.AddOpenIddict()
.AddCore(options =>
{
options.UseEntityFrameworkCore()
.UseDbContext<ApplicationDbContext>()
.ReplaceDefaultEntities<Guid>();
})
.AddServer(options =>
{
options.UseMvc();
options.EnableTokenEndpoint("/connect/token");
options.AllowPasswordFlow()
.AllowRefreshTokenFlow()
.AcceptAnonymousClients();
options.DisableHttpsRequirement();
options.SetRefreshTokenLifetime(TimeSpan.FromDays(2));
options.RegisterClaims(CustomClaimTypes.Country);
options.RegisterClaims(CustomClaimTypes.SoftwareCode);
options.RegisterScopes(
OpenIdConnectConstants.Scopes.OpenId,
OpenIdConnectConstants.Scopes.Email,
OpenIdConnectConstants.Scopes.OfflineAccess,
OpenIddictConstants.Scopes.Roles);
})
.AddValidation();
Angular Client and Authorization controller looks the same, as in example mentioned above, and Authorization (Password Flow) works good, but when application tries to refresh token it throws an error. Here is a log with stack:
2019-08-09T14:36:29.0719101+02:00 0HLOSOOJG1R7N:00000005 [INF] The token request was successfully validated. (d7e51e65)
2019-08-09T14:36:29.1861943+02:00 0HLOSOOJG1R7N:00000005 [INF] Entity Framework Core "2.2.6-servicing-10079" initialized '"ApplicationDbContext"' using provider '"Microsoft.EntityFrameworkCore.SqlServer"' with options: "MigrationsAssembly=My.Api " (9958f5bb)
2019-08-09T14:36:29.3450762+02:00 0HLOSOOJG1R7N:00000005 [INF] Executed DbCommand ("77"ms) [Parameters=["@__identifier='?' (DbType = Guid)"], CommandType='Text', CommandTimeout='30']"
""SELECT TOP(1) [token].[Id], [token].[ApplicationId], [token].[AuthorizationId], [token].[ConcurrencyToken], [token].[CreationDate], [token].[ExpirationDate], [token].[Payload], [token].[Properties], [token].[ReferenceId], [token].[Status], [token].[Subject], [token].[Type], [token.Authorization].[Id], [token.Authorization].[ApplicationId], [token.Authorization].[ConcurrencyToken], [token.Authorization].[Properties], [token.Authorization].[Scopes], [token.Authorization].[Status], [token.Authorization].[Subject], [token.Authorization].[Type], [token.Application].[Id], [token.Application].[ClientId], [token.Application].[ClientSecret], [token.Application].[ConcurrencyToken], [token.Application].[ConsentType], [token.Application].[DisplayName], [token.Application].[Permissions], [token.Application].[PostLogoutRedirectUris], [token.Application].[Properties], [token.Application].[RedirectUris], [token.Application].[Type]
FROM [OpenIddictTokens] AS [token]
LEFT JOIN [OpenIddictAuthorizations] AS [token.Authorization] ON [token].[AuthorizationId] = [token.Authorization].[Id]
LEFT JOIN [OpenIddictApplications] AS [token.Application] ON [token].[ApplicationId] = [token.Application].[Id]
WHERE [token].[Id] = @__identifier" (0723d8ff)
2019-08-09T14:36:29.6458786+02:00 0HLOSOOJG1R7N:00000005 [ERR] An exception occurred while iterating over the results of a query for context type '"My.Data.ApplicationDbContext"'."
""System.InvalidCastException: Unable to cast object of type 'System.Data.SqlTypes.SqlString' to type 'System.Data.SqlTypes.SqlGuid'.
at System.Data.SqlClient.SqlBuffer.get_SqlGuid()
at System.Data.SqlClient.SqlDataReader.GetGuid(Int32 i)
at lambda_method(Closure , DbDataReader )
at Microsoft.EntityFrameworkCore.Storage.Internal.TypedRelationalValueBufferFactory.Create(DbDataReader dataReader)
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.BufferlessMoveNext(DbContext _, Boolean buffer, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.MoveNext(CancellationToken cancellationToken)
at System.Linq.AsyncEnumerable.SelectEnumerableAsyncIterator`2.MoveNextCore(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\Select.cs:line 106
at System.Linq.AsyncEnumerable.AsyncIterator`1.MoveNext(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\AsyncIterator.cs:line 98
at System.Linq.AsyncEnumerable.FirstOrDefault_[TSource](IAsyncEnumerable`1 source, CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\First.cs:line 144
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.TaskResultAsyncEnumerable`1.Enumerator.MoveNext(CancellationToken cancellationToken)
at System.Linq.AsyncEnumerable.SelectEnumerableAsyncIterator`2.MoveNextCore(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\Select.cs:line 106
at System.Linq.AsyncEnumerable.AsyncIterator`1.MoveNext(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\AsyncIterator.cs:line 98
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext(CancellationToken cancellationToken)" (f5c7ac34)
System.InvalidCastException: Unable to cast object of type 'System.Data.SqlTypes.SqlString' to type 'System.Data.SqlTypes.SqlGuid'.
at System.Data.SqlClient.SqlBuffer.get_SqlGuid()
at System.Data.SqlClient.SqlDataReader.GetGuid(Int32 i)
at lambda_method(Closure , DbDataReader )
at Microsoft.EntityFrameworkCore.Storage.Internal.TypedRelationalValueBufferFactory.Create(DbDataReader dataReader)
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.BufferlessMoveNext(DbContext _, Boolean buffer, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.MoveNext(CancellationToken cancellationToken)
at System.Linq.AsyncEnumerable.SelectEnumerableAsyncIterator`2.MoveNextCore(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\Select.cs:line 106
at System.Linq.AsyncEnumerable.AsyncIterator`1.MoveNext(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\AsyncIterator.cs:line 98
at System.Linq.AsyncEnumerable.FirstOrDefault_[TSource](IAsyncEnumerable`1 source, CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\First.cs:line 144
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.TaskResultAsyncEnumerable`1.Enumerator.MoveNext(CancellationToken cancellationToken)
at System.Linq.AsyncEnumerable.SelectEnumerableAsyncIterator`2.MoveNextCore(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\Select.cs:line 106
at System.Linq.AsyncEnumerable.AsyncIterator`1.MoveNext(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\AsyncIterator.cs:line 98
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext(CancellationToken cancellationToken)
2019-08-09T14:36:29.6694893+02:00 0HLOSOOJG1R7N:00000005 [ERR] An exception occurred while iterating over the results of a query for context type '"My.Data.ApplicationDbContext"'."
""System.InvalidCastException: Unable to cast object of type 'System.Data.SqlTypes.SqlString' to type 'System.Data.SqlTypes.SqlGuid'.
at System.Data.SqlClient.SqlBuffer.get_SqlGuid()
at System.Data.SqlClient.SqlDataReader.GetGuid(Int32 i)
at lambda_method(Closure , DbDataReader )
at Microsoft.EntityFrameworkCore.Storage.Internal.TypedRelationalValueBufferFactory.Create(DbDataReader dataReader)
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.BufferlessMoveNext(DbContext _, Boolean buffer, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.MoveNext(CancellationToken cancellationToken)
at System.Linq.AsyncEnumerable.SelectEnumerableAsyncIterator`2.MoveNextCore(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\Select.cs:line 106
at System.Linq.AsyncEnumerable.AsyncIterator`1.MoveNext(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\AsyncIterator.cs:line 98
at System.Linq.AsyncEnumerable.FirstOrDefault_[TSource](IAsyncEnumerable`1 source, CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\First.cs:line 144
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.TaskResultAsyncEnumerable`1.Enumerator.MoveNext(CancellationToken cancellationToken)
at System.Linq.AsyncEnumerable.SelectEnumerableAsyncIterator`2.MoveNextCore(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\Select.cs:line 106
at System.Linq.AsyncEnumerable.AsyncIterator`1.MoveNext(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\AsyncIterator.cs:line 98
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext(CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteSingletonAsyncQuery[TResult](QueryContext queryContext, Func`2 compiledQuery, IDiagnosticsLogger`1 logger, Type contextType)" (f5c7ac34)
System.InvalidCastException: Unable to cast object of type 'System.Data.SqlTypes.SqlString' to type 'System.Data.SqlTypes.SqlGuid'.
at System.Data.SqlClient.SqlBuffer.get_SqlGuid()
at System.Data.SqlClient.SqlDataReader.GetGuid(Int32 i)
at lambda_method(Closure , DbDataReader )
at Microsoft.EntityFrameworkCore.Storage.Internal.TypedRelationalValueBufferFactory.Create(DbDataReader dataReader)
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.BufferlessMoveNext(DbContext _, Boolean buffer, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.MoveNext(CancellationToken cancellationToken)
at System.Linq.AsyncEnumerable.SelectEnumerableAsyncIterator`2.MoveNextCore(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\Select.cs:line 106
at System.Linq.AsyncEnumerable.AsyncIterator`1.MoveNext(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\AsyncIterator.cs:line 98
at System.Linq.AsyncEnumerable.FirstOrDefault_[TSource](IAsyncEnumerable`1 source, CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\First.cs:line 144
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.TaskResultAsyncEnumerable`1.Enumerator.MoveNext(CancellationToken cancellationToken)
at System.Linq.AsyncEnumerable.SelectEnumerableAsyncIterator`2.MoveNextCore(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\Select.cs:line 106
at System.Linq.AsyncEnumerable.AsyncIterator`1.MoveNext(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\AsyncIterator.cs:line 98
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext(CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteSingletonAsyncQuery[TResult](QueryContext queryContext, Func`2 compiledQuery, IDiagnosticsLogger`1 logger, Type contextType)
2019-08-09T14:36:29.7181001+02:00 0HLOSOOJG1R7N:00000005 [ERR] An unhandled exception has occurred while executing the request. (48a46595)
System.InvalidCastException: Unable to cast object of type 'System.Data.SqlTypes.SqlString' to type 'System.Data.SqlTypes.SqlGuid'.
at System.Data.SqlClient.SqlBuffer.get_SqlGuid()
at System.Data.SqlClient.SqlDataReader.GetGuid(Int32 i)
at lambda_method(Closure , DbDataReader )
at Microsoft.EntityFrameworkCore.Storage.Internal.TypedRelationalValueBufferFactory.Create(DbDataReader dataReader)
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.BufferlessMoveNext(DbContext _, Boolean buffer, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.MoveNext(CancellationToken cancellationToken)
at System.Linq.AsyncEnumerable.SelectEnumerableAsyncIterator`2.MoveNextCore(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\Select.cs:line 106
at System.Linq.AsyncEnumerable.AsyncIterator`1.MoveNext(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\AsyncIterator.cs:line 98
at System.Linq.AsyncEnumerable.FirstOrDefault_[TSource](IAsyncEnumerable`1 source, CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\First.cs:line 144
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.TaskResultAsyncEnumerable`1.Enumerator.MoveNext(CancellationToken cancellationToken)
at System.Linq.AsyncEnumerable.SelectEnumerableAsyncIterator`2.MoveNextCore(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\Select.cs:line 106
at System.Linq.AsyncEnumerable.AsyncIterator`1.MoveNext(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\AsyncIterator.cs:line 98
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext(CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteSingletonAsyncQuery[TResult](QueryContext queryContext, Func`2 compiledQuery, IDiagnosticsLogger`1 logger, Type contextType)
at OpenIddict.Core.OpenIddictTokenCache`1.<>c__DisplayClass11_0.<<FindByIdAsync>g__ExecuteAsync|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Threading.Tasks.ValueTask`1.get_Result()
at OpenIddict.Core.OpenIddictTokenManager`1.FindByIdAsync(String identifier, CancellationToken cancellationToken)
at OpenIddict.Core.OpenIddictTokenManager`1.OpenIddict.Abstractions.IOpenIddictTokenManager.FindByIdAsync(String identifier, CancellationToken cancellationToken)
at OpenIddict.Server.Internal.OpenIddictServerProvider.ReceiveTokenAsync(String type, String value, OpenIddictServerOptions options, OpenIdConnectRequest request, ISecureDataFormat`1 format)
at OpenIddict.Server.Internal.OpenIddictServerProvider.DeserializeRefreshToken(DeserializeRefreshTokenContext context)
at AspNet.Security.OpenIdConnect.Server.OpenIdConnectServerHandler.DeserializeRefreshTokenAsync(String token, OpenIdConnectRequest request)
at AspNet.Security.OpenIdConnect.Server.OpenIdConnectServerHandler.InvokeTokenEndpointAsync()
at AspNet.Security.OpenIdConnect.Server.OpenIdConnectServerHandler.HandleRequestAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware.InvokeCore(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
2019-08-09T14:36:29.7706829+02:00 0HLOSOOJG1R7N:00000005 [INF] Request finished in 711.4237ms 500 text/html; charset=utf-8 (791a596a)
From what I could see it calls FindByIdAsync(String identifier, CancellationToken cancellationToken)
of OpenIddict.Core.OpenIddictTokenManager
assembly, with a string identifier. Could you please advice if I’ve missed anything or this is an issue in OpenIddict.Core.OpenIddictTokenManager
?
Thanks in advance,
Issue Analytics
- State:
- Created 4 years ago
- Comments:5 (3 by maintainers)
Top GitHub Comments
Still, the exception clearly indicates that the expected type (Guid) was not the type found in the DB (string):
You should double-check the table definition, just to be sure.
Good to hear it’s working properly!