简体   繁体   English

ASP.NET Core AWS Cognito JWT

[英]ASP.NET Core AWS Cognito JWT

In ASP.NET Core, how can I standardize the available user information AuthorizationHandlerContext.User when the JWT tokens pass different claims?在 ASP.NET Core 中,当 JWT 令牌传递不同的声明时,如何标准化可用的用户信息 AuthorizationHandlerContext.User?

AWS Congito has two token types, access tokens, and id tokens. AWS Congito 有两种令牌类型,访问令牌和 id 令牌。 Id tokens contain claims for first name, last name, account Id, email, etc, while it's access token only contains the account Id claim. Id 令牌包含对名字、姓氏、帐户 ID、电子邮件等的声明,而它的访问令牌仅包含帐户 ID 声明。

How can I create a generic User object which get's populate depending on the token type?如何创建根据令牌类型填充的通用用户对象?

Available ID Token claims AccountId, FirstName, LastName, Email, Phone可用 ID 令牌声明 AccountId、FirstName、LastName、Email、Phone

Available Access Token claims AccountId可用访问令牌声明 AccountId

Now somewhere else in my application I need to get the current user's first name.现在在我的应用程序的其他地方,我需要获取当前用户的名字。 This isn't a problem with the ID token because it's already available, but I need to be able to go to my DB to fetch the user's first name, last name, email, and phone when an access token is sent.这不是 ID 令牌的问题,因为它已经可用,但我需要能够在发送访问令牌时转到我的数据库以获取用户的名字、姓氏、电子邮件和电话。

I tried create my own user object which is registered with the DI Container, but IHttpContextAccessor passes an identity which isn't authenticated so there are zero claims available at that point.我尝试创建自己的用户对象,该对象已在 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
}

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

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

If you use the latest version of AspNetCoreServer, you can get all claims from the JWT token and have all of it attached with your Principal.如果您使用最新版本的 AspNetCoreServer,您可以从 JWT 令牌中获取所有声明,并将所有声明附加到您的 Principal 中。 However, you still need to configure your ASP.NET Core application to understand those claims and authenticate the user from the ASP.NET Core (application) perspective.但是,您仍然需要配置 ASP.NET Core 应用程序以了解这些声明并从 ASP.NET Core(应用程序)角度对用户进行身份验证。 I had the exact same issue and ended up creating a library for it .我遇到了完全相同的问题,最终为它创建了一个

With that, you can:有了它,你可以:

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;
  });

If you still need more control about what to do with the token, you can create a custom AuthenticationHandler.如果您仍然需要更多地控制如何处理令牌,您可以创建一个自定义的 AuthenticationHandler。 Consider this example .考虑这个例子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM