Unable to connect to key vault using spring boot - java

I am following this part in the tutorial for integrating key vault with spring boot.
We have everything setup for using Managed identities (application.properties and dependency in pom) and since it doesn't run in local development, I am testing it by deployment, however I am getting these errors in the log stream:
java.io.FileNotFoundException:/home/tomcat/lib/azure.appservice.jar (No such file or directory)
and
java.lang.IllegalStateException: Failed to configure KeyVault property source
java.io.IOException: Server returned HTTP response code: 400 for URL: Http://xxx.xx.x.x.x
EDIT: turned out I had a typo error in the client-id property.

make sure the application has permissions to get and list secrets in access policies of your key vault and also check the jar files are added properly.
Edit the src/main/resources/application.properties file so that it has the following contents, adjusting the values for your Azure subscription.c
azure.keyvault.client-id=<your client ID>
azure.keyvault.client-key=<your client key>
azure.keyvault.enabled=true
azure.keyvault.tenant-id=<your tenant ID>
azure.keyvault.uri=https://contosokv.vault.azure.net/
After adding azure.keyvault.tenant-id=<your-tenant-id> in the file:
For more details refer this document and follow this Github code

Related

Azure AD configuration for Spring Boot

I tried to integrate Azure AD with a Spring Boot web application, I followed the example from the Azure's documentation but I encountered an error message: "[invalid_request] AADSTS9000411: The request is not properly formatted. The parameter 'scope' is duplicated...", as shown in the below screenshot.
I can't find any scope parameter to figure out why it says is duplicated.
I have in the application.properties file the following setup:
spring.cloud.azure.active-directory.enabled=true
#Specifies your Active Directory ID:
spring.cloud.azure.active-directory.credential.client-id=...
spring.cloud.azure.active-directory.profile.tenant-id=...
spring.cloud.azure.active-directory.credential.client-secret=...
Does anyone had the same issue?

how to point spring cloud config server to a folder decided by client if git is the version control

Am trying spring cloud config server and client as stand-alone separate applications.
on git, i have folder structure like below-
my-config
----projectfolder1
--------application.properties
----projectfolder2
--------application.properties
I would like that spring cloud client named "projectfolder1" should search application.properties within projectfolder1 on git from spring cloud server i.e
----projectfolder1
--------application.properties
and client "projectfolder2" should get the below mentioned properties from spring cloud config server
----projectfolder2
--------application.properties
My Spring Cloud Config server application.properties has-
spring.cloud.config.server.git.search-paths='{application}'
projectfolder1 in its bootstrap.properties has
spring.application.name=projectfolder1
and projectfolder2 in its bootstrap.properties has
spring.application.name=projectfolder2
According to spring cloud config documentation '{application}' in search path should find the files within the "resolved application name" folder on git. But the above '{application}' doesn't work for me. Clients projectfolder1 and projectfolder2 are not able to get any property at all.
pls assist. i know its possible duplicate of another question on stack overflow. but that question is not resolved and i do not have rights to comment on any question being a new user, So i created this as another question here.
I solved it myself.
The trick is to give search-path {application} without quotes as given below.
It was a little tricky as spring documentation mentions it as '{application}' , probably spring developers just wanted to highlight it with quotes.
spring.cloud.config.server.git.search-paths={application}
instead of
spring.cloud.config.server.git.search-paths='{application}'

Getting list of file names from GIT repo from Spring cloud config server

I am using Spring cloud config server with GIT which is working fine as expected.
Now, my requirement is to get the list of filenames from the spring cloud server.
Spring cloud config only provides API like http://localhost:8088/myconfig/default/master/config.properties to get the property values.
Is there any API available to get all file names? If not, what would be the alternate approach?
No, unfortunately it's not possible. The way we did in our project - added properties with needed file names in config.properties and fetched files in the code using
additional endpoint at /{name}/{profile}/{label}/{path}
https://cloud.spring.io/spring-cloud-config/reference/html/#_serving_plain_text

Spring boot is not able to get configuration file from my file system

I am trying to build a sample app on Spring boot and spring cloud.
I have written my database and hibernate configuration in config.properties property file which is located in my desktop and I want my spring boot to make use of this configuration.
My project have 3 modules
API
DataLayer
ServiceLayer
This is the code that I have mentioned in the application.property file of API
spring.profiles.active=native
spring.cloud.config.server.native.searchLocation=C:/Users/DEV/Desktop/configuration/config.properties
and the property file of DataLayer and ServiceLayer is empty
But when I run the API I am getting the following error
***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
Action:
Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).
Process finished with exit code 1
Could any one help me with this error.
Thanks in advance.
This is can not be done from your API module. You added configuration server properties to your 'client' (from configuration point of view) application.
If you want to use Spring Cloud Config to configure your project you should have separate application that will manage your configuration. Let's call it config-server. (You should properly configure maven or gradle dependencies, see documentation) To configure usage of native profile in the config-server in application.properties you have to add properties that you mentioned in the question (example for native profile).
spring.profiles.active=native
spring.cloud.config.server.native.searchLocation=file:<path-to-the-directory-with-conf-files> or classpath:/<path-to-the-directory-with-conf-files>
Note: config-server can handle configuration for lot of services.
More can be found in the documentation Spring Cloud Config Server section.
Then in your API (or any other module) which is a spring boot app you should add spring-cloud-config-client dependency and add bootstrap.properties (or .yml) configuration file. There your should add properties that will describe communication with config-server. By default config-server listens on port 8888.
spring.application.name=<your app name>
spring.cloud.config.uri=http://localhost:8888 # this is also default value for this property
At start-up it will go by http to config-server and fetch your configuration properties based on service name (spring.application.name).
More can be found in Spring Cloud Config client section
Important: make sure your properly organize files in your configuration directory (which is used by native profile by config-server), find some samples. Property files naming are important. For start you can try to use your-application-name.properties
You have to have file: prefixed to the property file location.
Documentation from https://cloud.spring.io/spring-cloud-config/multi/multi__spring_cloud_config_server.html
There is also a “native” profile in the Config Server that does not use Git but loads the config files from the local classpath or file system (any static URL you want to point to with spring.cloud.config.server.native.searchLocations). To use the native profile, launch the Config Server with spring.profiles.active=native.
[Note]
Remember to use the file: prefix for file resources (the default without a prefix is usually the classpath). As with any Spring Boot
configuration, you can embed ${}-style environment placeholders, but
remember that absolute paths in Windows require an extra / (for
example, file:///${user.home}/config-repo).
[Warning]
The default value of the searchLocations is identical to a local Spring Boot application (that is, [classpath:/, classpath:/config,
file:./, file:./config]). This does not expose the
application.properties from the server to all clients, because any
property sources present in the server are removed before being sent
to the client.
[Tip] A filesystem backend is great for getting started quickly and for testing. To use it in production, you need to be sure that the
file system is reliable and shared across all instances of the Config
Server.

AWS Instance Profile doesn't work with Spring Cloud AWS

I have a small Spring Boot app, using Spring Cloud AWS (1.0.0.RELEASE) to access SQS queue. It is beeing deployed on an EC2 instance with Instance Profile set. It appears that AWS side of things is working, as I can access both relevant metadata links: iam/info and iam/security-credentials/role-name, and they do contain correct information. Just to be sure, I've used aws cmdline utility (aws sqs list-queues) and it does work, so I guess setup is ok. However, when the app starts, it reads application.properties (which contains line cloud.aws.credentials.instanceProfile=true) then drops following warning: com.amazonaws.util.EC2MetadataUtils: Unable to retrieve the requested metadata and finally throws following exception:
Caused by: com.amazonaws.AmazonServiceException: The security token included in the request is invalid. (Service: AmazonSQS; Status Code: 403; Error Code: InvalidClientTokenId; Request ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:1071)
at com.amazonaws.http.AmazonHttpClient.executeOneRequest(AmazonHttpClient.java:719)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:454)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:294)
at com.amazonaws.services.sqs.AmazonSQSClient.invoke(AmazonSQSClient.java:2291)
at com.amazonaws.services.sqs.AmazonSQSClient.getQueueUrl(AmazonSQSClient.java:516)
at com.amazonaws.services.sqs.buffered.AmazonSQSBufferedAsyncClient.getQueueUrl(AmazonSQSBufferedAsyncClient.java:278)
at org.springframework.cloud.aws.messaging.support.destination.DynamicQueueUrlDestinationResolver.resolveDestination(DynamicQueueUrlDestinationResolver.java:78)
at org.springframework.cloud.aws.messaging.support.destination.DynamicQueueUrlDestinationResolver.resolveDestination(DynamicQueueUrlDestinationResolver.java:37)
at org.springframework.messaging.core.CachingDestinationResolverProxy.resolveDestination(CachingDestinationResolverProxy.java:88)
at org.springframework.cloud.aws.messaging.listener.AbstractMessageListenerContainer.start(AbstractMessageListenerContainer.java:295)
at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer.start(SimpleMessageListenerContainer.java:38)
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:173)
... 17 common frames omitted
...which means that for some reason Spring Cloud AWS is not picking up on Instance Profile credentials. I've enabled debug log level on com.amazonaws.request and it appears that request is sent without access key and secret key.
DEBUG --- com.amazonaws.request : Sending Request: POST https://sqs.eu-west-1.amazonaws.com / Parameters: (Action: GetQueueUrl, Version: 2012-11-05, QueueName: xxxxxxxxxxxxx, ) Headers: (User-Agent: aws-sdk-java/1.9.3 Linux/3.14.35-28.38.amzn1.x86_64 Java_HotSpot(TM)_64-Bit_Server_VM/25.45-b02/1.8.0_45 AmazonSQSBufferedAsyncClient/1.9.3, )
Anybody has any idea what am I missing or at least any hints how to further debug this?
EDIT: After going through spring-cloud-aws code a bit, I've kinda moved forward. Configuration file application.properties bundled with jar had some text value for accessKey and secretKey. My customized application.properties haven't got those properties and that probably caused spring to use values in bundled file as defaults. I've included them with empty values, which changed the exception to com.amazonaws.AmazonClientException: Unable to load AWS credentials from any provider in the chain. It appears that AWS SDK is configured with DefaultProviderChain, yet it still fails to pick up instance profile credentials.
The solution to this problem comes from two distinct facts.
Instance profile credentials are going to be used only and only if application.properties has instanceProfile property set to true and accessKey set to null (ContextCredentialsAutoConfiguration).
Even if you will provide your custom application.properties file, Spring is going to read application.properties file bundled with app jar (if it does exist). If that's the case, properties from both files will sum up to create an execution enviroment. I suspect that bundled file is parsed first, then custom second, overriding any property present in bundled file.
In my case, bundled application.properties had accessKey and secretKey placeholders (with phony values) which were filled out by developer whenever he wanted some testing outside of EC2 enviroment. That made accessKey not null and therefore, excluded instance profile path. I just removed the application.properties file from jar and that solved the problem.
cloud:
aws:
credentials:
accessKey:
secretKey:
instanceProfile: true
useDefaultAwsCredentialsChain: true
This would do the trick, if you were using the latest (2.X.X) Spring AWS Cloud.

Categories

Resources