AWS Authentication and Logging - api

I would like to:
Use AWS Cognito user pool to authenticate users and make requests to an API Gateway.
have some way to grant different permission levels to different user groups.
Log the users making requests and pass the user details to backend.
Currently, I am using IAM authoriser on the API Gateway, and sign the incoming requests with AWS Signature 4. I am also using User Pool Groups to give different permissions to different users.
I'm not sure how best to identify users making the request, though. Is it possible to access those details? To log the username (or some user ID) and pass a user ID to the Lambda function backend to inspect further ?
Or would it be better to use a JWT access token and OAuth scopes or something like that?

If you're using api gateway with lambda as proxy, then you can access the event object in lambda to obtain the relevant information. Try to get event.requestContext.identity which contains
{
"cognitoIdentityPoolId": null,
"accountId": null,
"cognitoIdentityId": null,
"caller": null,
"sourceIp": "52.255.255.12",
"principalOrgId": null,
"accessKey": null,
"cognitoAuthenticationType": null,
"cognitoAuthenticationProvider": null,
"userArn": null,
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36",
"user": null
},
in your lambda function.
ref: https://github.com/awsdocs/aws-lambda-developer-guide/blob/main/sample-apps/nodejs-apig/event.json

Related

How to access COWIN APIs?

I want to access these APIs from cowin.gov.in
This API is for getting the vaccination certificate -
https://ndh.digitallocker.gov.in/public/marketplace/api/cowin/cowincert
But when I access this using mobile number and a beneficiary ID , I get unauthorized access.
It requires to generate token and require following this from this site - https://openapi.aarogyasetu.gov.in/profile
I am integrating this to my Flutter App how can I get the following
Your Public Key (Callback data will be signed using this)
Callback URL
I am an individual using this API but it needs some company info too. What should I do?
Check this image for more details of registration
I checked the website https://openapi.aarogyasetu.gov.in/ and got the contact details
openapi.aarogyasetu#gov.in. Please try to send a mail to this id and lets see what they are going to respond. I am not sure whether individuals can get access to those API's since they are asking a lot of information about company/organization.
As stated in the image below, We might need to contact the Ministry of Health and Family Welfare, Government of India to get access to the protected APIs.
You can now raise your issues on https://github.com/cowinapi/developer.cowin
This is official github repository of COWIN
You can check all the open issues as well the closed issues for clarifications.
You don't need an api key for accessing the public api end points
mention general user agent like this {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36 Edg/90.0.818.56"} to avoid getting the error.
Co-WIN Public APIs allow any third-party application to access certain un-restricted information, that can be shared with its users. This is limited only to read access in Co-WIN. The appointment availability data is cached and may be up to 5 minutes old. Further, these APIs are subject to a rate limit of 100 API calls per 5 minutes per IP.
Swager API documentation official resource
https://apisetu.gov.in/public/api/cowin/cowin-public-v2
header = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36',
'origin': 'https://selfregistration.cowin.gov.in/',
'referer': 'https://selfregistration.cowin.gov.in/'
}
also needs
data = {"mobile": mobile,
"secret": "U2FsdGVkX1+z/4Nr9nta+2DrVJSv7KS6VoQUSQ1ZXYDx/CJUkWxFYG6P3iM/VW+6jLQ9RDQVzp/RcZ8kbT41xw=="
}
source
https://github.com/pallupz/covid-vaccine-booking/

How to authenticate Python client app for access to restricted Google Cloud function?

