我正在开发一个微服务应用程序,以管理用户对已开发的其他微服务的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);
}
}