首页 > 解决方案 > IdentityServer 4 with .net Core Identity:在 Azure 上发布代码更新会使刷新令牌无效,尽管使用了数据保护

问题描述

我已经设置了一个 IdentityServer 4 API,我在其中使用 .Net Core Identity 来管理用户。作为此设置的一部分,我使用 JWT 令牌来控制对我们 API 的访问,并结合刷新令牌在需要时更新 JWT。

在我进行代码更新并在 Azure 应用服务上重新发布之前,一切都像魅力一样。从那时起,刷新令牌不再起作用,所有用户都必须重新登录,这真的很痛苦。我在网上到处寻找,但找不到解决方案。我确实使用数据保护将密钥保存在 blob 存储中,但这似乎没有任何作用。

任何人都可以帮助我,因为我陷入了避免进行任何代码更新的情况,这样我的用户就不会感到沮丧。提前致谢。

这是我在 startup.cs 中的 ConfigureServices:

public void ConfigureServices(IServiceCollection services)
    {
        services.AddIdentity<ApplicationUser, IdentityRole>(options =>
        {
            // Default Lockout settings.
            options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
            options.Lockout.MaxFailedAccessAttempts = 5;
            options.Lockout.AllowedForNewUsers = true;

            // Default Password settings.
            options.Password.RequireDigit = false;
            options.Password.RequireLowercase = false;
            options.Password.RequireNonAlphanumeric = false;
            options.Password.RequireUppercase = false;
            options.Password.RequiredLength = 1;
            options.Password.RequiredUniqueChars = 1;

            // Default User settings.
            options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+"; //must be email characters if taken as username
            options.User.RequireUniqueEmail = true;
        })
            .AddEntityFrameworkStores<ApplicationDbContext>();

        var builder = services.AddIdentityServer(options =>
        {
            options.Events.RaiseErrorEvents = true;
            options.Events.RaiseInformationEvents = true;
            options.Events.RaiseFailureEvents = true;
            options.Events.RaiseSuccessEvents = true;
            options.PublicOrigin = Configuration["Domains:PublicOrigin"];
            options.IssuerUri = Configuration["Domains:Authority"];
        })
            .AddInMemoryIdentityResources(Config.GetIdentityResources())
            .AddInMemoryApiResources(Config.GetApis())
            .AddInMemoryClients(Config.GetClients(Configuration))
            .AddAspNetIdentity<ApplicationUser>()
            .AddProfileService<MyProfileService>();

        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddIdentityServerAuthentication(isAuth =>
            {
                isAuth.RequireHttpsMetadata = false;
                isAuth.Authority = Configuration["Domains:Authority"];
                isAuth.ApiName = "identity_api";
            });

        X509Certificate2 certificate = CertificateHelper.GetCertificate(Configuration, Environment);

        var connectionString = Configuration["CloudStorageAccount:ConnectionString"];
        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
        var blobClient = storageAccount.CreateCloudBlobClient();
        CloudBlobContainer container = blobClient.GetContainerReference("tokens");

        container.CreateIfNotExistsAsync().GetAwaiter().GetResult();

        services.AddDataProtection()
            .PersistKeysToAzureBlobStorage(container, Configuration["KeyVault:AzureBlobKeysFileIfNotKubernetes"])
            .ProtectKeysWithCertificate(certificate)
            .SetApplicationName("AppIdentity");

        builder.AddSigningCredential(certificate);

        services.AddMvc().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_2_1);
    }

标签: azureidentityserver4asp.net-core-identityrefresh-tokendata-protection

解决方案


您需要为 Identity Server 添加 Operational Store 的配置。

builder.AddOperationalStore(options => 
   options.ConfigureDbContext = storeBuilder => storeBuilder.UseSqlServer(connectionString);
);

没有这个 Identity Server 不知道在哪里存储刷新令牌,以便在应用程序重新启动后它们可用。

查看Operational Store 对持久授权的支持以获取更多信息。


推荐阅读