I've created a Google Cloud function and I would like to access it from a Python application I'm developing. I am able to access the function when there is no authentication required, but can't access the functions when I enable authentication.
Here is the service account key I'm using with stripped out info. The only role it is configured for is invoking cloud functions.
{
"type": "service_account",
"project_id": "XYZ",
"private_key_id": "XYZ",
"private_key": "XYZ",
"client_email": "XYZ",
"client_id": "XYZ",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "XYZ"
}
It seems that authenticated requests require a token that's included in the requests Authorization header, but I don't understand where to acquire this token.
I've tried using the approach outlined here with environment variables and the default auth method, but this doesn't work. I assume this is because the service account key is different from an OAuth token. (I have created a new service account the Cloud Functions invoker permission and am using that service account key). I receive the following error:
google.auth.exceptions.RefreshError: ('invalid_scope: Invalid OAuth scope or ID token audience provided.', '{"error":"invalid_scope","error_description":"Invalid OAuth scope or ID token audience provided."}')
How do I generate this token to authenticate the request from my Python script? Or is the approach with the service account recommended, but something else is going wrong?
I was able to get this working, though at time of writing there is a bug in the documentation that threw me off.
Access protected Cloud Functions is possible by using the IDTokenCredentials class within the google-auth library:
credentials = service_account.IDTokenCredentials.from_service_account_file(
SERVICE_ACCOUNT_JSON_FILE,
target_audience="https://function/url/here",
)
authed_session = AuthorizedSession(credentials)
response = authed_session.post(url)
I have my service account configured with the "Cloud Functions Invoker" role.
Your problem is almost certainly in the roles you gave that service account. Service accounts are finicky and the roles / permissions do not always act the way you think they will in my experience. Start by making a Service Account that has full permissions (project owner). Use that service account in your script then begin limiting the permissions from there. It sounds like you will need at a minimum cloud function "admin". If that works try another level down. Cloud function "developer" etc.
If you are using, for instance, App Engine or even other Cloud Functions to connect to your Cloud Function, you can use this: Function-to-function, the steps, basically are:
Grant the Cloud Functions Invoker.
In the calling function, you'll need to:
Create a Google-signed OAuth ID token with the audience (aud) set to the URL of the receiving function
Include the ID token in an Authorization: Bearer ID_TOKEN header in the request to the function.
import requests
//# TODO<developer>: set these values
REGION = 'us-central1'
PROJECT_ID = 'my-project'
RECEIVING_FUNCTION = 'my-function'
//# Constants for setting up metadata server request
//# See https://cloud.google.com/compute/docs/instances/verifying-instance-identity#request_signature
function_url = f'https://{REGION}-{PROJECT_ID}.cloudfunctions.net/{RECEIVING_FUNCTION}'
metadata_server_url = \
'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience='
token_full_url = metadata_server_url + function_url
token_headers = {'Metadata-Flavor': 'Google'}
def calling_function(request):
//# Fetch the token
token_response = requests.get(token_full_url, headers=token_headers)
jwt = token_response.text
//# Provide the token in the request to the receiving function
function_headers = {'Authorization': f'bearer {jwt}'}
function_response = requests.get(function_url, headers=function_headers)
return function_response.text
I have tested this solution and works as expected.
If you're invoking a function from a compute instance that doesn't have access to compute metadata (e.g. your own server), you'll have to manually generate the proper token:
Self-sign a service account JWT with the target_audience claim set to the URL of the receiving function.
Exchange the self-signed JWT for a Google-signed ID token, which should have the aud claim set to the above URL.
Include the ID token in an Authorization: Bearer ID_TOKEN header in the request to the function.
The Cloud IAP docs have sample code to demonstrate this functionality. The part you could be interested in should be this Authenticating from a service account

Angular 2 and Symfony 3 (OAuth and API calls)

I have a project in Angular 2.4.0 where I want to call endpoints from a Symfony 3 REST API. Both projects are launched locally. To get rid of CORS errors in Http calls in Angular, I set some proxy rules as follows :
{
"/api/*": {
"target": "http://myapi.dev:8000",
"secure": false,
"changeOrigin": true,
"pathRewrite": {"^/api" : ""},
"logLevel": "debug"
}
}
The first step is the authentication with Google OAuth, so I open a new popup window (in my Angular project) :
window.open('api/connect/google', '_blank', 'location=yes,height=570,width=520,scrollbars=yes,status=yes');
Then I chose a Google account to authenticate with, then the API close the popup window automatically when successfully authenticated.
Then I call the API again to get the current logged-in user :
get(): Observable<User> {
return this.http.get('api/user')
.map((response: Response) => response.json())
.catch((error: any) => Observable.throw(error));
}
The problem is that the API throws the following :
Request URL:http://localhost:2222/api/user
Request Method:GET
Status Code:302 Found
Remote Address:127.0.0.1:2222
Access-Control-Allow-Origin:*
cache-control:no-cache, private
connection:close
content-type:json
date:Wed, 22 Mar 2017 10:20:32 GMT
location:http://myapi.dev:8000/login
server:nginx/1.11.10
transfer-encoding:chunked
x-debug-token:128b90
x-debug-token-link:http://myapi.dev:8000/_profiler/128b90
x-powered-by:PHP/7.1.3
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Cache-Control:no-cache
Connection:keep-alive
Cookie:PHPSESSID=18c73caec383e91904dfd239d1a95faa
Host:localhost:2222
Pragma:no-cache
Referer:http://localhost:2222/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
It seems the API don't know I'm already authenticated and tries to redirect me to the /login route for every other Http calls I want to make.
The API works as following :
/login is a twig page with a link to /connect/google (the Google OAuth)
/connect/google allows you to choose one Google Account to authenticate with
If you call any API endpoint without being authenticated, it redirects you to /login
If you're authenticated, you can call every API endpoint
If I try all above Angular Http calls directly into the browser (eg: http://myapi.dev:8000/connect/google, http://myapi.dev:8000/user) everything works well.
I really have no idea where this issue comes from.
As you said in comments, Angular app is hosted on http://localhost:2222/, but api is hosted on http://myapi.dev:8000. Those two origins are completely different. It means that when myapi.dev will begin session, set cookie, it will be unavailable on localhost. Browser is not allowed to send cookies from different origins (due to CORS). That's why api doesn't see your session id key.
Possible ways to overcome problem:
Store both apps (angular and api) on the same origin (it means same domain, same protocol, and same port) - it's the easiest way.
Catch session ID cookie value (just after it will be set) and store it inside sessionStorage. Next, create Angular's request interceptor which will add SESSION cookie to all requests which're going to myapi.dev

OKTA API not exporting Source address details

I have created an OKTA API using token and admin account url to export the events(logs) reffered to the activities done on my okta account.
i am able to export the events but the IP address details or the source IP (from where) info is not getting exported.
anything more need to added to API for the same. please advise.
Modify Okta API com.okta.sdk.models.event.Actor.java
Add a property:
private String ipAddress;
Add get/set funcitons.
Compile source code to a new Okta API jar, use this jar substitute the original one, then you will get your IpAddress attribute value in event.actor.ipAddress
The ipAddress depends on the Actor objectType. Events with a Client ObjectType will include the ipAddress as shown in the example below:
{
"id": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.65 Safari/537.36",
"displayName": "CHROME",
"ipAddress": "127.0.0.1",
"objectType": "Client"
}
One way to debug this would be to use the public Events API and filter the events to validate that for the ipAddress is getting captured for the appropriate Events. If the ipAddress is included in the JSON response but is not getting parsed in the CSV export, then you may have uncovered a bug. That said, I just tested this and it worked for me ;-)

When an Adobe AIR app requests a resource from the server what shows as user agent?

When a browser like Chrome makes a request for a web page or image like a gravatar icon the server receives the userAgent information like so:
"Chrome/2.0 AppleWebKit/400.1.1 (KHTML, like Gecko)"
But if an Adobe AIR app makes a request for an image in the Image component what does the server receive? Is the same as a URLRequest?
"Chrome/2.0 AppleWebKit/400.1.1 (KHTML, like Gecko) AdobeAIR/3.0"
Background:
My AIR app shows Gravatar icon for the user and recently it stopped working. I'm wondering if it's gravatar is denying calls from user agents it doesn't recognize.
I've tried changing the userAgent to test the theory and it's throwing an error:
// 1195: Attempted access of inaccessible method userAgent through a reference with static type Class.
URLRequestDefaults.userAgent("chrome");
Update:
It looks like I need to set the user agent as a property and not a method. Was referring to this forum post. So I can change that might fix the gravatar issue but not answer how Adobe AIR apps appear to the server.
i hope this result's comes useful
Mozilla/5.0 (Windows; U; en-US) AppleWebKit/533.19.4 (KHTML, like
Gecko) AdobeAIR/3.1
also i cant realize that what's difference between requesting for an Image and URLRequest, they are same.