如何使用 IdentityServer 使用 JWT 令牌在 .NetCore 中授权 WebApi?

Leo*_*ias 5 c# mongodb jwt .net-core identityserver4

我正在开发一个微服务应用程序来管理我的用户对已经开发的其他微服务的 webapi 路由的授权和身份验证。在研究了最佳选择后,我发现 IdentityServer4 完全符合我的需要,但我需要使用 MongoDB 作为我的数据库,但我无法让它工作。

如何将我的应用程序配置为使用 MongoDb 对他人进行身份验证的服务器?

这个想法是:

  1. 我希望我的用户在我的授权服务器上使用登录路由,如果成功,接收 JWT 令牌作为响应。
  2. 然后,用户使用 JWT 令牌作为 Header 在其他已经开发的服务上使用我的 API。
  3. 该服务接收 JWT 令牌,然后在我的授权微服务上对其进行验证,以查看用户是否有权使用该 API。

我使用项目 eShopOnContainers 作为我的基本参考:https://github.com/dotnet-architecture/eShopOnContainers,并使用这个库https://github.com/alexandre-spieser/AspNetCore.Identity.MongoDbCore我可以生成一个 JWT项目中的令牌和登录名,但无法使用 IdentityServer 使其与其他项目一起使用。还尝试遵循此示例https://github.com/souzartn/IdentityServer4.Samples.Mongo但它们中的大多数都是旧的并且代码不再起作用。

这是我能做的到现在。此代码生成 JWT 令牌,并且能够在身份验证项目上完美地进行授权和身份验证。

启动文件

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    var mongoSettings = Configuration.GetSection(nameof(MongoDbSettings));
    var settings = Configuration.GetSection(nameof(MongoDbSettings)).Get<MongoDbSettings>();

    services.AddSingleton<MongoDbSettings>(settings);

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

    var signingConfigurations = new SigningConfigurations();
    services.AddSingleton(signingConfigurations);

    var tokenConfigurations = new TokenConfigurations();
    new ConfigureFromConfigurationOptions<TokenConfigurations>(
        Configuration.GetSection("TokenConfigurations"))
            .Configure(tokenConfigurations);
    services.AddSingleton(tokenConfigurations);

    services.AddAuthentication(authOptions => {
        authOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        authOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    }).AddJwtBearer(bearerOptions => {
        var paramsValidation = bearerOptions.TokenValidationParameters;
        paramsValidation.IssuerSigningKey = signingConfigurations.Key;
        paramsValidation.ValidAudience = tokenConfigurations.Audience;
        paramsValidation.ValidIssuer = tokenConfigurations.Issuer;

        // Verify if token signature is valid
        paramsValidation.ValidateIssuerSigningKey = true;
        // Verify if token hasn't expired
        paramsValidation.ValidateLifetime = true;
        // Define tolerance time to token lifetime
        paramsValidation.ClockSkew = TimeSpan.Zero;
    });

    // Create policy to use Token as Authorization method
    services.AddAuthorization(auth => {
        auth.AddPolicy("Authorized", new AuthorizationPolicyBuilder()
            .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme??)
            .RequireAuthenticatedUser().Build());
        auth.AddPolicy("Admin", policy => policy.RequireRole("Admin"));
        auth.AddPolicy("Manager", policy => policy.RequireRole("Manager"));
    });
}
Run Code Online (Sandbox Code Playgroud)

签名配置.cs

public class TokenConfigurations
{
    public string Audience { get; set; }
    public string Issuer { get; set; }
    public int Seconds { get; set; }
}

public class SigningConfigurations
{
    public SecurityKey Key { get; }
    public SigningCredentials SigningCredentials { get; }

    public SigningConfigurations() {
        using (var provider = new RSACryptoServiceProvider(2048)) {
            Key = new RsaSecurityKey(provider.ExportParameters(true));
        }

        SigningCredentials = new SigningCredentials(Key, SecurityAlgorithms.RsaSha256Signature);
    }
}
Run Code Online (Sandbox Code Playgroud)