Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot resolve PersistedGrantDbContext when using Aspire. #1520

Open
Vampire2008 opened this issue Dec 17, 2024 · 2 comments
Open

Cannot resolve PersistedGrantDbContext when using Aspire. #1520

Vampire2008 opened this issue Dec 17, 2024 · 2 comments

Comments

@Vampire2008
Copy link

Which version of Duende IdentityServer are you using?
7.0.8

Which version of .NET are you using?
.NET 9.0

Describe the bug
When adding PersistedGrantDbContext using Aspire extension OperationalStore cannot be resolve it.

To Reproduce
IndentityServerWithAspire.zip

Expected behavior

Maybe add some option to AddOperationalStore to skip adding DbContext to DI. So it should use from Aspire.

@StuFrankish
Copy link

Hi @Vampire2008 👋

Just interested to know if there's a particular reason you've chosen to configure the DB Contexts that way?
I also have an Aspire hosted solution, but I'm setting up connections for the stores using the options available in the builder extension methods - rather than explicit calls to builder.AddSqlServerDbContext<T>("...");

I don't know if that should work, but it's not a way I've configured, or seen IdentityServer configured before.

Here's a link to where I configure my setup - it may help;
https://github.com/StuFrankish/AspireForIdentityServer.IdentityServer/Extensions/WebApplicationBuilderExtensions.cs

The important bit is here though;

builder.Services.AddIdentityServer(options =>
{
    // Allow unregistered redirect URIs for PAR clients
    options.PushedAuthorization.AllowUnregisteredPushedRedirectUris = true;

    options.Events.RaiseErrorEvents = true;
    options.Events.RaiseInformationEvents = true;
    options.Events.RaiseFailureEvents = true;
    options.Events.RaiseSuccessEvents = true;

    // see https://docs.duendesoftware.com/identityserver/v6/fundamentals/resources/
    options.EmitStaticAudienceClaim = true;
})
    .AddConfigurationStore(options =>
    {
        options.ConfigureDbContext = builder => builder.UseSqlServer(connectionStrings.SqlServer, sql => sql.MigrationsAssembly(migrationsAssembly));
    })
    .AddOperationalStore(options =>
    {
        options.ConfigureDbContext = builder => builder.UseSqlServer(connectionStrings.SqlServer, sql => sql.MigrationsAssembly(migrationsAssembly));
    })
    .AddServerSideSessions()
    .AddTestUsers(TestUsers.Users);

You're more than welcome to clone the repo and have a play about - just be aware it's very "preview" heavy so things may or may not work as expected.

@Vampire2008
Copy link
Author

I am experimenting in my pet project. I assume that adding DbContext in Aspire way builder.AddSqlServerDbContext<T>("..."); is better because it also make additional configuring (add pooling, add resilience, etc). But also I assume that someone can has it's own reasons to do it in that way.
IdentityServer as component should support many ways to confgiure DbContext to meet customers needs.

Also I found a workaround:

builder.Services
    .AddIdentityServer()
    .AddConfigurationStore(options => options.EnablePooling = true)
    .AddOperationalStore(options => options.EnablePooling = true);

With EnablePooling IdentityServer tries to add DbContext pool, but it already exists from Aspire and it works.

Also about your example. I don't configure migration assembly in main IdentyServer project. Main project shouldn't do any DDL operation. For develop and testing I use dedicated console project to migrate and seed DBs. For production way recomended to generate SQL script, review it and execute on DB server.
For tesing in Aspire I maked next code:

var sql = builder.AddSqlServer("sql1")
    .AddDatabase("IdentityDb");

var identityServer = builder.AddProject<Projects.IdentityServer>("identityServer")
    .WithExternalHttpEndpoints()
    .WithReference(sql);

if (builder.Environment.IsDevelopment())
{
    var seeder = builder.AddProject<Projects.DatabaseSeeder>("seeder")
        .WithReference(sql)
        .WaitFor(sql);

    identityServer.WaitForCompletion(seeder);
}
else
{
    identityServer.WaitFor(sql);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants