Asp.net core 在Startup.cs种子数据库期间添加UserClaims

Asp.net core 在Startup.cs种子数据库期间添加UserClaims,asp.net-core,asp.net-identity,claims-based-identity,Asp.net Core,Asp.net Identity,Claims Based Identity,如果用户通过我的GUI登录,一切正常 我使用SignInManager将其登录 我创建了一些声明 我创建了一个附带声明的JwtSecurityToken 我将JWT返回给客户机,他们在未来Http请求的头中使用它 我创建了一个“提供者”,代表后端服务访问其中一些声明。这些后端服务与提供者一起注入。当服务想要知道关于声明的一些信息时,它会询问提供者,提供者访问HttpContext,提取声明并向后端服务提供请求的值。它工作得很好 我的挑战是,我现在添加了一个SeedData例程,该例程在启动期间调

如果用户通过我的GUI登录,一切正常

  • 我使用SignInManager将其登录
  • 我创建了一些声明
  • 我创建了一个附带声明的JwtSecurityToken
  • 我将JWT返回给客户机,他们在未来Http请求的头中使用它
  • 我创建了一个“提供者”,代表后端服务访问其中一些声明。这些后端服务与提供者一起注入。当服务想要知道关于声明的一些信息时,它会询问提供者,提供者访问HttpContext,提取声明并向后端服务提供请求的值。它工作得很好

    我的挑战是,我现在添加了一个SeedData例程,该例程在启动期间调用。它将创建一个用户,然后播种一些业务数据(在新用户的上下文中)

    我的问题是,因为这不是来自客户端请求,所以在从startup.cs调用SeedData例程期间,我的HttpContext为NULL

    我(在SeedData内)尝试

    在启动过程中,当我尝试初始登录时,它似乎会立即抛出。我的观点是,startup.cs执行期间没有HttpContext

    在启动过程中是否有方法:

  • 创建初始用户
  • 以该用户身份登录
  • 向该用户添加一些声明
  • 在该用户的上下文中执行种子设定(调用后端服务)

  • 我可以通过创建一个特殊的“Foo”提供者来解决这个问题,该提供者不从声明中获取价值,而是直接从startup.cs获取硬信息,但我想知道是否有一种方法可以在startup.cs期间为声明设置HttpContext。

    您可以看到这可能会有所帮助。@Yinqiu。。。杰出的非常感谢。我已经创造了一个丑陋的黑客围绕它使我的供应商在启动和请求处理过程中表现不同,但你提供的链接似乎更优雅的解决方案。我要试一试。干杯
    // Sign in User
    SignInResult signInResult = await signInManager.PasswordSignInAsync("username", "password", false, false);
    
    // Create Claim
    CustomClaim claim = new CustomClaim();
    claim.ValueForBackend = "Foo";
    
    // Add to Claims List
    List<Claim> claims = new List<Claim>();
    claims.Add(new Claim("custom-claim", JsonSerializer.Serialize(claim)));
    
    // Create Claims Identity
    ClaimsIdentity claimsId = new ClaimsIdentity(claims);
    
    // Add the Claims Identity to current ClaimsPrincipal
    HttpContextAccessor.HttpContext.User.AddIdentity(claimsId);
    
    System.AggregateException: One or more errors occurred. (HttpContext must not be null.)
     ---> System.InvalidOperationException: HttpContext must not be null.
       at Microsoft.AspNetCore.Identity.SignInManager`1.get_Context()