Multiple ORIGINS for CORS not working in case of custom authorizer error - serverless

I have CORS enabled in the application and have multiple origins, Its working fine with normal requests and error responses. But when I am getting some error in custom authorizer or deny the authorization. The CORS is not working for any status code(4XX or 5XX). I don't want to use * and have to handle multiple origins. I am using serverless
Here is the snippet from serverless.yml
resources:
Description: My backend
Resources:
GatewayResponseDefault4XX:
Type: 'AWS::ApiGateway::GatewayResponse'
Properties:
ResponseParameters:
gatewayresponse.header.Access-Control-Allow-Origin: "'qwe.xyz.com,abc.xxxx.com,xyz.xxxx.xom'"
gatewayresponse.header.Access-Control-Allow-Headers: "'qwe.xyz.com,abc.xxxx.com,xyz.xxxx.xom'"
ResponseType: DEFAULT_4XX
RestApiId:
Ref: 'ApiGatewayRestApi'
GatewayResponseDefault5XX:
Type: 'AWS::ApiGateway::GatewayResponse'
Properties:
ResponseParameters:
gatewayresponse.header.Access-Control-Allow-Origin: "'qwe.xyz.com,abc.xxxx.com,xyz.xxxx.xom'"
gatewayresponse.header.Access-Control-Allow-Headers: "'qwe.xyz.com,abc.xxxx.com,xyz.xxxx.xom'"
ResponseType: DEFAULT_5XX
RestApiId:
Ref: 'ApiGatewayRestApi'
Could you please help me to find a solution if I have multiple origins. How to handle multiple origins if default gateway responses for error codes

Related

How to add Accept, Authorization or Content-Type in OpenAPI 3.0?

My spec is as below.
/path:
/user:
get:
parameters:
- name: Authorization
in: header
required: true
schema:
type: string
Problem is that it is giving me the below warning. I get the same warning if I add Content-Type or Accept header.
Header parameters named Authorization are ignored. Use securitySchemes and security to define the Authorization
I tried the below but I don't see Authorization header added in the request. I am using https://editor.swagger.io to create the spec.
/path:
/user:
get:
parameters:
- name: Authorization
in: header
required: true
schema:
type: string
security:
- my_auth: []
components:
securitySchemes:
my_auth:
type: http
scheme: bearer
bearerFormat: JWT
Any help is appreciated. Thanks !!
In the request parameters, there are operation's specific parameters.
The general purpose HTTP headers aren't defined here because:
Content-Type is defined by the request body content. If there are multiple content types, the consumer has to choose and set Content-Type accordingly.
Accept is similar; it only relates to the response message.
For security, we do not describe the Authorization header but instead define the security scheme (see docs for more).
You may use the description property to explain how to use these headers with your API. However, if your API follows standards, it should not be necessary.
Once you have added the security schema to your API definition, you can use the Authorization function of Swagger Editor. So, you will add your token and trigger "Try it out." Swagger will populate the Authorization header; see the attached screenshot.

Is it possible to set the Micronaut OAuth2 callback-uri as an absolute URL?

I have a Micronaut web-app that uses OpenId / OAuth2 / JWT. In some environments, everything works really well with this set up, however, in other environments, auth fails during the step where the configured callback-uri is called. For some reason, in these environments, the URL generated is "http" instead of "https". This causes the call to fail since my application is only accessible over https.
I have no clue why it is trying to use http in the first place, however, if I was able to specify the callback-uri as an absolute / full URL, then I could probably work around this anomaly in these environments.
An example yml config that I use:
application:
name: xxxxx
security:
authentication: idtoken
oauth2:
enabled: true
clients:
azure:
client-id: ${OAUTH_CLIENT_ID}
client-secret: ${OAUTH_CLIENT_SECRET}
openid:
issuer: https://login.microsoftonline.com/xxx
callback-uri: ${OAUTH_CALLBACK_URI}
redirect:
login-success: ${LOGIN_SUCCESS_URL}
logout: '/logout-handler/logout-success'
endpoints:
logout:
get-allowed: true
token:
jwt:
cookie:
cookie-same-site: none
cookie-secure: true
In this config if I set the callback-uri environment variable (OAUTH_CALLBACK_URI) to /oauth/callback/azure, for example, then the full URL that seems to be used is http://xxxxx/oauth/callback/azure. However, if I use a full URL for the environment variable, e.g. https://xxxxx/oauth/callback/azure then the full URL it uses still appends that as opposed to using it as an absolute URL, i.e. http://xxxxx/https://xxxxx/oauth/callback/azure.
Is it possible to specify this uri as an absolute one and not have it append it like the above effectively duplicating it?
Good news. This was fixed in micronaut-security 2.3.4
https://github.com/micronaut-projects/micronaut-security/pull/644

Angular with Rails API: "Failed to load resource: the server responded with a status of 401 (Unauthorized)"

So I am deploying an Angular 5 app with a Rails 5 back-end. I can get the data to flow properly between the two locally, but trying to connect to the deployed version of the API (which is on Heroku) I run into some authorization issue. The error is:
Failed to load https://my_api.herokuapp.com/data.json: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:4200' is therefore not allowed access.
The response had HTTP status code 404.
Cross-Origin Read Blocking (CORB) blocked cross-origin response <URL> with MIME type application/json.
See <URL> for more details.
Is this something I need to change within the Rails API or in Angular? The deployed Rails API is essentially the same as the local version so I'm not sure where the disconnect is coming from.
There are only two refrences to the API in Angular. I connect to it the same way that I do to the local server:
Angular, app-module.ts
providers: [Angular2TokenService, AuthService, AuthGuard,
// {provide: 'api', useValue: 'http://localhost:3000/'}
{provide: 'api', useValue: 'https://my_ api.herokuapp.com/data.json'}
]
Perhaps it's my use of Angular2TokenService?
Angular, environment.ts:
export const environment = {
production: false,
token_auth_config: {
// apiBase: 'http://localhost:3000'
apiBase: 'https://my_api.herokuapp.com/data.json'
}};
Thanks! Let me know of any suggestions you might have or if you need clarification.
It's issue with CORS(cross-origin-resource-sharing). You can handle it by adding callback in your API like below:
def cors_set_access_control_headers
headers['Access-Control-Allow-Origin'] = ENV['SERVER_URL'] || '*'
end
where SERVER_URL is your front-end server URL
Else you can use gem 'rack-cors' as suggested in comments by #Kedarnag Mukanahallipatna

Why does API Gateway not have permissions for my Authorizer lambda when using Swagger?

I have an API defined using Swagger, which defines the following API Key authorizer:
securityDefinitions:
api_key:
type: apiKey
name: x-api-key
in: header
x-amazon-apigateway-authtype: "oauth2"
x-amazon-apigateway-authorizer:
type: token
authorizerUri: arn:aws:apigateway:eu-west-1:lambda:path/2015-03-31/functions/arn:aws:lambda:eu-west-1:[accountid]:function:ApiKeyAuthorizerLambdaFunction/invocations
authorizerResultTtlInSeconds: 0
However, when I pass this Swagger definition into my CloudFormation script and call an endpoint secured with this authorizer, I get a 500. The API Gateway logs show the following:
Incoming identity: ***key
Execution failed due to configuration error: Invalid permissions on Lambda function
Execution failed due to configuration error: Authorizer error
Note that I have given API Gateway permission to execute this lambda:
LambdaPermissionAuthorizerApiGateway:
Type: AWS::Lambda::Permission
Properties:
FunctionName:
Fn::GetAtt:
- ApiKeyAuthorizerLambdaFunction
- Arn
Action: lambda:InvokeFunction
Principal: apigateway.amazonaws.com
In fact, when I compare the CloudFormation script which Serverless generates for authoized endpoints (using Serverless's notation) with my own CloudFormation script using Swagger, I see little difference between them, except that my authorizer is defined with Swagger rather than directly as a CF resource.
Can anyone shed any light on this? Is this a bug when using Swagger with CloudFormation?
Can you try setting the authorizerCredentials parameter of your x-amazon-apigateway-authorizer to a valid IAM role that has permission to execute the authorizer lambda? Not sure the standard AWS::Lambda::Permission applies for this, though you probably want to keep it for now just in case it is still required.
The x-amazon-apigateway-authorizer docs show an example.

Get call with Authorization-header converts to OPTIONS call

I am using swagger-ui to create and test my apis calls but in case where I have a GET call with Authorization header it fails and returns ERROR. When I try to debug I found out that it sends this GET call as OPTIONS if Authorization header is present, else as a GET call.
The strange part is with Authorization header the POST call works fine.
/urlCode:
get:
description: Initiate something
parameters:
- name: Authorization
in: header
description: Authorization token
required: true
type: string
- name: var
in: query
description: variable
required: true
type: string
format: string
This is a CORS issue. To see what's allowed, web applications must first send an OPTIONS request prior to submitting the actual request (which is why you see OPTIONS and not GET). In order for it to work properly, you must enable CORS on the API itself. Further details can be found in swagger-ui's repository.

Resources