Search code examples
openiddict

OpenIddict - Refresh token flow causes entity error when using custom key


When testing the refresh token flow, I get the following error when using the overloaded signature that specifies a custom key for the UseOpenIddict method (in this case ).

InvalidOperationException: The entity type 'OpenIddictAuthorization' was not found. Ensure that the entity type has been added to the model.

What's interesting is that if I don't use the overloaded method to use int as the primary key, it works correctly and I receive the refresh token. It's only when I use the overload that I receive this error.

Here is the context declaration in startup

public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            services.AddDbContext<RouteManagerContext>(options =>
            {
                options.UseSqlServer(AppSettings.RouteManagerContext);
                options.UseOpenIddict<int>();
            });
            services.AddIdentity<ApplicationUser, ApplicationRole>().AddEntityFrameworkStores<RouteManagerContext>().AddDefaultTokenProviders();
            services.Configure<IdentityOptions>(options =>
            {
                options.ClaimsIdentity.UserNameClaimType = OpenIdConnectConstants.Claims.Name;
                options.ClaimsIdentity.UserIdClaimType = OpenIdConnectConstants.Claims.Subject;
                options.ClaimsIdentity.RoleClaimType = OpenIdConnectConstants.Claims.Role;
            });
            services.AddOpenIddict(options =>
            {
                options.AddEntityFrameworkCoreStores<RouteManagerContext>();
                options.AddMvcBinders();
                options.EnableTokenEndpoint("/connect/token");
                options.AllowPasswordFlow()
                    .AllowRefreshTokenFlow()
                    .SetAccessTokenLifetime(TimeSpan.FromMinutes(1))
                    .SetRefreshTokenLifetime(TimeSpan.FromMinutes(20160))
                options.DisableHttpsRequirement();
            });
            services.AddAuthentication()
                .AddOAuthValidation()
                .AddFacebook(o => { o.ClientId = AppSettings.FacebookAppID; o.ClientSecret = AppSettings.FacebookAppSecret; });
            services.AddDocumentation(AppSettings);
        }

and here is my context

public class RouteManagerContext : IdentityDbContext<ApplicationUser, ApplicationRole, int>
{
    public RouteManagerContext(DbContextOptions<RouteManagerContext> options) : base(options)  { }
    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
    }
}

The application seems to be configured correctly as I have all the tables in the database that openiddict needs: Applications, Authorizations, Tokens, etc...

All the examples seem to be configured the same way. Any ideas?


Solution

  • By calling options.UseOpenIddict<int>();, you're asking Entity Framework Core to use the default OpenIddict entities but with a custom key type (int instead of string).

    Yet, you're also using services.AddOpenIddict(), that configures OpenIddict with the default entities and the default key type. When the Entity Framework Core stores are called by OpenIddict, the expected entities can't be found in the context since their generic definition is different.

    To fix the inconsistency, use services.AddOpenIddict<int>().