GCS bucket generating presigned url for uploads - java

I am trying to generate the presigned url for uploading files to buckets in GCS. But am having the following error when trying to open the link in the browser. Following is my code
package test;
import com.google.auth.Credentials;
import com.google.auth.ServiceAccountSigner;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.cloud.storage.BlobId;
import com.google.cloud.storage.BlobInfo;
import com.google.cloud.storage.HttpMethod;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageException;
import com.google.cloud.storage.StorageOptions;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public class TestGcs {
public static void main(String args[]) throws FileNotFoundException, IOException {
String extracted = extracted();
System.out.println(extracted);
}
private static String extracted() throws IOException, FileNotFoundException, UnsupportedEncodingException {
Credentials credentials = getCreds();
Storage storage = StorageOptions.newBuilder()
.setCredentials(credentials)
.setProjectId("<<project ID>>")
.build()
.getService();
BlobInfo blobInfo = BlobInfo.newBuilder(BlobId.of("<<bucketname>>", "<<object Nmae>>")).build();
// Generate Signed URL
Map<String, String> extensionHeaders = new HashMap<>();
extensionHeaders.put("Content-Type", "application/octet-stream");
URL url = storage.signUrl(blobInfo, 1, TimeUnit.HOURS,
Storage.SignUrlOption.httpMethod(HttpMethod.PUT),
Storage.SignUrlOption.signWith((ServiceAccountSigner) getCreds()),
Storage.SignUrlOption.withExtHeaders(extensionHeaders),
Storage.SignUrlOption.withV4Signature());
return URLDecoder.decode(url.toString(), StandardCharsets.UTF_8.name());
}
private static Credentials getCreds() throws IOException, FileNotFoundException {
Credentials credentials = GoogleCredentials.fromStream(new FileInputStream("<<Json service account key path>>"));
return credentials;
}
}
I get the following error when accesing through browser. The service account role has storage admin role.
<Error>
<Code>MalformedSecurityHeader</Code>
<Message>Your request has a malformed header.</Message>
<ParameterName>content-type</ParameterName>
<Details>Header was included in signedheaders, but not in the request.</Details>
</Error>

Related

GoogleAuthException 401 Unauthorized

I am trying to run google drive api starter code in my local and it is working fine when it is using com.google.api.client.auth.oauth2.Credential and results in 401 when it is using
com.google.auth.oauth2.GoogleCredentials.
I am a newbie, sorry if this is a stupid question. Please help me, I am trying to upload a file to my drive, it is working with a service account, but the upload is happening to the service account and I don't know how to access the service account files.
Here is the starter code I am using:
package com.google.drive.api.try;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.FileList;
import com.google.drive.api.try.write.UploadBasic;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.GeneralSecurityException;
import java.util.List;
public class DriveQuickstart {
private static final String APPLICATION_NAME = "Google Drive API Java Quickstart";
private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();
private static final String TOKENS_DIRECTORY_PATH = "tokens";
private static final String CREDENTIALS_FILE_PATH = "/credentials.json";
private static Drive service;
public static void main(String... args) throws IOException {
init();
UploadBasic.uploadBasic();
FileList result = service.files().list().setPageSize(10).setFields("nextPageToken, files(id, name)").execute();
List<File> files = result.getFiles();
if (files == null || files.isEmpty()) {
System.out.println("No files found.");
} else {
System.out.println("Files:");
for (File file : files) {
System.out.printf("%s (%s)\n", file.getName(), file.getId());
}
}
}
private static void init() {
try {
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
service = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
.setApplicationName(APPLICATION_NAME).build();
} catch (Exception e) {
e.printStackTrace();
}
}
private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
InputStream in = DriveQuickstart.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
if (in == null) {
throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
}
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY,
clientSecrets, DriveScopes.all())
.setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
.setAccessType("offline").build();
LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
Credential credential = new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
return credential;
}
}
UploadBasic.java
package com.google.drive.api.try.write;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.FileContent;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.IOException;
import java.util.Arrays;
public class UploadBasic {
public static String uploadBasic() throws IOException {
GoogleCredentials credentials = GoogleCredentials.getApplicationDefault()
.createScoped(Arrays.asList(DriveScopes.DRIVE_FILE));
HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials);
// Build a new authorized API client service.
Drive service = new Drive.Builder(new NetHttpTransport(), GsonFactory.getDefaultInstance(), requestInitializer)
.setApplicationName("Drive samples").build();
// Upload file photo.jpg on drive.
File fileMetadata = new File();
fileMetadata.setName("photo.jpg");
// File's content.
java.io.File filePath = new java.io.File("files/photo.jpg");
// Specify media type and file-path for file.
FileContent mediaContent = new FileContent("image/jpeg", filePath);
try {
File file = service.files().create(fileMetadata, mediaContent).setFields("id").execute();
System.out.println("File ID: " + file.getId());
return file.getId();
} catch (GoogleJsonResponseException e) {
// TODO(developer) - handle error appropriately
System.err.println("Unable to upload file: " + e.getDetails());
throw e;
}
}
}

Getting java.nio.file.AccessDeniedException , when trying to create zip file using java NIO 2 on MAC

import java.io.IOException;
import java.net.URI;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.util.HashMap;
import java.util.Map;
public class ZipFileSystem {
public static void main(String[] args) throws IOException {
URI uri = URI.create("jar:file:///sample.zip");
Map<String,String> options = new HashMap<>();
options.put("create","true");
FileSystem fileSystem = FileSystems.newFileSystem(uri, options);
}
}
I have this java simple code , when i try to run this on MAC, getting below exception, am I missing anything?
Exception in thread "main" java.nio.file.AccessDeniedException: /sample.zip
at sun.nio.fs.UnixException.translateToIOException(UnixException.java:84)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
at sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:214)
at java.nio.file.spi.FileSystemProvider.newOutputStream(FileSystemProvider.java:434)
at java.nio.file.Files.newOutputStream(Files.java:216)
at com.sun.nio.zipfs.ZipFileSystem.<init>(ZipFileSystem.java:116)
at com.sun.nio.zipfs.ZipFileSystemProvider.newFileSystem(ZipFileSystemProvider.java:117)
at java.nio.file.FileSystems.newFileSystem(FileSystems.java:326)
at java.nio.file.FileSystems.newFileSystem(FileSystems.java:276)
at ZipFileSystem.main(ZipFileSystem.java:14)

/ExampleApplication/IntrusionException] INTRUSION - Mixed encoding (2x) detected in URL

I am retrieving URL from database and it contains special characters like % - = / ? etc. so while I try to populate that in my page JSON is not able to parse that URL and it is giving me some exception when I was debugging I got like this
(Log4JLogger.java:log:449) [SECURITY FAILURE Anonymous:null#unknown -> /ExampleApplication/IntrusionException] INTRUSION - Mixed encoding (2x) detected
I tried from these link here this my offending URL here
but it is not working he mentioned that bug is solved. but for which version version here I am using is 2.1.0 below is my code
package com.ghn.repufact.review.extractor;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import javax.ws.rs.core.UriBuilder;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.log4j.Logger;
import org.owasp.esapi.ESAPI;
import org.owasp.esapi.Encoder;
import org.owasp.esapi.Validator;
import org.owasp.esapi.errors.EncodingException;
import org.owasp.esapi.reference.DefaultValidator;
import org.springframework.stereotype.Component;
#Component
public class ValidateURL {
private static final Logger logger=Logger.getLogger(ValidateResponse.class);
public String parseOrgConsumerLink(String myLink) throws URISyntaxException {
if(myLink==null || "".equalsIgnoreCase(myLink))
return myLink;
Encoder enc=ESAPI.encoder();
URI mixURI=new URI(myLink);
UriBuilder uriBuider=UriBuilder.fromUri(enc.canonicalize(mixURI.getAuthority()+mixURI.getPath()));
uriBuider.path(enc.canonicalize(mixURI.getAuthority() + mixURI.getPath()));
logger.info("Uri after URIbuilder:"+uriBuider.build().toString());
List<NameValuePair> params = URLEncodedUtils.parse(mixURI, "UTF-8");
for (NameValuePair nameValuePair : params)
uriBuider.queryParam(enc.canonicalize(nameValuePair.getName()), enc.canonicalize(nameValuePair.getValue()));
String canonicalizedUrl = uriBuider.build().toString();
logger.info("canonicaliz URI:"+canonicalizedUrl);
return canonicalizedUrl;
}
public boolean isCanonicalizedURI(String myLink) throws EncodingException {
Validator validator=DefaultValidator.getInstance();
//boolean flag=validator.isValidInput("test", myLink, "URI", 200, false);
myLink = ESAPI.encoder().encodeForURL(myLink);
boolean flag = validator.isValidInput("APPNAME", myLink, "URLSTRING", 600, true, false);
logger.info("checking for URI:"+myLink+" isCanonical:"+flag);
return flag;
}
}
please let me know if any work around here. By the way I am using spring MVC

Gmail API configuration issue (in Java)

Here is my Gmail service configuration/factory class:
import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.gmail.Gmail;
import com.google.api.services.gmail.GmailScopes;
public class GmailServiceFactoryBean {
private #Autowired Environment env;
private final NetHttpTransport transport;
private final JacksonFactory jacksonFactory;
public GmailServiceFactoryBean() throws GeneralSecurityException, IOException {
this.transport = GoogleNetHttpTransport.newTrustedTransport();
this.jacksonFactory = JacksonFactory.getDefaultInstance();
}
public Gmail getGmailService() throws IOException, GeneralSecurityException {
return new Gmail.Builder(transport, jacksonFactory, getCredential())
.setApplicationName(env.getProperty("gmail.api.application.name")).build();
}
private HttpRequestInitializer getCredential() throws IOException, GeneralSecurityException {
File p12File = new File(this.getClass().getClassLoader().getResource("google-key.p12").getFile());
Credential credential = new GoogleCredential.Builder()
.setServiceAccountId(env.getProperty("gmail.api.service.account.email"))
.setServiceAccountPrivateKeyId(env.getProperty("gmail.api.private.key.id"))
.setServiceAccountPrivateKeyFromP12File(p12File)
.setTransport(transport)
.setJsonFactory(jacksonFactory)
.setServiceAccountScopes(GmailScopes.all())
//.setServiceAccountUser(env.getProperty("gmail.api.user.email"))
.build();
credential.refreshToken();
return credential;
}
}
Here is my inner mailing service that uses previous bean under the hood:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.List;
import java.util.Properties;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import com.google.api.client.repackaged.org.apache.commons.codec.binary.Base64;
import com.google.api.services.gmail.Gmail;
import com.google.api.services.gmail.model.Message;
import com.example.factory.GmailServiceFactoryBean;
import com.example.service.MailService;
import com.example.service.exception.MailServiceException;
#Service
public class MailServiceImpl implements MailService {
private #Autowired GmailServiceFactoryBean gmailServiceFactoryBean;
private #Autowired Environment env;
#Override
public void send(com.example.model.Message message, String recipient) throws MailServiceException {
try {
Gmail gmailService = gmailServiceFactoryBean.getGmailService();
MimeMessage mimeMessage = createMimeMessage(message, recipient);
Message gMessage = createMessageWithEmail(mimeMessage);
gmailService.users().messages().send("me", gMessage).execute();
} catch(MessagingException | IOException | GeneralSecurityException e) {
throw new MailServiceException(e.getMessage(), e.getCause());
}
}
#Override
public void send(com.example.model.Message message, List<String> recipients) throws MailServiceException {
for (String recipient : recipients) {
send(message, recipient);
}
}
private MimeMessage createMimeMessage(com.example.model.Message message, String recipient) throws MessagingException {
Session session = Session.getDefaultInstance(new Properties());
MimeMessage email = new MimeMessage(session);
InternetAddress toAddress = new InternetAddress(recipient);
InternetAddress fromAddress = new InternetAddress(env.getProperty("gmail.api.service.account.email"));
email.setFrom(fromAddress);
email.addRecipient(RecipientType.TO, toAddress);
email.setSubject(message.getTitle());
email.setText(message.getContent(), env.getProperty("application.encoding"));
return email;
}
private Message createMessageWithEmail(MimeMessage email) throws MessagingException, IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
email.writeTo(baos);
return new Message().setRaw(Base64.encodeBase64URLSafeString(baos.toByteArray()));
}
}
When I execute method send(Message message, String recipient) of class MailServiceImpl I get following response:
400 Bad Request
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"message" : "Bad Request",
"reason" : "failedPrecondition"
} ],
"message" : "Bad Request"
}
Does anyone know what's wrong?
For GMail API to work, you have to "Delegate domain-wide authority to the service account" within your Google Apps account.
Service account doesn't represent a human Google account. You also can't delegate authority to whole Google domain(***#gmail.com).
The other way out could be with OAuth 2.0 for Web Server Applications or Java Mail api
For more do check: GMail REST API: Using Google Credentials Without Impersonate
Check if you have enabled gmail to send mails using 3rd party applications.
Go to my account ->Sign in and Security -> Connected Apps
now scroll to the bottom of the page you will get Less secure apps ->change it to on !!
Hope this will work

Consume Java weblogic web service having usernametoken and client certificate in ASP.Net

i need to consume a web service developed with java web logic server, usernametoken and client certificate are used to invoke the service.
and i got the java code to call web service as below
import javax.ejb.CreateException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.rmi.RemoteException;
import weblogic.wtc.jatmi.TPException;
import weblogic.wtc.jatmi.TypedString;
import weblogic.wtc.jatmi.Reply;
import weblogic.wtc.jatmi.TuxedoReply;
import weblogic.wtc.jatmi.TPServiceInformation;
import weblogic.wtc.jatmi.TypedFML32;
import weblogic.wtc.jatmi.TuxedoService;
import weblogic.wtc.jatmi.TypedBuffer;
import java.util.StringTokenizer;
import java.io.IOException;
import javax.xml.rpc.ServiceException;
import MMSWbSrv.*;
import java.util.Properties;
import java.text.SimpleDateFormat;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.FileInputStream;
import java.security.cert.X509Certificate;
import weblogic.security.SSL.TrustManager;
import weblogic.xml.crypto.wss.provider.CredentialProvider;
import weblogic.xml.crypto.wss.WSSecurityContext;
import weblogic.wsee.security.bst.ClientBSTCredentialProvider;
import weblogic.wsee.security.unt.ClientUNTCredentialProvider;
import java.security.cert.X509Certificate;
import weblogic.wsee.security.util.CertUtils;
import javax.xml.rpc.Stub;
import java.util.List;
import java.util.ArrayList;
import java.util.regex.*;
import weblogic.wtc.jatmi.TypedFML32;
public class MMSTest
{
public static void main(String args[]) throws Throwable
{
Properties sysProps = System.getProperties();
sysProps.setProperty("http.proxyHost","XXX.XX.X.XX");
sysProps.setProperty("http.proxyPort","XXXX");
sysProps.setProperty("weblogic.webservice.transport.http.proxy.host", "XXX.XX.X.XX");
sysProps.setProperty("weblogic.webservice.transport.http.proxy.port", "XXXX");
sysProps.setProperty("http.proxySet","true");
sysProps.setProperty("weblogic.webservice.verbose","true");
sysProps.setProperty("javax.net.ssl.trustStore","D:/weblogic92/server/lib/DemoTrust.jks");
System.out.println("proxyHost::"+ sysProps.getProperty("http.proxyHost"));
System.out.println("proxyPort::"+ sysProps.getProperty("http.proxyPort"));
MMSService service = null;
MMSPortType port = null;
try{
System.out.println("before..");
service = new MMSService_Impl("http://XXX.XX.X.XX/MMS/Service?wsdl");
System.out.println("after..");
if(service==null)
System.out.println("NULL SERVICE");
System.out.println("got service...");
port = service.getMMSServicePort();
if(port==null)
System.out.println("NULL PORT");
}
catch(ServiceException svcEx)
{
System.out.println("In ServiceXexception");
}
List credProviders = new ArrayList();
System.out.println("After cred");
String clientCertFile = "F:/client-cert.der";
String keyFile = "F:/client-key-pkcs8.der";
String username = "userName" ;
String password = "Password" ;
CredentialProvider cp = new ClientBSTCredentialProvider(clientCertFile, keyFile);
credProviders.add(cp);
System.out.println("credProviders:"+credProviders);
System.out.println("cp:"+cp+":");
String strret= "";
try{
cp = new ClientUNTCredentialProvider(username, password);
credProviders.add(cp);
Stub stub = (Stub)port;
System.out.println("before");
stub._setProperty(WSSecurityContext.CREDENTIAL_PROVIDER_LIST, credProviders);
System.out.println("after");
stub._setProperty(WSSecurityContext.TRUST_MANAGER,
new TrustManager()
{
public boolean certificateCallback(X509Certificate[] chain, int validateErr)
{
return true;
}
}
);
String strArg = "Parameters";
strret = port.sendData(strArg);
}
catch(Exception e)
{
System.out.println("JJJ");
e.printStackTrace();
}
System.out.println("strret:"+strret);
}
}
and also .pfx format client certificate and .key file .
So using WSE3.0 i try to consume the service like below
WebReference.MMSServiceWse wse = new MMSServiceWse();
UsernameToken token = new UsernameToken("XXXX", "XXXX", PasswordOption.SendPlainText);
wse.RequestSoapContext.Security.Tokens.Add(token);
X509Certificate2 cert = new X509Certificate2(#"D:\\certificate.pfx","",X509KeyStorageFlags.MachineKeySet);
wse.ClientCertificates.Add(cert);
wse.SetPolicy("ClientPolicy");
//System.Net.ServicePointManager.CertificatePolicy =new TrustAllCertificatePolicy();
String strArg = "Param";
strArg= wse.sendData(strArg);
but i have got exception.
When this happens to me, it is usually because the time on the server and the client are too different. The security token has a validity period and if you're not in sync, it seems expired or worse, in the future.

Categories