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

时间:2019-07-25 17:16:56

标签: c# mongodb .net-core jwt identityserver4

我正在开发一个微服务应用程序,以管理用户对已开发的其他微服务的webapi路由的授权和身份验证。在研究了最佳选择之后,我发现IdentityServer4完全可以满足我的需要,但是我需要使用MongoDB作为数据库,并且无法使其正常工作。

如何配置我的应用程序以用作服务器,以便使用MongoDb对其他人进行身份验证?

这个想法是: 1.我希望用户使用我的授权服务器上的登录路由,如果成功,则接收JWT令牌作为响应。 2.然后,用户将JWT令牌用作标头,以在已开发的其他服务上使用我的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令牌,并且能够在身份验证项目上进行完美的授权和身份验证。

Startup.cs

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"));
    });
}

SigningConfigurations.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);
    }
}

0 个答案:

没有答案