serverless icon indicating copy to clipboard operation
serverless copied to clipboard

Lambda Authorizer multiple identity sources with OR between them

Open Slash7GNR opened this issue 2 years ago • 12 comments

Is there an existing issue for this?

  • [X] I have searched existing issues, it hasn't been reported yet

Use case description

Today there is already a feature where multiple identity source can be applied to lambda authorizer. The feature request can be seen here As far as I understand, for this case, all the identity sources should be applied, otherwise API gateway will return 401 result automatically. I would like to have the option that if ONE of the identity sources exists, then the lambda authorizer will be ran. So for example if I have two identity sources:

  1. Authorization Header
  2. Cookie Header
  • If Cookie header exists and authorization header not exists - lambda authorizer will be ran
  • If Authorization header exists but cookie header not exists - lambda authorizer will be ran
  • If both Authorization and Cookie header not exists - API Gateway will return 401 automatically.

Is it a use case that can be implemented ?

Regards, Nadav Mary

Proposed solution (optional)

No response

Slash7GNR avatar Jul 14 '22 08:07 Slash7GNR

Hey @Slash7GNR - did you validate that in the case of specifying two identity sources, where only one is available, it results in a 401 error?

pgrzesik avatar Jul 18 '22 08:07 pgrzesik

I verified this behavior. An authorizer with multiple identity sources requires all of them to be set, and if any are missing, it returns 401.

This is consistent with AWS docs:

“API Gateway uses the specified identity sources as the request authorizer caching key. When caching is enabled, API Gateway calls the authorizer’s Lambda function only after successfully verifying that all the specified identity sources are present at runtime. If a specified identify source is missing, null, or empty, API Gateway returns a 401 Unauthorized response without calling the authorizer Lambda function.”

One workaround is to define separate events with different authorizer settings:

    events:            
      - http:
          path: example/
          method: post
          authorizer:
            arn: ${self:custom.customAuthorizerArn}
            type: request
            resultTtlInSeconds: 300
            identitySource: method.request.header.Authorization
      - http:
          path: example/this-uses-another-identity-source/
          method: post
          authorizer:
            arn: ${self:custom.customAuthorizerArn}
            type: request
            resultTtlInSeconds: 300
            identitySource: method.request.header.X-Some-Other-Header

This isn't ideal.

@pgrzesik Do you see a better approach?

kmjennison avatar Jul 20 '22 18:07 kmjennison

Depending on your situation: another approach would be to include all relevant auth info to a single header, if your client is able to do so. Then, your authorizer could handle the header value in different ways. This probably doesn't work well for many use cases related to cookies, though.

Related: #3782

kmjennison avatar Jul 20 '22 23:07 kmjennison

I don't really see a better approach - one option would be to either only use one identity source or always put dummy values if it's missing for a given source (e.g. add a dummy header when using cookies)

I think it's a limitation of AWS - could we move this to a discussion @Slash7GNR?

pgrzesik avatar Jul 21 '22 08:07 pgrzesik

Hello I am facing the same problem, we have the use case of a websocket authorizer that should work for both web client using Cookie header and 3rd party app using Authorization Bearer token. At the moment it's not possible, the only option is either to create 2 apis (which require 2 custom domains) or ask developer to use Cookie header for passing authorization token (which look not professional at all).

jodem avatar Sep 16 '22 11:09 jodem

I'm encountering a similar issue when using an API Gateway endpoint that is being hit by AppSync through both an Authorization Token (in the Authorization header) and also through an API Key (which is sent through the x-api-key header ). I'd like to have the authorizer verify both of these types of Authorization but right now its impossible

Sircrab avatar Oct 21 '22 18:10 Sircrab

I verified this behavior. An authorizer with multiple identity sources requires all of them to be set, and if any are missing, it returns 401.

This is consistent with AWS docs

Reading the docs further, the identitySource is only required and therefore both would only be needed if caching is enabled (obviously there is a performance impact to consider here):

For Authorization Caching, select or deselect the Enabled option, depending on whether you want to cache the authorization policy generated by the authorizer or not. When policy caching is enabled, you can choose to modify the TTL value from the default (300). Setting TTL=0 disables policy caching.

When caching is disabled, it is not necessary to specify an identity source.

In the YAML this can be set via resultTtlInSeconds: 0 - has anybody tried this approach yet to validate that it works and that caching is also disabled in this case?

@Slash7GNR @kmjennison @pgrzesik

clocked0ne avatar Nov 03 '22 18:11 clocked0ne

@clocked0ne No, I haven't tried it. Disabling caching wasn't a viable option for us.

kmjennison avatar Nov 03 '22 18:11 kmjennison

This feature would also be required especially to maintain backward compatibility. Consider the scenario where I need to add another identity source and don’t want to implement a string splitting logic and need to ensure that old clients don’t break. Please prioritize this feature.

na1taneja2821 avatar Jan 13 '23 05:01 na1taneja2821

@na1taneja2821 This seems to be a limitation of AWS, not Serverless Framework, you can try to raise that concert with them

pgrzesik avatar Jan 14 '23 08:01 pgrzesik

@clocked0ne I tried that (setting cache to 0 and provide no identitysource) and it works. thanks

husseinkohy avatar Sep 08 '23 13:09 husseinkohy

I have the same need as the earlier posters - an API that needs to support either a Cookie header or an Authorization: bearer token.

fdmarc avatar Jan 08 '24 16:01 fdmarc