Get claims in C# Lambda function called from an API with authorization

0

I am developing a lambda function in C# that is called from an api with authorization. I need to get the calling user's email, I have the following code:- //get user email string UserEmail = string.Empty; if (apigProxyEvent.RequestContext != null) { IDictionary<string, string> Claims = apigProxyEvent.RequestContext.Authorizer.Claims; context.Logger.LogLine($"GetBreaks Got email"); UserEmail = Claims["email"]; } else { UserEmail = "Testing"; }

I keep getting an error when getting the Claims:- "The requested operation requires an element of type 'Object', but the target element has type 'String'."

Thanks

3 Answers
0

Hi Martin -

It looks like you're using a "vanilla" Lambda function, and not using the Amazon.Lambda.AspNetServerCore NuGet package to run ASP.NET Core, in which case you obviously cannot use HttpContext.

Note that the apigProxyEvent.RequestContext is not the same as HttpContext. The RequestContext contains information about the request to the Lambda function, such as the AccountId, the ApiStage, etc. If your API callers are being authenticated with a custom authorizer (aka "Lambda Authorizer") that is sets the claims, you can get to the email claim like this:

var email = apigProxyEvent.RequestContext.Authorizer.Claims.ContainsKey("email") ?
           apigProxyEvent.RequestContext.Authorizer.Claims["email"] :
           string.Empty;

If you are not using a custom authorizer (aka Lambda Authorizer), then the question is, how are your API callers being authorized? Are they just passing a bearer token in the Authorization header? If so, you would need to validate that token (which you can read from the apigProxyEvent.Headers collection], and set the claims yourself. I recommend using a Lambda Authorizer though, or if you are using API Gateway HTTP APIs, there is a built-in JWT authorizer feature that will set claims for you.

profile pictureAWS
Kirk_D
answered 22 days ago
  • Thanks Kirk D, I am using "vanilla" Lambda, I get the error on the apigProxyEvent.RequestContext.Authorizer.Claims["email"] line. Let me check what Authorizer the API is using.

  • Ensure you are checking that the "email" claim exists before trying to read it (using ContainsKey("email") ), or else if it doesn't exist, you'll get an exception.

0

Here are a few ways to get the caller's email claim in a C# lambda function called from an API Gateway with authorization:

  1. Use the APIGatewayProxyEvent.RequestContext property to get the authorizer claims:
string email = apigProxyEvent.RequestContext.Authorizer.Claims["email"];
  1. Use the HttpContext to get the user claims:
var emailClaim = HttpContext.Current.User.Claims.FirstOrDefault(c => c.Type == "email");
string email = emailClaim?.Value;
  1. Inject IHttpContextAccessor and use it to access the current HttpContext:
public class MyClass 
{
  private readonly IHttpContextAccessor _httpContextAccessor;

  public MyClass(IHttpContextAccessor httpContextAccessor)
  {
    _httpContextAccessor = httpContextAccessor;
  }

  public string GetEmail()
  {
    var emailClaim = _httpContextAccessor.HttpContext.User.Claims.FirstOrDefault(c => c.Type == "email");
    return emailClaim?.Value;
  }
}

The key is accessing the authorizer claims from the APIGatewayProxyEvent or the current HttpContext's user claims.

AWS
answered 22 days ago
  • Just a note that you gave "HttpContext.Current" as an example, but HttpContext.Current only exists in ASP.NET on .NET Framework, not ASP.NET Core. AWS Lambda only supports modern .NET versions (.NET 6, .NET 8, etc.), not .NET Framework.

    Also, HttpContext is only relevant to ASP.NET in any case, and the question asked was about an AWS Lambda function using APIGatewayProxyRequest, which means the asker is not using ASP.NET Core, but a vanilla .NET Lambda function, for which there is no HttpContext at all.

0

Thanks, but uption1 still give the same error. Tried option 2 and got compile error that HttpContext does not have Current,

MartinU
answered 22 days ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions