How do access my newly created REST API endpoints with curl? - liferay

Using REST builder I created some API endpoints. I am trying to access them using curl.
$ curl -X GET "http://localhost:8080/o/headless-xxx/v1.0/profile/12345" -H "accept: application/json" -H "x-csrf-token: xxx"
I retrieved the token from the browser after logged in with Liferay.authToken.
I get this error message.
"message" : "Access denied to com.xxx.headless.xxx.internal.resource.v1_0.ClassName#methodName"
I replaced actual names with xxx, ClassName and methodName. They all look correct.
Is there a setting I am missing? Am I authenticating incorrectly?
I was expecting to see the output of the api but I only get the error.

The message Access denied to might also result from a missing Service Access Policy. Please check it in the:
Control Panel -> Configuration -> Service Access Policy
If you have an oauth2 authentication, you could add
com.xxx.headless.xxx.internal.resource.v1_0.ClassName#methodName
or
com.xxx.headless.xxx.internal.resource.v1_0.ClassName#*
to AUTHORIZED_OAUTH2_SAP

Related

Azure AD Go SDK daemon application list users returns "Access Token missing or malformed"

I am attempting to retrieve user details via the graph API Go SDK. I have a daemon application which has been setup with adequate permissions that I have validated via curl as shown below:
Get token
curl \
-X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
--data 'client_id={client_id}&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret={client_secret}&grant_type=client_credentials' \
https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token
Request
curl -X GET \
-H "Authorization: Bearer XYZ...." \
"https://graph.microsoft.com/v1.0/users"
I successfully get a list of users.
However, when I attempt this via the Go SDK it fails.
I have set the required environment variables for authentication as per https://github.com/Azure/azure-sdk-for-go#more-authentication-details:
- `AZURE_TENANT_ID`: Specifies the Tenant to which to authenticate.
- `AZURE_CLIENT_ID`: Specifies the app client ID to use.
- `AZURE_CLIENT_SECRET`: Specifies the app secret to use
Code
func main() {
authorizer, err := auth.NewAuthorizerFromEnvironment()
if err != nil {
fmt.Println(err)
}
client := graphrbac.NewUsersClient(os.Getenv("AZURE_TENANT_ID"))
client.Authorizer = authorizer
if _, err := client.List(context.Background(), "", ""); err != nil {
fmt.Println("list users", err)
}
}
Error
list users graphrbac.UsersClient#List: Failure responding to request: StatusCode=401 -- Original Error: autorest/azure: Service returned an error. Status=401 Code="Unknown" Message="Unknown service error" Details=[{"odata.error":{"code":"Authentication_MissingOrMalformed","message":{"lang":"en","value":"Access Token missing or malformed."}}}]
The documentation here to me suggests that the authentication and token is handled by the auth package.
Update 1
I ran it debug mode by setting AZURE_GO_SDK_LOG_LEVEL=DEBUG and found that the GET request URL is different to what I used in my curl command:
(2020-06-16T15:31:49.3790420+10:00) INFO: REQUEST: GET https://graph.windows.net/{tenant_id}/users?api-version=1.6
User-Agent: Go/go1.13.11 (amd64-darwin) go-autorest/v14.1.1 Azure-SDK-For-Go/v43.2.0 graphrbac/1.6
Authorization: **REDACTED**
(2020-06-16T15:31:50.5191120+10:00) INFO: RESPONSE: 401 https://graph.windows.net/{tenant_id}/users?api-version=1.6
If I use that URL in my curl command I get:
{"odata.error":{"code":"Authentication_ExpiredToken","message":{"lang":"en","value":"Your access token has expired. Please renew it before submitting the request."}}}%
It seems the sdk uses azure ad graph api but not microsoft graph api in the backend.
Azure AD graph api shows like: https://graph.windows.net/{tenant_id}/users?api-version=1.6
Microsoft graph api shows like: https://graph.microsoft.com/v1.0/users
So you need to add the azure ad graph permissions for the application registered in your azure ad, but not add the microsoft graph permissions. Please add the permission by following the steps below:
1. Go to your application in your azure ad and click "API permissions" --> "Add a permission" --> "Azure Active Directory Graph".
2. Add the "Directory" permission.
3. Don't forget grant admin consent for it.
It seems that ADAL is already deprecated although MSAL is not yet ready (in an SDK).
Azure Console:
microsoft-authentication-library-for-go:
Which means that #hury-shen answer is still valid.

ErrorAccessDenied when requesting Microsoft Graph calendar resources via client credentials OAuth flow

I needed to access resource room's events via the Microsoft Graph API in a server-to-server environment so I followed this guide a few months ago. I created the application, set the calendar-related Application Permissions required and used an admin account to consent to the permissions successfully. Everything has been working for a good 3-4 months now without issues.
However, after not changing anything, today I am getting this response back from the /v1.0/users/{resource room email}/events endpoint:
{
"error": {
"code": "ErrorAccessDenied",
"message": "Access is denied. Check credentials and try again.",
"innerError": {
"request-id": "952955b5-562e-4fa6-8b0f-e381c8294fcd",
"date": "2017-09-06T03:09:49"
}
}
}
This appears to be a permissions issue as the /v1.0/users/{resource room email}/messages endpoint returns the resource room's messages just fine (assuming permissions are set).
If I follow the previously linked guide using CURL I can replicate the issue.
Get a token:
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" \
-d 'client_id=XXXXXX-XXXX-XXXX-XXXX-XXXXXXX&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret=XXXXXXXXX&grant_type=client_credentials' \
'https://login.microsoftonline.com/{my tennant URL}/oauth2/v2.0/token'
Try and get the events:
curl -X GET -H "Authorization: Bearer {token}" 'https://graph.microsoft.com/v1.0/users/{resource room email}/events'
And I receive the same error as above.
Has something changed that I am unaware of that would break this functionality?
Thanks for your help.

Sharepoint webhooks: Subscribing to a list

I'm trying to subscribe an application to a Sharepoint list. The notifications will be sent to the app via webhooks. To do this, you have to make an HTTP POST request to:
https://{your-account}.sharepoint.com/_api/web/lists('{list-guid}')/subscriptions
Body:
{
"resource": "{{ URL of the resource Id }}",
"notificationUrl" : "{{ URL of the endpoint that will process the webhooks }}",
"expirationDateTime" : "2017-09-27T00:00:00+00"
}
The call requires an access token. I obtained the token with curl this way:
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "client_id={{ Id of the application registered on Azure Active Directory }}&client_secret={{ Key added on Azure for the app }}&grant_type=client_credentials&resource=https%3A%2F%2F{{ My account }}.sharepoint.com" "https://login.microsoftonline.com/{{ Azure account tenant id}}/oauth2/token"
This returns a token that is included as a header in the POST request. Unfortunately, this request failed with error code 401. Body:
{
"error_description" : "The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework SDK documentation and inspect the server trace logs."
}
I think the problem is not the token, we tried too many times before it stopped throwing errors related to invalid token data.
Is there a way to debug this error? Any suggestions?
Finally, the problem was the access token, and we were able to get a correct access token. There are two ways to do it, and these methods work for single-tenant application.
Method 1: Two steps without sending the Azure credentials (only app credentials)
Step 1: Request a verification code.
Access this URL. It will redirect you to the redirect_uri passed in the query string, and the query string of the redirect will include a code that will be used to request the token.
https://login.microsoftonline.com/{{ Tenant id }}/oauth2/authorize?client_id={{ Application id }}&response_type=code&redirect_uri={{ URI of the application }}&response_mode=query&resource={{ Resource that you want to access}}&state=12345
Resource example: https%3A%2F%2Fyouraccount.sharepoint.com
Step 2: Request a token
curl -X POST -H "content-type: application/x-www-form-urlencoded" -d "grant_type=authorization_code&client_id={{ Application code }}&code={{ The code received in the last request }}&redirect_uri={{ Same redirect URI }}&resource={{ Same resource}}&client_secret={{ Application key }}" https://login.microsoftonline.com/{{ Tenant id }}/oauth2/token
Method 2: One step, sending the Azure credentials
curl -i -X POST -d "grant_type=password&resource={{ Resource id }}&client_id={{ App id }}&username={{ Azure username }}&password={{ Azure password }}" "https://login.windows.net/{{ Tenant id }}/oauth2/token"

