I have a cloud function named rad_format_text_v0. I (andy#onehot.io) have permission to invoke it, shown here:
$ gcloud beta functions get-iam-policy rad_format_text_v0
bindings:
- members:
- allAuthenticatedUsers
- user:andy#onehot.io
role: roles/cloudfunctions.invoker
etag: BwWOSfjYxp0=
version: 1
I can invoke it using gcloud functions call...
$ gcloud auth list
Credentialed Accounts
ACTIVE ACCOUNT
* andy#onehot.io
$ gcloud functions call rad_format_text_v0 --data "$(< test.json)"
executionId: 2wm7nrgc0vjo
result: |
["REDACTED successful result"]
However, when I try another HTTP client like curl, it fails even though I'm passing an auth token...
$ curl -i -X POST "https://us-central1-onehot-autocoder.cloudfunctions.net/rad_format_text_v0" -H "Content-Type:application/json" -H "Authorization: bearer $(gcloud auth application-default print-access-token)" --data #test.json
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer error="invalid_token" error_description="The access token could not be verified"
Date: Mon, 22 Jul 2019 19:46:59 GMT
Content-Type: text/html; charset=UTF-8
Server: Google Frontend
Content-Length: 312
Alt-Svc: quic=":443"; ma=2592000; v="46,43,39"
<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>401 Unauthorized</title>
</head>
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Unauthorized</h1>
<h2>Your client does not have permission to the requested URL <code>/rad_format_text_v0</code>.</h2>
<h2></h2>
</body></html>
I did exactly as explained in the documentation. I have no idea why my token is not working.
You are using the gcloud auth application-default print-access-token to get the token and the documentation you shared specify that you should use the gcloud auth print-identity-token command instead.
I tested it and I found that I was not able to use the print-identity-token for my user account. Instead I had to create a new service account and activate it. Then in the curl command, I specified the service account like in the example below:
curl -i https://[REGION]-[PROJECT_ID].cloudfunctions.net/[FUNCTION_NAME] -H "Authorization: bearer $(gcloud auth print-identity-token [SERVICE_ACCOUNT] )"
Apparently the Google Cloud SDK has an issue with the gcloud auth print-identity-token command on version 254, you could also try to downgrade it with the following command:
gcloud components update --version 249.0.0
Related
If I try to provide authentication credentials in my request as a generated ID token stored in an Authorization header:
curl -m 550 -X POST https://origin-project.cloudfunctions.net/myfunction \
-H "Authorization: bearer $(gcloud auth print-identity-token)" \
-H "Content-Type: application/json" -d '{}'
I get 401 Unauthorized:
<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>401 Unauthorized</title>
</head>
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Unauthorized</h1>
<h2>Your client does not have permission to the requested URL <code>/myfunction</code>.</h2>
<h2></h2>
</body></html>
But if I manually insert the ID token like below, it works:
curl -m 550 -X POST https://origin-project.cloudfunctions.net/myfunction \
-H "Authorization: bearer eyM5NjBJ0eXAiOiJKV1QifQ.eyJpc3MiOztszEgUX4oH.YI80RjsZdxSFIcFshmA" \
-H "Content-Type: application/json" -d '{}'
Response:
Request payload is empty: None
Does anyone know why this is so?
Note: I'm executing commands locally via Google Cloud CLI.
I'm attempting to call Google Cloud's signJwt method with Workload Identity Federation with a service account via domain wide delegation. As far as I can tell I'm following Google's instructions exactly but am getting the following error:
{
"error": {
"code": 400,
"message": "Request contains an invalid argument.",
"status": "INVALID_ARGUMENT"
}
}
I'm running the following curl command in the Cloud Shell
curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d #request.json \
"https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/<SA_USERNAME>%40<PROJECT_NAME>.iam.gserviceaccount.com:signJwt"
where request.json contains the following:
{
"payload": "{\"iss\":\"<SA_USERNAME>#<PROJECT_NAME>.iam.gserviceaccount.com\",\"scope\":\"https://www.googleapis.com/auth/gmail.readonly\",\"aud\":\"https://oauth2.googleapis.com/token\",\"exp\":1672868057013,\"iat\":1672868053513,\"sub\":\"<USER_NAME_OF_USER_TO_IMPERSONATE>#<DOMAIN>\"}",
"delegates": [],
}
Why am I getting an invalid argument error?
Try something like this in the request body :
{
"delegates": [
string
],
"payload": string
}
As given in the document:
The sequence of service accounts in a delegation chain. Each service
account must be granted the roles/iam.serviceAccountTokenCreator role
on its next service account in the chain. The last service account in
the chain must be granted the roles/iam.serviceAccountTokenCreator
role on the service account that is specified in the name field of the
request.
The delegates must have the following format: projects/-/serviceAccounts/{ACCOUNT_EMAIL_OR_UNIQUEID}. The - wildcard character is required; replacing it with a project ID is invalid.
Also there is a bug request on it.You can raise a new request if you need it by using the issue tracker.
I'm trying to use the token provided by AWS Cognito to access a URL via Postman or cURL, but I'm failing to.
I have used the CloudFormation template bellow to create an API with a JWT authentication.
https://github.com/awsdocs/amazon-api-gateway-developer-guide/blob/main/cloudformation-templates/HTTP/http-with-jwt-auth.yaml
After signing-in, I can access the lambda function using the returned URL and access_token. This works just as expected:
http://<api_url>/?access_token=<token>
But when I try to access it from Postman or cURL using the access_token in the header, it outputs a 401. I was expecting to have access granted.
$ curl -v -X GET <url> -H "Authorization: <token>"
{"message":"Unauthorized"}
What have I tried:
I have tried to add 'Content-Type: application/json', but still get 401.
I have tried to use Authorization: Bearer <token>, but still get 401.
This template only return the access_token, but another stack I have also returns the id_token, and a 401 is returned for both
The
complete returned header is:
HTTP/2 401
date: Thu, 03 Mar 2022 20:12:58 GMT
content-type: application/json
content-length: 26
www-authenticate: Bearer
apigw-requestid: ObIjqhmPIAMEJtA=
* Connection #0 to host <url> left intact
{"message":"Unauthorized"}
The JWT Authorizer is configured as:
JWTAuthorizer:
Type: AWS::ApiGatewayV2::Authorizer
Properties:
ApiId: !Ref MyAPI
AuthorizerType: JWT
IdentitySource:
- '$request.querystring.access_token'
JwtConfiguration:
Audience:
- !Ref AppClient
Issuer: !Sub https://cognito-idp.${AWS::Region}.amazonaws.com/${UserPool}
Name: test-jwt-authorizer
The IdentitySource must be '$request.header.Authorization' in order for it to read from header.Authorization.
I am using WSO2 Identity server and using email as username from following documentation-
https://is.docs.wso2.com/en/5.9.0/learn/using-email-address-as-the-username/
Then while performing a sign-up ie create users using SCIM2 APIs with email more than 30 characters i was getting the following error-
{
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:Error"
],
"scimType": "invalidValue",
"detail": "31301 - Username test1233.admin#motioneducation.com is not valid. User name must be a non null string with following format, ^[\\S]{3,30}$",
"status": "400"
}
Then to fix this i added this regex expression in deployment.toml file in user store-
[user_store]
username_java_script_regex = '^[a-zA-Z0-9.-]+#[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$'
username_java_regex='^[a-zA-Z0-9.-]+#[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}'
This change fixed my sign-up problem but the token generated by performing login using wso2 /oauth2/token API is giving 401 unauthorized in /oauth2/introspect API?
Please Help........?
Since you have enabled email as username, then you need to use the email username in the authorization header also. A sample curl command is given below.
curl --location --request POST
'https://{host_name}:{port}/oauth2/introspect'
--header 'Content-Type: application/x-www-form-urlencoded'
--header 'Authorization: Basic {base64encode(emailusername:password)}'
--data-urlencode 'token={access_token}'
Sample request
curl --location --request POST
'https://localhost:9443/oauth2/introspect'
--header 'Content-Type: application/x-www-form-urlencoded'
--header 'Authorization: Basic YWRtaW5Ad3NvMi5jb206YWRtaW4='
--data-urlencode 'token=47f65812-c5fb-3f90-b5c0-3bbc3603578f'
401 unauthorized error comes only if you are sending invalid credentials. So please check whether you are sending valid emailusername and valid password in authorization header
I built a sample container(sample of Go, https://cloud.google.com/run/docs/quickstarts/build-and-deploy) and deployed to cloud run (I unchecked "allow unauthenticated invocations").
However, when I open the endpoint URL of my service, I get a 401 page,
<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>401 Unauthorized</title>
</head>
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Unauthorized</h1>
<h2>Your client does not have permission to the requested URL <code>/</code>.</h2>
<h2></h2>
</body></html>
According to the official document (https://cloud.google.com/run/docs/securing/authenticating#developers), I used this command.
curl -H "Authorization: Bearer $(gcloud config config-helper --format 'value(credential.id_token)')" [SERVICE_URL]
My user account has "roles/run.invoker"
When I checked "allow unauthenticated invocations", I got an expected result.
Is there anything to open the endpoint?
Please make sure gcloud version is at least 243.0.0 by "gcloud --version"
Please use "gcloud components update" to update if gcloud is too old
[Updated] Using gcloud in Cloud Shell to call authentication-required Cloud Run service is also working now.
Thanks!
I managed to connect from a cloud function, finally, after 15-minute wrestling with the same 401 error when invoking a cloud run service that does not allow unauthenticated invocations:
import google.auth
auth_req = google.auth.transport.requests.Request()
id_token = google.oauth2.id_token.fetch_id_token(auth_req, URL)
headers = {'Authorization': 'Bearer ' + id_token,
"Content-Type": "application/json; charset=utf-8"}
response = requests.post(URL, json=request_json, headers=headers)