AWS SDK authorization in ECS id failing, but not local - java

I have a dockerized spring boot app running on AWS Fargate in a private subnet on ECS, sitting behind a load balancer. I created vpc PrivateLink Endpoints to AWS services such that the task has access to ECR, ECS, S3, etc for the purposes of building and saving the image. I also exposed an SNS endpoint so that the service can access SNS. I can see in the logs, traffic is reaching the spring boot app.
I created a user called “myapp-sns-access”, authorized it to publish to topics and generated programmatic credentials, stored them in AWS secrets manager, and have them passed in as environment variables inside the container definition, found under the task definition ("value-from" and secret arn).
The spring boot service has an endpoint that calls AWS SNS. I cannot figure out why I keep getting this error:
com.amazonaws.services.sns.model.AmazonSNSException: '"SNS_SECRET_KEY":"XXXXX"}/20220811/us-east-1/sns/aws4_request' not a valid key=value pair (missing equal-sign) in Authorization header: 'AWS4-HMAC-SHA256 Credential={"SNS_ACCESS_KEY_ID":"CORRECT_ACCESS_ID","SNS_SECRET_KEY":"CORRECT_SECRET_KEY"}/20220811/us-east-1/sns/aws4_request, SignedHeaders=amz-sdk-invocation-id;amz-sdk-request;amz-sdk-retry;host;user-agent;x-amz-date, Signature=XXXXREDACTEDXXXX'. (Service: AmazonSNS; Status Code: 400; Error Code: IncompleteSignature; Proxy: null)
I can see that the service is receiving the credentials from the AWS Secrets Manager (notice above), but I guess the AWS SDK is failing to handle the auth portion of the sns call for some reason that I cannot figure out.
Heres the gradle import:
// https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk
implementation group: 'com.amazonaws', name: 'aws-java-sdk', version: '1.12.253'
This all works locally, so I wonder if theres some weird auth flow / access to some auth server that I need to create an endpoint for in order for the service to create the auth headers correctly. I triple checked for typos with the secrets and refreshed them. I also opened up my security groups and allowed all traffic on all ports (for testing purposes).
Appreciate your time.
Update: I swapped out the PrivateLink endpoints for a Nat gateway, and I tried role based authorization and its still not working.

Related

MS Teams Message Extension not working on test server[Cloud]

I have developed MS Teams Message Extension using Java[Spring Boot] and registered the bot in Botframework Development portal[https://dev.botframework.com/]. It is working fine in local. I tested in local environment using a tunneling application named localtunnel. I tested the extension in MS Teams.
I pushed the code to cloud[AWS] as it was working fine on local and also changed the message endpoint URL to point to our test server. But, unfortunately i am getting " Bot returned unsuccessful status code unauthorized."[You can see the screenshot]. Test server message endpoint doesn't require JWT token, I am able to call it successfully from postman with out giving token.
As per the documentation, this error occurs usually when:
The Messaging endpoint specified on the Settings page for your bot in the Bot Framework Portal is incorrect. Make sure you have included the proper path at the end of the URL (e.g., /api/messages).
The Messaging endpoint specified on the Settings page for your bot in the Bot Framework Portal does not begin with https or is not trusted by the Bot Framework. Your bot must have a valid, chain-trusted certificate.
The bot is configured with missing or incorrect values for app ID or password. Verify that the bot configuration settings specify valid values for app ID and password.
All the points are correct in my case.
In this documentation, It is mentioned about Azure Bot resources in the "Test your bot" section of "Step 4: Test your bot in the cloud".
https://learn.microsoft.com/en-us/azure/bot-service/bot-service-troubleshoot-authentication-problems?view=azure-bot-service-4.0&tabs=csharp#step-3
So in order to test the bot on cloud, is it necessary to register it on Azure Bot services instead of Botframework development portal? Can't we just test it just by registering it on Botframework development portal?
The dev.botframework.com portal is deprecated, so I'd advise against continuing to use it. The Azure Bot resource is the evolution and replacement of the Bot Channels Registration, so you will need to use it to test your bot in the cloud. It effectively does the same things, but it better handles various new security and tenancy features that the old portal did not.
Furthermore, the documentation you linked mentions that extra security configuration steps must be taken for non-Azure deployments to get your bot to use https. Ensure you do this before filling in the messaging endpoint in your Azure Bot configuration.
I figure out the issue. Even though message endpoint could be called without any JWT token of our app, code was verifying the token if in case it is present in Authorization header instead of ignoring it. MS Teams sends JWT token in Authorization header of every request to verify it is coming from teams, but extension app was comparing this token sent from teams against our app. Since this token is not created by our app but instead by bot framework, so it was throwing 401 unauthorized.
So make sure your app is in ignoring the token sent in Authorization header for message endpoint.
About the other doubts I had:
It is not mandatory to register bot in azure in order to test in cloud, you can register it in development portal as well. Since development portal is depreciated, I highly recommend to use azure as it is highly secure.
You can do non azure deployment as well. You can deploy your extension app or message API endpoint in any cloud provider of your choice. But you have to register the bot either in development portal or azure which will call your extension app.

jhipster gateway not routing requests to microservice

I am trying to create app with microservice architecture. I am using jhipster. I want to separate backend and frontend. So first i created jhipster uaa server for authorization named as uaa then i created a gateway with --skip-client and --skip-user-management options named as gateway. After running them both i can be login with postman with /auth/login api. But when i want to get account information i am getting api not found error. I am trying to get account information with /uaa/api/account link because microservices's name is uaa but no luck. Am i missing something or is there any other settings that forget?
Before /uaa is missing /services, on the end is gonna be something like /services/uaa/api/account .

How to connect to Azure keyvault from SpringBoot application for local development using MSI

I am trying to connect to Azure KeyVault from my locally running Spring Boot Application. I can't keep those secrets to be saved in keyvault in different properties or yaml during dev, because my application will generate and delete so many secrets and tokens to be saved in keyvault in the run time.
I am aware of the process in which we can create an Azure service principal from your application registration. And use
azure.keyvault.client-id
azure.keyvault.client-key
in application.properties to connect.
But it may not be allowed to be created Azure service principal in our case. So is there any way to connect to key vault using MSI from locally running SpringBoot application.
using MSI_ENDPOINT
and MSI_SECRET
So is there any way to connect to key vault using MSI from locally running SpringBoot application.
using MSI_ENDPOINT and MSI_SECRET
I don't think you can use MSI_ENDPOINT and MSI_SECRET get the token in local, it just works when the web app published in the cloud.
But it may not be allowed to be created Azure service principal in our case.
As you know, you can use the service principal client id and secret(key) to access the keyvault. Actually, when enabling the MSI of the web app, it will create a service principal in your Azure AD tenant automatically. So you can just use the client id and secret of it.
Navigate to the portal -> Azure Active Directory -> Enterprise applications -> search for your web app name(select the Application Type with All Applications), then you get the client id(application id).
Note: Remember to check the object id of the service principal with that in your web app -> Identity, make sure you use the correct one.
For the service principal secret, you could create it via powershell like below(your account need the admin role Application administrator or Global administrator in your AAD tenant).
New-AzureADServicePrincipalPasswordCredential -ObjectId <service principal object id>
Then you will be able to access the keyvault with the client id and secret. For details in java, you can refer to this link.
You can't get it using those variables because locally there is no Azure AD Identity Registered on your local machine and as such Microsoft didn't build any MSI emulator so no variables will be set.
I can recommend what Microsoft did in their .NET library
Run Azure CLI and log in
In code check for variables and if they don't exist then run CLI command
az account get-access-token --resource 'https://vault.azure.net'
In CLI simply log into either principal or your account. Make sure to add this account/your account to KeyVault policy.
I know it's weird but I you can even check it HERE on their GitHub.
I might have an article that will help you in case you want more details
https://marczak.io/posts/2019/07/securing-websites-with-msi/

How to access destination service which is behind RabbitMQ using S4 Cloud SDK Connectivity

We are using S4SDK to access destination service. it needs to work in multi-tenancy env. Normally if the app is a frontend app, the request context is triggered by user request. Accessing destination service with multi-tenancy is doable with approuter and XUAA.
In our case, our application is behind RabbitMQ which is not trigger by a user request (e.g. REST API call). Currently we are using the class com.sap.cloud.sdk.cloudplatform.connectivity.DestinationAccessor from cloud SDK. we can retrieve a tenant id out of message (RabbitMQ/AMQP). The issue is that we cannot find a way to inject the tenant id or clone a JWT token into DestinationAccessor from S4SDK. We look for a way/guidance of how to achieve that. We expect this exchange/clone token is provided by the SDK.
You should be able to use the JwtBasedRequestContextExecutor for this purpose.
new JwtBasedRequestContextExecutor()
.withJwt(encodedJwt)
.execute(() -> {
// code using the SAP Cloud SDK
});

Developing UCWA applications for Skype for Business Online

I'm trying to develop a simple java client that needs to access Skype for Business APIs in order to setup an online meeting (i.e. I need to retrieve a simple setup meeting URL by invoking an UCWA API).
I followed this Microsoft tutorial step-by-step:
https://learn.microsoft.com/en-us/skype-sdk/ucwa/developingucwaapplicationsforsfbonline
I have an Office 365 Business Premium license and I configured a custom domain (correctly registered and added at the zone DNS file);
I configured and registered my java client app on Azure (taking care to assign required delegated permission for Skype for Business capabilities);
I performed the Sign-in phase and Azure is able to recognize me;
I performed the Autodiscovery phase in order to retrieve the user's UCWA home pool;
I sent a GET request to the Azure oauth2 endpoint with response 401 error (and this is the expected behaviour by the authentication handshake);
Unfortunately, I failed when I request an access token using implicit grant flow: Azure responds with a Sign-In HTML page rather than the json object containing the oauth2 access token.
What's wrong on this GET request?
GET https://login.microsoftonline.com/oauth2/authorize?
response_type=id_token
&client_id=my_application_client_id
&redirect_uri=configured_redirect_uri
&state=UUID_generated_code
&resource=UCWA_home_pool
HTTP/1.1
This GET URL looks like that one used for the Sign-In phase (step 3); I suspect that it isn't the right request URL.
I tryed to put my domain on the URL:
https://login.microsoftonline.com/my_domain_name/oauth2/authorize
and I tryed to put a common domain name (as reported on the documentation):
https://login.microsoftonline.com/common/oauth2/authorize
But Azure still reponds with a Sign-In page (and response code 200 OK).
Can someone help me please?
Please check the oauth2AllowImplicitFlow property in manifest of your application after downloading the latest manifest file. It should be set to true for this to wrok. If it's still false, only then I would expect the redirect to sign-in page as you're seeing.
More detailed steps here -
Configure your app for OAuth implicit grant flow

Categories

Resources