Keyvault Authentication (REST API)

I am a little confused by Microsoft's scattered documentation.
I have created an application (https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal), which means I now have:
Application ID
Key
Directory ID
I have gone into the KeyVault in Azure Portal, and I have granted permissions to the application.
For test purposes, I am trying to run a test via CURL. The basis I am using for this is the following Microsoft pages (https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-service-to-service#request-an-access-token and https://learn.microsoft.com/en-us/rest/api/#create-the-request)
So, the first thing I do is get a token through the following call:
curl -d "grant_type=client_credentials&client_id=<removed_for_security>&client_secret=<removed_for_security>" https://login.microsoftonline.com/<removed_for_security>/oauth2/token
This returns a token.
I then (try to) use that token as follows:
curl -H "Authorization: Bearer <removed_for_security>” -vv https://<removed_for_security>.vault.azure.net/secrets/<removed_for_security>/<removed_for_security>
I get no content back, just "HTTP/1.1 401 Unauthorized"
You need to specify the resource you are requesting the token for.
curl -d "grant_type=client_credentials&client_id=<removed_for_security>&client_secret=<removed_for_security>&resource=https://vault.azure.net" https://login.microsoftonline.com/<removed_for_security>/oauth2/token
and also add the api version.
Ok, so I can confirm that the request you are doing is valid, for the most part, you forgot the API-version, but problem is not with the API version (it would tell you that).
https://xxx.vault.azure.net/secrets/xxx/?api-version=2015-06-01
this url works, so I guess the token is not right. The easiest way to check would be to go to JWT.io and paste the token there and see the contents, if they match with what the Key Vault expects. Probably you have a mismatch.

Error accessing an Azure Active Directory secured resource

I need to access a Web API which is secured via Azure Active Directory. I followed this documentation https://msdn.microsoft.com/sv-se/library/azure/dn645542.aspx
The first steps were successful, but at the end I can't access the required resource.
What I did:
First I call this link
https://login.microsoftonline.com/mytenantname.onmicrosoft.com/oauth2/authorize?response_type=code&client_id=3eec...32e5
and get redirected to the login portal.
After successful login I extract the code from redirected URL, which is something like this
https://localhost:8080/?code=AAABAAAAiL9Kn2Z27........RdzFpearqiAA
Then I use this code to acquire an access token. The first problem is here. According to the documentation (link above) the resource is optional. But it doesn't work if I omit the resource (error=Resource identifier is not provided.), so I have to provide it. Secondly, if I put the APP ID URI of my application registered in Azure AD to the recourse parameter, I got another error ( The client '3eec...32e5' and resource 'myapp.azurewebsites.net' identify the same application.). Therefore I put the graph.windows.net for resource parameter.
curl -s -X POST https://login.microsoftonline.com/akeliusdev.onmicrosoft.com/oauth2/token
-d grant_type=authorization_code -d client_id=3eec...32e5
-d client_secret=F%2BfpjpR............Wi8%3D
-d code=AAABAAAAiL9Kn2Z27........RdzFpearqiAA -d resource=https://graph.windows.net
This way I could get an access token. But then I am not able to access the resource using the access token. I did it this way:
curl https://myapp.azurewebsites.net/data
--header "Authorization:eyJ0eXAiOiJKV1QiLCJhbGciOiJ.............4WYr6xn"
Could someone help me on this issue?
Thanks.
To do this as a service to service call, without user interaction, you can follow Service to Service Calls Using Client Credentials
You need to create an AAD application and credentials. i.e. a Service Principal.
then to get the access token you make a POST call to
https://login.windows.net/<tenant ID>/oauth2/token
with the following data
grant_type=client_credentials&client_id=$username&client_secret=$password&resource=$resource
Where $username is your HTTP://localhost/whatever identifier
$password is your service principal password
$resource is https://management.core.windows.net/ (this might be graph, try it and see)
The access token will be in the JSON response as 'access_token'
You then add a header of Authorization: Bearer $AccessToken and hopefully you should get access!

Resources