ASP.NET Core AWS Cognito JWT

Posted

技术标签:

【中文标题】ASP.NET Core AWS Cognito JWT【英文标题】: 【发布时间】:2018-10-14 20:42:48 【问题描述】:

在 ASP.NET Core 中,当 JWT 令牌传递不同的声明时,如何标准化可用的用户信息 AuthorizationHandlerContext.User?

AWS Congito 有两种令牌类型,访问令牌和 id 令牌。 Id 令牌包含对名字、姓氏、帐户 Id、电子邮件等的声明,而它的访问令牌仅包含帐户 Id 声明。

如何创建一个根据令牌类型填充的通用用户对象?

可用的 ID 令牌声明 AccountId、名字、姓氏、电子邮件、电话

可用的访问令牌声明 帐户ID

现在在我的应用程序的其他地方,我需要获取当前用户的名字。这不是 ID 令牌的问题,因为它已经可用,但我需要能够在发送访问令牌时转到我的数据库以获取用户的名字、姓氏、电子邮件和电话。

我尝试创建自己的用户对象,该对象在 DI 容器中注册,但 IHttpContextAccessor 传递了一个未经身份验证的身份,因此此时可用的声明为零。

//Startup.cs
public IServiceProvider ConfigureServices(IServiceCollection services)

    services.AddAuthentication(options => 
        options.DefaultAuthenticationScheme = JwtBearerDefault.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    )
    .AddJwtBearer(options => 
       //Omitted for brevity
    );

    services.AddAuthorization(options => 
        //Omitted for brevity
    );


public void Configure(IApplicationBuilder app, IHostingEnvironment env)

    app.UseAuthentication();


//MyUser.cs
//How can this class's properties be set depending on the access token type?
//IE set by the claims available in the ID token, but send by a DB query when the an access token is used.
class MyUser : IMyUser

     public int AccountId get;set;
     public string FirstName get;set;
     public string LastName get;set;


//MyService.cs
class MyService

    private IMyUser _user;

    public MyService(IMyUser user)
    
        _user = user;
    

    public MyMethod()
    
       //Do something with _user.FirstName, _user.LastName
    


//I tried passing IHttpContextAccessor as a constructor param in MyUser
//but context.User.Identity.Claims.Count = 0 and context.User.Identity.IsAuthenticated = false
//MyUser.cs
public MyUser(IHttpContextAccessor context)
    //context.User.Identity.IsAuthenticated == false
    //context.User.Identity.Claims.Count == 0
    //context.User.Identity.Name == null

【问题讨论】:

【参考方案1】:

如果您使用 Amazon.Lambda.AspNetCoreServer,您只需要在 API Gateway 中配置 cognito 为身份验证,然后您就可以通过以下方式访问声明:

var claim = Request.HttpContext.User.Claims.First(x=>x.Type =="Foo").Value;

【讨论】:

【参考方案2】:

如果您使用最新版本的 AspNetCoreServer,您可以从 JWT 令牌中获取所有声明,并将所有声明附加到您的 Principal 中。但是,您仍然需要配置您的 ASP.NET Core 应用程序以理解这些声明并从 ASP.NET Core(应用程序)的角度对用户进行身份验证。 我遇到了完全相同的问题,最终创建了一个library for it。

有了它,你可以:

services.AddAuthentication(AwsJwtAuthorizerDefaults.AuthenticationScheme)
  .AddJwtAuthorizer(options =>
  
      // In the case of local run, this option enables the extraction of claims from the token
      options.ExtractClaimsFromToken = true;
      
      // Validates the presence of the token
      options.RequireToken = true;
  );

如果您仍然需要更多地控制如何处理令牌,您可以创建自定义 AuthenticationHandler。考虑this example。

【讨论】:

以上是关于ASP.NET Core AWS Cognito JWT的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core AWS 无服务器和 CORS

AWS ASP.NET Core 2.1 和带角度的 CORS

将 asp.net core web api 部署到 aws elastic beanstalk 时出现错误 404

如何使用 AWS Cognito 和控制台 .NET Core 2.0 注册用户?

AWS负载均衡器后面的ASP.NET Core 2.1 HTTPS重定向?

如何使用 .AddJwtBearer() 在 .NET Core Web API 中验证 AWS Cognito JWT