web-dev-qa-db-fra.com

Clé Web Core Api .Net

Je développe une application que les utilisateurs peuvent authentifier via un nom d'utilisateur et un mot de passe et nous fournissons un jeton JWT qui est ensuite validé sur le serveur.

Une chose que j'aimerais ajouter est la possibilité d'avoir une clé API spéciale (guid) que les utilisateurs peuvent utiliser lors de l'intégration avec cette application au lieu d'utiliser un nom d'utilisateur et un mot de passe.

Je ne sais pas comment faire cela, car la partie authentification semble être un peu une boîte noire (en utilisant Aspnet Identity).

Voici une partie de mon code pour la configuration de l'authentification.

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddDbContext<OmbiContext>(options =>
        options.UseSqlite("Data Source=Ombi.db"));

    services.AddIdentity<OmbiUser, IdentityRole>()
        .AddEntityFrameworkStores<OmbiContext>()
        .AddDefaultTokenProviders();

    services.Configure<IdentityOptions>(options =>
    {
        options.Password.RequireDigit = false;
        options.Password.RequiredLength = 1;
        options.Password.RequireLowercase = false;
        options.Password.RequireNonAlphanumeric = false;
        options.Password.RequireUppercase = false;
    });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IMemoryCache cache)
{
    var tokenOptions = (IOptions<TokenAuthentication>)app.ApplicationServices.GetService(
        typeof(IOptions<TokenAuthentication>));

    var ctx = (IOmbiContext)app.ApplicationServices.GetService(typeof(IOmbiContext));

    var tokenValidationParameters = new TokenValidationParameters
    {

        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenOptions.Value.SecretKey)),

        RequireExpirationTime = true,
        ValidateLifetime = true,
        ValidAudience = "Ombi",
        ValidIssuer = "Ombi",
        ClockSkew = TimeSpan.Zero
    };

    app.UseJwtBearerAuthentication(new JwtBearerOptions()
    {
        Audience = "Ombi",
        AutomaticAuthenticate = true,
        TokenValidationParameters =  tokenValidationParameters,

    });
 //....
}

Le code ci-dessus fonctionne lorsque le [Authorized] attributs sur les contrôleurs et vérification des rôles et autres.

Tout le monde a une idée de comment je peux passer une sorte de Api-Key en-tête sur toutes les demandes contenant cette clé API spéciale pour qu'il passe le [Authorized] les attributs? (la clé est stockée dans le Db).

Merci

21
Jamie Rees

C'est ce que j'ai fait au final:

 public static void ApiKeyMiddlewear(this IApplicationBuilder app, IServiceProvider serviceProvider)
    {
        app.Use(async (context, next) =>
        {
            if (context.Request.Path.StartsWithSegments(new PathString("/api")))
            {
                // Let's check if this is an API Call
                if (context.Request.Headers["ApiKey"].Any())
                {
                    // validate the supplied API key
                    // Validate it
                    var headerKey = context.Request.Headers["ApiKey"].FirstOrDefault();
                    await ValidateApiKey(serviceProvider, context, next, headerKey);
                }
                else if (context.Request.Query.ContainsKey("apikey"))
                {
                    if (context.Request.Query.TryGetValue("apikey", out var queryKey))
                    {
                        await ValidateApiKey(serviceProvider, context, next, queryKey);
                    }
                }
                else
                {
                    await next();
                }
            }
            else
            {
                await next();
            }
        });
    }

    private static async Task ValidateApiKey(IServiceProvider serviceProvider, HttpContext context, Func<Task> next, string key)
    {
        // validate it here
        var valid = false;
        if (!valid)
        {
            context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
            await context.Response.WriteAsync("Invalid API Key");
        }
        else
        {
            var identity = new GenericIdentity("API");
            var principal = new GenericPrincipal(identity, new[] { "Admin", "ApiUser" });
            context.User = principal;
            await next();
        }
    }

Cela a beaucoup changé depuis que j'ai répondu à la question d'origine (la réponse est toujours valable). Mais vous pouvez lire à ce sujet ici: http://jamietech.com/2019/03/25/net-core-jwt-api-key/

19
Jamie Rees

Il y a un bel article sur l'utilisation des clés API dans les demandes d'en-tête sur ce lien: http://www.mithunvp.com/write-custom-asp-net-core-middleware-web-api/

Pour résumer, dans ASP.NET Core, vous pouvez utiliser un middleware pour contrôler la configuration du pipeline http. Le middleware remplace efficacement les HttpHandlers, qui étaient utilisés dans les versions antérieures d'asp.net MVC.

1
Mwiza