Identityserver4: After restarting server a valid refresh token is not getting the new token

Created on 18 Oct 2016  路  20Comments  路  Source: IdentityServer/IdentityServer4

I am facing the problem after restarting server a valid refresh token is not getting the new token. I have published both api and server on IIS10.

question

Most helpful comment

I have done it, I have my own Configuration schema in DB for holding configuration data(clients, scopes and users) and only one table of PersistedGrants to hold persisted grants.

All 20 comments

@leo9223

You had DI IPersistedGrantStore ?

how are you storing your refresh tokens?

@xyting no I didn't DI IPersistedGrantStore

@leastprivilege storing in local SharedPrefrences in android it stores like KeyValuePair.

by the way after restarting the server just refresh token not works if its valid. But if access token is valid it works.

I meant how do you store them in IdentityServer? They will not be automagically persisted - you need to do some work for that.

Sorry Sir,
I literally don't know about storing tokens in IdentityServer?
I didn't do anything for storing them explicitly.
I just followed your samples.

Please guide me. Thank you

If you are still using the In-Memory stores (e.g. AddInMemoryPersistedGrants or AddIdentityServer) then all tokens that are stored by IdentityServer will be lost upon application restart. Tokens that are stored like this are: refresh tokens, reference tokens, consent and authorization codes.

If you want these tokens to persist across deployments then you need to use the EntityFramework implementation or something similar (see: http://docs.identityserver.io/en/dev/quickstarts/8_entity_framework.html).

@scottbrady91 okay thank you sir.

here is my new ConfigureServices method
`public void ConfigureServices(IServiceCollection services)
{
string DbConnString = Configuration["DatabaseConnection:ConnectionString"];

        var cert = new X509Certificate2(Path.Combine(_environment.ContentRootPath, "Cert", "IdentityServer4cert.pfx"), "IdentityServer4cert");

        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        var builder = services.AddIdentityServer().SetSigningCredential(cert);

        builder.AddInMemoryStores();


        // Add framework services.
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(DbConnString));

        services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

        builder.Services.AddSingleton<IClientStore>(new ClientStore(DbConnString));
        builder.Services.AddSingleton<IScopeStore>(new ScopeStore(DbConnString));
        builder.Services.AddScoped<IResourceOwnerPasswordValidator, ResourceOwnerPasswordValidator>();
        builder.Services.AddSingleton<IProfileService>(new ProfileService(DbConnString));

        services.AddMvc();
    }`

What I understood is this --> builder.AddInMemoryStores(); line should be replaced with .AddConfigurationStore and .AddOperationalStore

now the scenario is I have custom tables for clients, users and scopes in sql server 2014 (configuration data)
that is working fine if I use InMemoryStores.

Now I only need to store my operational data of IdentityServer4 i.e tokens etc.

Kindly help me out how can I store operational data in sql server 2014.

any db schema for operational data ?

Yes, you need AddOperationalStore for storing tokens that should be persisted.

Otherwise you need to register implementations for IPersistedGrantStore and IPersistedGrantDbContext.

@scottbrady91 Sir is there any docs for how to Implement these interfaces?

They are interfaces, you can implement them how you want as long as you fulfill the contract.

See IdentityServer4.EntityFramework for existing implementation: https://github.com/IdentityServer/IdentityServer4.EntityFramework/blob/release/src/IdentityServer4.EntityFramework/Stores/PersistedGrantStore.cs

@scottbrady91 Sir thank you so much. It's really helpful.

Sir but I am not getting what is key, type and subjectId in PersistedGrant class?

That's not for the store to understand, only persist. If you want to see how these are used search the core repository for usages of the interfaces.

@scottbrady91 Sir can you guide me how to DI both these IPersistedGrantDbContext, IPersistedGrantStore

I am doing this way
builder.Services.AddScoped<IPersistedGrantDbContext, ApplicationDbContext>(); builder.Services.AddScoped<IPersistedGrantStore, PersistedGrantStore>();

and I guess I am doing it wrong

because constructor needs two arguments

public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, OperationalStoreOptions storeOptions) : base(options)
{
if (storeOptions == null)
throw new ArgumentNullException(nameof(storeOptions));

        `this.storeOptions = storeOptions;`
    `}`

Okay, I think we've cleared up this issue. For implementation specific questions like this I would recommend StackOverflow.

Alright Sir.

I have done it, I have my own Configuration schema in DB for holding configuration data(clients, scopes and users) and only one table of PersistedGrants to hold persisted grants.

leo, how did you solve this issue? do you have a sample code?

Leo can you share your solution?

leo, how did you solve this issue? do you have a sample code?

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings