com.google.cloud.storage.StorageException: 401 Unauthorized - java

I am trying to get this sample working without success
I installed and initialized the client:
export CLOUD_SDK_REPO="cloud-sdk-$(lsb_release -c -s)"
echo "deb https://packages.cloud.google.com/apt $CLOUD_SDK_REPO main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
sudo apt-get update \
&& sudo apt-get -y install google-cloud-sdk \
&& sudo apt-get -y install google-cloud-sdk-app-engine-java \
&& sudo apt-get -y install google-cloud-sdk-app-engine-python \
gcloud init
Then I authenticated successfully:
gcloud auth activate-service-account 13672300789-compute#developer.gserviceaccount.com --key-file=DockerStorage-e7def0adcafb.json
Then I tried the quick start sample:
Storage storage = StorageOptions.getDefaultInstance().getService();
String bucketName = "my-first-bucket"; // "my-new-bucket";
Bucket bucket = storage.create(BucketInfo.of(bucketName));
System.out.printf("Bucket %s created.%n", bucket.getName());
BOOM unauthorized
Exception in thread "main" com.google.cloud.storage.StorageException: 401 Unauthorized
What did I miss?

At first, You have to a generate a Service account credential.
Generating a service account credential
To generate a private key in JSON or PKCS12 format:
Open the list of credentials in the Google Cloud Platform Console.
Google Cloud Platform Console
Click Create credentials.
Select Service account key.
A Create service account key window opens.
Click the drop-down box below Service account, then click New service account.
Enter a name for the service account in Name.
Use the default Service account ID or generate a different one.
Select the Key type: JSON or P12.
Click Create.
Then simply use the credential json file in you code.
StorageOptions storageOptions = StorageOptions.newBuilder()
.setProjectId("YOUR_PROJECT_ID")
.setCredentials(GoogleCredentials.fromStream(new
FileInputStream("path/YOUR_SERVICE_ACCOUNT_CRENDENTIAL.json"))).build();
Storage storage = storageOptions.getService();

Hrm...good question. Theoretically this should work If you don't otherwise specify auth, that library will first attempt to use the credentials file specified by the GOOGLE_APPLICATION_CREDENTIALS environment variable, and if that's not set, it should go looking for your gcloud credentials.
I'm guessing that it can't find your gcloud credentials for some reason. By default, they'll be in the ".config/gcloud" directory under your home directory, but that can be overridden. Maybe check to see if there're some files there?
One thing worth trying is simply copying a service account's JSON file to that machine and specifying the path to it with the GOOGLE_APPLICATION_CREDENTIALS environment variable. That shouldn't be necessary, but if that fails as well, something more interesting is going on.

Related

Inject application.properties value in GitLab CICD

Currently my tech stack is Java, Spring Boot.
I am using application-dev.properties to keep the AWS access key and secret key.
In application-dev.properties to inject the keys I have:
#This property provide access key details
com.abc.sqs.accesskey = AWS_ACCESS_KEY
#This property provide secret key details
com.abc.sqs.secretkey = AWS_SECRET_KEY
Now from GitLab CICD .gitlab-ci.yml file while I am trying to smoke test of the application .jar I have something like this (stage is smoke test) -
smoke test:
stage: smoke-test
image: openjdk:12-alpine
before_script:
- apk add --update curl && rm -rf /var/cache/apk/*
script:
- ls -la ./app-service/target/
- sed -i "s/AWS_ACCESS_KEY/$AWS_ACCESS_KEY_ID/" ./app-service/src/main/resources/application-dev.properties
- sed -i "s/AWS_SECRET_KEY/$AWS_SECRET_ACCESS_KEY/" ./app-service/src/main/resources/application-dev.properties
- java -jar -Dspring.profiles.active=dev ./app-service/target/app-service.jar &
- sleep 30
- curl http://localhost:5000/actuator/health | grep "UP"
- curl -i -X POST http://localhost:5000/actuator/shutdown
Here I am bringing $AWS_ACCESS_KEY_ID and $AWS_SECRET_ACCESS_KEY from GitLab CICD environment variables and trying to replace AWS_ACCESS_KEY and AWS_SECRET_KEY of properties file. But this way I am not able to inject during start of the server.
While trying to test the jar getting following exception:
Caused by: com.amazonaws.services.sqs.model.AmazonSQSException: The
security token included in the request is invalid. (Service:
AmazonSQS; Status Code: 403; Error Code: InvalidClientTokenId;
Please need your suggestion.
Advance thanks.
If you want to override properties in a properties file, instead of using sed, you can simply declare an environment variable or a JVM variable with a similar name. It will have the priority over properties declare in file.
For instance:
com.abc.sqs.accesskey = AWS_ACCESS_KEY
Can become with a JVM variable:
java -jar -Dspring.profiles.active=dev -Dcom.abc.sqs.accesskey=$AWS_ACCESS_KEY_ID ./app-service/target/app-service.jar
This will override the value of the properties file, and this will be available on application startup.

How do I authenticate my Java application with Google Cloud Storage?

I am writing a Java application to interact with files in Google Cloud Storage. I found gcloud-java which I'm trying to get working.
Looking at their examples it seems I should be able to simply run them after having logged-in with gcloud, but it doesn't seem to be working. I'm trying to run StorageExample, which says "logged-in project will be used if not supplied", but despite logging in I cannot access my project whether I specify it or not.
$ gcloud auth login
Your browser has been opened to visit:
https://accounts.google.com/o/oauth2/auth?....
Saved Application Default Credentials.
You are now logged in as [...].
Your current project is [...]. You can change this setting by running:
$ gcloud config set project PROJECT_ID
$ java -cp GCloudDemo.jar com.google.gcloud.examples.storage.StorageExample list
Exception in thread "main" java.lang.IllegalArgumentException: A project ID is required for this service but could not be determined from the builder or the environment. Please set a project ID using the builder.
at com.google.common.base.Preconditions.checkArgument(Preconditions.java:122)
at com.google.gcloud.ServiceOptions.<init>(ServiceOptions.java:317)
...
at com.google.gcloud.examples.storage.StorageExample.main(StorageExample.java:566)
$ java -cp GCloudDemo.jar com.google.gcloud.examples.storage.StorageExample ... list
Exception in thread "main" com.google.gcloud.storage.StorageException: Login Required
at com.google.gcloud.spi.DefaultStorageRpc.translate(DefaultStorageRpc.java:94)
at com.google.gcloud.spi.DefaultStorageRpc.list(DefaultStorageRpc.java:148)
...
at com.google.gcloud.examples.storage.StorageExample$ListAction.run(StorageExample.java:1)
at com.google.gcloud.examples.storage.StorageExample.main(StorageExample.java:579)
Caused by: com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized
{
"code" : 401,
"errors" : [ {
"domain" : "global",
"location" : "Authorization",
"locationType" : "header",
"message" : "Login Required",
"reason" : "required"
} ],
"message" : "Login Required"
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:145)
...
at com.google.gcloud.spi.DefaultStorageRpc.list(DefaultStorageRpc.java:138)
... 10 more
Clearly something is wrong with my environment, but what do I have to do to fix it? I'd like to correct my environment rather than make changes to the example.
Notes:
I'm running in Cygwin 2.0.4 on Windows 10
I'm not building via Maven, but I assume that isn't the source of the problem
The reason gcloud auth login isn't working is because Java doesn't play well with Cygwin, specifically with regards to absolute paths.
gcloud stores your settings and credentials in your Cygwin home directory, ~/.config/gcloud, but Java is going to look for them in your Windows home directory via System.getProperty("user.home"). You can specify where the application should look for this directory via the CLOUDSDK_CONFIG environment variable, like so (be sure to only specify it when calling java; setting it for your shell will in turn break gcloud):
$ CLOUDSDK_CONFIG=$(cygpath -w ~/.config/gcloud) \
java -cp GCloudDemo.jar com.google.gcloud.examples.storage.StorageExample list
Exception in thread "main" com.google.gcloud.storage.StorageException: Login Required
at ....
Notice that that we didn't have to specify a project, but we're still not logged in for some reason. It turns out the demo app doesn't do a great job of reporting authentication errors. Adding an explicit call to AuthCredentials.createApplicationDefaults() at the start of the main() method reports a much more helpful error message:
Exception in thread "main" java.io.IOException: The Application Default Credentials are
not available. They are available if running in Google Compute Engine. Otherwise, the
environment variable GOOGLE_APPLICATION_CREDENTIALS must be defined pointing to a
file defining the credentials. See https://developers.google.com/accounts/docs/application-default-credentials
for more information.
So now we at least have the GOOGLE_APPLICATION_CREDENTIALS environment variable to go on. But why isn't gcloud configuring things for us? It looks like that's actually a bug in the library; it should now be able to find our login token.
In the meantime, we can workaround it by explicitly specifying the credentials path as well:
$ CLOUDSDK_CONFIG=$(cygpath -w ~/.config/gcloud) \
GOOGLE_APPLICATION_CREDENTIALS=$(cygpath -w ~/.config/gcloud)/application_default_credentials.json \
java -cp GCloudDemo.jar com.google.gcloud.examples.storage.StorageExample list
Bucket{name=...}
Success!

Separating jhipster back-end and front-end into two projects?

I'm trying jhipster with token-based authentication. It works perfectly.
Now, I want to run back-end and front-end code on different domains. How can I do this?
This is what I tried:
Run yo jhipster and select token-based authentication option:
Welcome to the JHipster Generator
? (1/13) What is the base name of your application? jhipster
? (2/13) What is your default Java package name? com.mycompany.myapp
? (3/13) Do you want to use Java 8? Yes (use Java 8)
? (4/13) Which *type* of authentication would you like to use? Token-based authentication (stateless, with a token)
? (5/13) Which *type* of database would you like to use? SQL (H2, MySQL, PostgreSQL)
? (6/13) Which *production* database would you like to use? MySQL
? (7/13) Which *development* database would you like to use? H2 in-memory with Web console
? (8/13) Do you want to use Hibernate 2nd level cache? Yes, with ehcache (local cache, for a single node)
? (9/13) Do you want to use clustered HTTP sessions? No
? (10/13) Do you want to use WebSockets? No
? (11/13) Would you like to use Maven or Gradle for building the backend? Maven (recommended)
? (12/13) Would you like to use Grunt or Gulp.js for building the frontend? Grunt (recommended)
? (13/13) Would you like to use the Compass CSS Authoring Framework? No
...
I'm all done. Running bower install & npm install for you
^C
Make two copies of the project as jhipster/backend and jhipster/frontend
Delete unnecessary files from back-end and front-end
rm -rf backend/.bowerrc
rm -rf backend/.jshintrc
rm -rf backend/bower.json
rm -rf backend/Gruntfile.js
rm -rf backend/package.json
rm -rf backend/src/main/webapp
rm -rf backend/src/test/javascript
rm -rf frontend/pom.xml
rm -rf frontend/src/main/java
rm -rf frontend/src/main/resources
rm -rf frontend/src/test/gatling
rm -rf frontend/src/test/java
rm -rf frontend/src/test/resources
Make changes in code to completely remove backend/frontend dependency
frontend/Gruntfile.js
...
var parseVersionFromPomXml = function() {
return '1.2.2.RELEASE';
};
...
browserSync: { ..., proxy: "localhost:8081" }
frontend/src/main/webapp/scripts/app/app.js
angular.module('jhipsterApp', [...])
.constant('API_URL', 'http://localhost:8080/')
.run( ... )
frontend/src/main/webapp/scripts/**/*.service.js
angular.module('jhipsterApp').factory(..., API_URL) {
return $http.post(API_URL + 'api/authenticate', ...);
}
angular.module('jhipsterApp').factory('Account', function Account($resource, API_URL) {
return $resource(API_URL + 'api/account', {}, {...});
}
// Make similar changes in all service files.
backend/pom.xml
Remove yeoman-maven-plugin
backend/src/main/java/com/mycompany/myapp/SimpleCORSFilter.java
// Copied from here: https://spring.io/guides/gs/rest-service-cors/
#Component
public class SimpleCORSFilter implements Filter {
public void doFilter(...) {
...
response.setHeader("Access-Control-Allow-Origin", "*");
...
}
}
Run
Terminal Tab #1: BACKEND
cd backend
mvn spring-boot:run
...
[INFO] com.mycompany.myapp.Application - Started Application in 11.529 seconds (JVM running for 12.079)
[INFO] com.mycompany.myapp.Application - Access URLs:
----------------------------------------------------------
Local: http://127.0.0.1:8080
External: http://192.168.56.1:8080
----------------------------------------------------------
Terminal Tab #2: FRONTEND
cd frontend/src/main/webapp
npm install -g http-server
http-server
Starting up http-server, serving ./ on: http://0.0.0.0:8081
Hit CTRL-C to stop the server
Terminal Tab #3: GRUNT
cd frontend
bower install
npm install
grunt serve
...
[BS] Proxying: http://localhost:8081
[BS] Access URLs:
-------------------------------------
Local: http://localhost:3000
External: http://10.34.16.128:3000
-------------------------------------
UI: http://localhost:3001
UI External: http://10.34.16.128:3001
-------------------------------------
Browse http://localhost:3000/#/login
Enter username:password as admin:admin
Our BACKEND tab reads:
[DEBUG] com.mycompany.myapp.security.Http401UnauthorizedEntryPoint - Pre-authenticated entry point called. Rejecting access
Apparently, I'm doing something wrong. What is it?
When requests fail due to CORS, there is no visible error on the backend. The HTTP request actually succeeds, but is blocked on the front-end side by javascript. A message like this one will appear in the JS console.
XMLHttpRequest cannot load http://localhost:8080/api/authenticate. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access.
The error message you're seeing is actually related to authentication. When you enable CORS, your JS will send ''pre-flight'' requests using the HTTP OPTIONS method. JHipster isn't configured to allow the OPTIONS method globally. I ran into this exact same problem myself while doing the same thing you did. The fix is very simple: just add this line to your com.mycompany.config.SecurityConfiguration immediately preceding (before) the first antMatchers entry.
.antMatchers(org.springframework.http.HttpMethod.OPTIONS, "/api/**").permitAll()
This will explicitly allow all requests with the OPTIONS method. The OPTIONS method is used in CORS as a way to read all of the headers and see what HTTP methods are allowed in the CORS request.
Finally, in your SimpleCORSFilter class, you should also add these headers:
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "86400"); // 24 Hours
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, x-auth-token");
Separating frontend and backend in JHipster application is quite simple. Please follow the steps mentioned below if you want to setup frontend and backend applications separately and individually using JHipster:
Create two directories for frontend and backend applications
mkdir frontend
mkdir backend
change your directory to frontend and run the JHipster command to create just frontend module
cd frontend
jhipster --skip-server --db=sql --auth=jwt
if all works fine, run npm start command to run your frontend application.
I'm using mysql for db and JWT for auth and if you want to use websockets you add: "--websocket=spring-websocket"
Now, change your directory to the backend and run JHipster command to create just backend module
cd .. //as we are ing backend directory currently
cd backend
jhipster --skip-client
Run your backend application as you run your spring boot application
Now, your frontend and backend application are running separately and individually and frontend is coordinating with the backend application via REST API calls.
In addition to xeorem's answer above, I also had to modify the parse-links-service.js to handle the preflight OPTIONS responses, which don't have the "link" response header:
var links = {};
if (!angular.isObject()) {
// CORS OPTIONS responses
return links;
}
if (header.length == 0) {
throw new Error("input must not be of zero length");
}
// Split parts by comma
var parts = header.split(',');
...
Instead of adding API_URL to app.js, modify Gruntfile.js and add the API_URL to the ngConstants block for both DEV and PROD environments.
You can use CORS filter from Tomcat. Put Tomcat dependency in the pom.xml:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>8.0.15</version>
<scope>provided</scope>
</dependency>
Use whatever version of Tomcat you use.
Add CORS filter initialization in WebConfigurer:
private void initCorsFilter(ServletContext servletContext, EnumSet<DispatcherType> disps) {
log.debug("Registering CORS Filter");
FilterRegistration.Dynamic corsFilter = servletContext.addFilter("corsFilter", new CorsFilter());
Map<String, String> parameters = new HashMap<>();
parameters.put("cors.allowed.headers", "Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization");
parameters.put("cors.allowed.methods", "GET,POST,HEAD,OPTIONS,PUT,DELETE");
corsFilter.setInitParameters(parameters);
corsFilter.addMappingForUrlPatterns(disps, false, "/*");
corsFilter.setAsyncSupported(true);
}
put this line in WebConfigurer.onStartup(...), put it as close to the top as possible.
...
initCorsFilter(servletContext, disps);
...
I'm using Jhipster version 4.14.5
I have copied the following files to a project-forntend folder:
.bowerrc
gulp
pom.xml
yarn.lock
gulpfile.js
readme.md
bower_components
.gitattributes
src/main/web
bower.json
.gitignore
package.json
target/www
Then ran:
yarn install
bower install
gulp install
Then changed to the gulp/config.js file to :
apiPort: 8081
uri: 'http://localhost:'
Then started the project by running:
gulp serve

Jenkins - could not read Username for 'https://github.com': No such device or address

I'm trying to set up Jenkins / Hudson on my Ubuntu PC. That's not the problem but I set an Android job with the following commands:
export CLEAN=false
export LUNCH=cm_ace-userdebug
export REPO_BRANCH=cm-10.1
export RELEASE_TYPE=CM_NIGHTLY
curl -O https://raw.github.com/CyanogenMod/hudson/master/job.sh
. ./job.sh
The job stops after a few seconds because of the error:
could not read Username for 'https://github.com': No such device or address
How do I fix this error?
Please help!
I suspect that Jenkins is attempting to open "/dev/tty" or something to ask you for a user name and password. That is failing because Jenkins is running as a daemon ... and "/dev/tty" can't be used in that context. The "No such device or address" comes from the failed attempt to open "/dev/tty".
The solution would be to configure the job to use a specific private key for the fetch. Read the curl manual entry and check out the -E option. Alternatively, you could use -u and specify the username and password in the curl command.

CodeCollaborator error:please see the 'svn upgrade' command

I want to install the tool of CodeCollaborator to manager the code in my development,but there has a install error i cannot handle it.
I trusted that the CodeCollaborator client was installed successful.
When i click the button of add in the CodeCollaborate Client,and then Add CSM Configration successful.
When chose the SCM Cofigration to Add Changes,it always show error as below:
Error initializing changed files
Reason:svn:E155036:please see the 'svn upgarade' command
svn:E155036:Working copy 'E:\woekplace\chunya' is too old(formate 10,create by Subversion 1.6)
I think the error is result by the version between Slik-Subversion-1.7.8-x64 and Subersion in my eclipse, but no matter how i to upgrade the version each other, the error has unswerving exist.How to solve this problem?
Typing svn help upgrade at a Windows command prompt (or svn --help upgrade in a Linux terminal) shows this:
upgrade: Upgrade the metadata storage format for a working copy.
usage: upgrade [WCPATH...]
Local modifications are preserved.
Valid options:
-q [--quiet] : print nothing, or only summary information
Global options:
--username ARG : specify a username ARG
--password ARG : specify a password ARG
--no-auth-cache : do not cache authentication tokens
--non-interactive : do no interactive prompting
--trust-server-cert : accept SSL server certificates from unknown
certificate authorities without prompting (but only
with '--non-interactive')
--config-dir ARG : read user configuration files from directory ARG
--config-option ARG : set user configuration option in the format:
FILE:SECTION:OPTION=[VALUE]
For example:
servers:global:http-library=serf
So it's telling you you need to upgrade your local working copy's metadata, not upgrade SVN itself. You do that also from a command prompt or terminal window, using the syntax shown by the usage example above.

Categories

Resources