我可以在ASP.NET Core启动期间访问数据库吗?

Top*_*Rat 18 .net c# asp.net-core-mvc .net-core asp.net-core

我最近一直在研究.NET Core Web API.我刚刚通过https://stormpath.com/blog/token-authentication-asp-net-core上的指南尝试使用JWT进行身份验证.

一切顺利,直到我不得不GetIdentity用数据库查询替换方法中的硬编码用户名和密码,并意识到我不知道如何从这个文件中访问数据库!

我所指的方法显示在第70行的链接中 .https://github.com/nbarbettini/SimpleTokenProvider/blob/master/test/SimpleTokenProvider.Test/Startup.Auth.cs

我的问题如下.

  1. 我可以在这里访问数据库吗?如果是这样的话?
  2. 这应该是GetIdentity方法的位置,还是有更好的方法?

Nat*_*ini 15

是的,您可以访问数据库!在该Configure方法中运行的代码可以访问方法中添加的任何服务ConfigureServices,包括数据库上下文等.

例如,如果您有一个简单的Entity Framework上下文:

using Microsoft.EntityFrameworkCore;
using SimpleTokenProvider.Test.Models;

namespace SimpleTokenProvider.Test
{
    public class SimpleContext : DbContext
    {
        public SimpleContext(DbContextOptions<SimpleContext> options)
            : base(options)
        {
        }

        public DbSet<User> Users { get; set; }
    }
}
Run Code Online (Sandbox Code Playgroud)

你添加它ConfigureServices:

services.AddDbContext<SimpleContext>(opt => opt.UseInMemoryDatabase());
Run Code Online (Sandbox Code Playgroud)

然后,您可以在设置中间件时访问它:

var context = app.ApplicationServices.GetService<SimpleContext>();

app.UseSimpleTokenProvider(new TokenProviderOptions
{
    Path = "/api/token",
    Audience = "ExampleAudience",
    Issuer = "ExampleIssuer",
    SigningCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256),
    IdentityResolver = (username, password) => GetIdentity(context, username, password)
});
Run Code Online (Sandbox Code Playgroud)

GetIdentity稍微重写一下这个方法:

private Task<ClaimsIdentity> GetIdentity(SimpleContext context, string username, string password)
{
    // Access the database using the context
    // Here you'd need to do things like hash the password
    // and do a lookup to see if the user + password hash exists
}
Run Code Online (Sandbox Code Playgroud)

我是原始样本的作者.对不起,最初还不清楚!我尝试以IdentityResolver一种易于提供自己的功能的方式编写委托 - 比如与您自己的数据库集成(如上所述),或者将其挂钩到ASP.NET Core Identity.当然,您可以随意丢弃我的代码并做更好的事情.:)

  • 如果您只是将JWT添加到aspnet标识,则可以传递signinmanager而不是dbcontext:var userManager = app.ApplicationServices .GetService(typeof(UserManager <ApplicationUser>)) (3认同)

jua*_*ora 9

在.NET CORE 2.1上,只需将上下文作为参数传递给Configure方法:

public void Configure(IApplicationBuilder app, YourDbContext context, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
        //do whatever you want with the context here...
}
Run Code Online (Sandbox Code Playgroud)

将服务添加到服务容器可以使它们在应用程序和Configure方法中可用。通过依赖项注入或从ApplicationServices解析服务。


Flo*_*ser 6

接受的答案不为范围的服务工作(范围的每个请求都创建的服务,如果您正在使用实体框架,并增加与上下文AddDbContext是这种情况)。

您可以在启动时按如下方式使用作用域服务():

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    using (var serviceScope = app.ApplicationServices.CreateScope())
    {
        var services = serviceScope.ServiceProvider;
        var myDbContext = services.GetService<MyDbContext>();
    }
}
Run Code Online (Sandbox Code Playgroud)

Configure如juanora的答案所示将其传递给方法的参数