Here is my function:
public String uploadImage(URL image,String message) throws Exception{
HashMap<String,String> paramArgs=new HashMap<String,String>();
paramArgs.put("fbImgPostURL","https://graph.facebook.com/me/photos");
paramArgs.put("accessToken",accessGrant.getKey());
paramArgs.put("imageURL",image.toString());
paramArgs.put("message",message);
return HttpPictureUpload.uploadImageViaHttpPost(paramArgs);
}
and while i debug it from intelliJ debugger, strangely in the line
paramArgs.put("accessToken",accessGrant.getKey());
Clearly the key is accessToken. But the debugger shows it as follows:
access_token=CAACKan8suD0BAKUZAyxLinmXw2PZAkmkhIhVZCojG1sE2QsW60CfQjZAJWyMbqc1Lxy1JmVmSyAU4eHOGSkHhqJSQE6tcORuXAkyFbok7WGyysgJYZC6QF6KZBPRwDwbPCE6JUJgKIGyXzZCfzVgnjHHuoZBLZBt2xXgZD
So clearly the problem is that I am setting a different key name but in hash map, a different key name is being set which is actually passed to
HttpPictureUpload.uploadImageViaHttpPost(paramArgs);
Anyone here could guess that what is going on?
Edit:
Here is my uploadImageViaHttpPost() function:
public static String uploadImageViaHttpPost(HashMap<String,String> keyParams){
String in="Image Uploaded Successfully!!";
try {
HttpClient client = new HttpClient();
PostMethod method = new PostMethod(keyParams.get("fbImgPostURL"));
//Add any parameter if u want to send it with Post req.
method.addParameter("accessToken", keyParams.get("accessToken"));
method.addParameter("url",keyParams.get("imageURL"));
method.addParameter("message",keyParams.get("message"));
int statusCode = client.executeMethod(method);
if (statusCode != -1) {
in = method.getResponseBodyAsString();
}
System.out.println(in);
} catch (Exception e) {
e.printStackTrace();
}
return in;
}
Related
In Java How can we verify that i given String is a JWT Token without using Signature?
I am using
try {
return (new JwtConsumerBuilder()).setVerificationKey(SECRET_KEY).build().processToClaims(token);
} catch (InvalidJwtException var4) {
throw new IOException("Failed to parse");
}
This works fine but I want to verify this without SECRET_KEY.
I Just want to verify whether it is a JWT token or not.
Here is an example to check the structure of the JWT. You only need to add the validations of the data that the JWT should carry
boolean isJWT(String jwt) {
String[] jwtSplitted = jwt.split("\\.");
if (jwtSplitted.length != 3) // The JWT is composed of three parts
return false;
try {
String jsonFirstPart = new String(Base64.getDecoder().decode(jwtSplitted[0]));
JSONObject firstPart = new JSONObject(jsonFirstPart); // The first part of the JWT is a JSON
if (!firstPart.has("alg")) // The first part has the attribute "alg"
return false;
String jsonSecondPart = new String(Base64.getDecoder().decode(jwtSplitted[1]));
JSONObject secondPart = new JSONObject(jsonSecondPart); // The first part of the JWT is a JSON
//Put the validations you think are necessary for the data the JWT should take to validate
}catch (JSONException err){
return false;
}
return true;
}
You can decode JWT from base64 and check necessarily field. Or simply check token, why you want verify it, It's not faster then simpy check it.
Try this one.
public static JSONObject getPayload(String jwt) {
try {
Base64.Decoder dec = Base64.getDecoder();
final String payload = jwt.split(SecurityConstants.SPLIT_SLASH)[PAYLOAD];
final byte[] sectionDecoded = dec.decode(payload);
final String jwtSection = new String(sectionDecoded, SecurityConstants.CODE_PAGE);
return new JSONObject(jwtSection);
} catch (final UnsupportedEncodingException e) {
throw new InvalidParameterException(e.getMessage());
} catch (final Exception e) {
throw new InvalidParameterException(SecurityConstants.ERROR_IN_PARSING_JSON);
}
}
Next You need to get from jwt body this part which is important for You eg.
JSONObject body = JWTUtils.getPayload(token);
String username = body.getString("username");
I am very new to this concept, and I am trying to create a notification, which can be deleted or modified from server, by looking so I came across "apns-collapse-id". The problem is by setting this using the below code does not change the content of notification, it is just like an extra key added.
I'm trying to understand if i need to make any changes to make it work.
PushNotificationPayload payload = PushNotificationPayload.complex();
payload = new PushNotificationPayload(){
public int getMaximumPayloadSize()
{
return 2048;
}};
payload.addBadge(1);
payload.addSound("default"); //No I18N
payload.addCustomDictionary("rfid","testRfid");
payload.addAlert("test notification2");
JSONObject aps = payload.getPayload().getJSONObject("aps");
JSONObject apsAlert = null;
try
{
apsAlert = aps.getJSONObject("alert");
}
catch(JSONException jse)
{
apsAlert = new JSONObject();
try
{
String apsAlertMsg = aps.getString("alert");
if(apsAlertMsg!=null)
{
apsAlert.put("body",apsAlertMsg);
}
}
catch(JSONException jse1)
{
}
}
aps.put("content-available","1");
aps.put("apns-collapse-id", "12345");
I m adding code to delete multiple objects from S3. POST request to delete returns 403 status. I am adding this code in legacy code and unfortunately cannot change to change AWS S3 library. Not able to figure out if I am missing a header or if the logic is incorrect.
public Response deleteMultipleObjects(Delete object) throws MalformedURLException, IOException, StorageException {
HttpURLConnection request = null;
try(ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(out)) {
os.writeObject(object);
Calendar now = Calendar.getInstance();
Map<String, List<String>> headers = new HashMap<>();
headers.put(AWSAuthConnection.CONTENT_TYPE_HEADER, Arrays.asList("application/octet-stream"));
headers.put(AWSAuthConnection.CONTENT_LENGTH_HEADER, Arrays.asList(Integer.toString(out.toByteArray().length)));
headers.put(AWSAuthConnection.AMAZON_DATE_HEADER, Arrays.asList(convertDateToString(now, AWSAuthConnection.TIMESTAMP_FORMAT, AWSAuthConnection.TIME_ZONE_UTC)));
headers.put(AWSAuthConnection.AMAZON_CONTENT_SHA256_HEADER, Arrays.asList(buildHash(out.toByteArray(), SHA256_HASH, EncodingType.HEX)));
headers.put(AWSAuthConnection.CONTENT_MD5_HEADER, Arrays.asList(buildHash(out.toByteArray(), AWSAuthConnection.MD5_HASH, AWSAuthConnection.EncodingType.BASE64)));
request = makeRequest("POST", bucket+"/?delete", headers, null);
request.setDoOutput(true);
request.getOutputStream().write(object == null ? new byte[]{} : out.toByteArray());
return new Response(request);
}
}
private String buildHash(final byte[] contentToHash, final String hashMethod, final AWSAuthConnection.EncodingType encodingType) throws StorageException{
try {
MessageDigest digest = MessageDigest.getInstance(hashMethod);
byte[] contentHash = digest.digest(contentToHash);
if (encodingType == AWSAuthConnection.EncodingType.HEX) {
return Hex.encodeHexString(contentHash);
} else {
return Base64.encodeBase64String(contentHash);
}
} catch (NoSuchAlgorithmException e) {
throw new StorageException(StorageException.ERROR_INVALID_STORAGE_TYPE, e);
}
}
private HttpURLConnection makeRequest(String method, String resource, Map<String, List<String>> headers, StorageObject object) throws MalformedURLException, IOException {
URL url = makeURL(resource);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod(method);
connection.setUseCaches(true);
addHeaders(connection, headers);
if (object != null) addMetadataHeaders(connection, object.metadata);
addAuthHeader(connection, method, resource);
return connection;
}
private void addAuthHeader(HttpURLConnection connection, String method, String resource) {
String canonicalString =
Utils.makeCanonicalString(method, resource, connection.getRequestProperties());
String encodedCanonical = Utils.encode(this.info, canonicalString, false);
connection.setRequestProperty("Authorization", "AWS " + this.info + ":" + encodedCanonical);
}
Error from S3:
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>.......</Error>
Has anyone faced this issue before? If you know a way to fix, please help
I am very new to the GC platform and am trying to create an API in Java with two methods: one which returns a list of all of the files in a specific bucket and another which retrieves a specified file from that bucket. The goal is to be able to iterate the file list in order to download every file from the bucket. Essentially, I am wanting to mirror the contents of the bucket on an Android device, so the API will be called from a generated client library in an Android app.
My getFileList() method returns a ListResult object. How do I extract a list of files from this?
#ApiMethod(name = "getFileList", path = "getFileList", httpMethod = ApiMethod.HttpMethod.GET)
public ListResult getFileList(#Named("bucketName") String bucketName) {
GcsService gcsService = GcsServiceFactory.createGcsService(RetryParams.getDefaultInstance());
ListResult result = null;
try {
result = gcsService.list(bucketName, ListOptions.DEFAULT);
return result;
} catch (IOException e) {
return null; // Handle this properly.
}
}
Also, I am struggling to determine what the return type of my getFile() API method should be. I can’t use a byte array since return types cannot be simple types as I understand it. This is where I am with it:
#ApiMethod(name = "getFile", path = "getFile", httpMethod = ApiMethod.HttpMethod.GET)
public byte[] getFile(#Named("bucketName") String bucketName, ListItem file) {
GcsService gcsService = GcsServiceFactory.createGcsService();
GcsFilename gcsFilename = new GcsFilename(bucketName, file.getName());
ByteBuffer byteBuffer;
try {
int fileSize = (int) gcsService.getMetadata(gcsFilename).getLength();
byteBuffer = ByteBuffer.allocate(fileSize);
GcsInputChannel gcsInputChannel = gcsService.openReadChannel(gcsFilename, 0);
gcsInputChannel.read(byteBuffer);
return byteBuffer.array();
} catch (IOException e) {
return null; // Handle this properly.
}
}
I am lost in the Google documentation for this stuff and am concerned that I am coming at it from completely the wrong direction since all I am trying to do is securely download a bunch of files!
I can't give you a complete solution because, this is code I wrote for my company, but I can show you some basics. I use the google-cloud-java API.
First you need to create an API key and download this in JSON format. More details can be found here.
I have - amongst other - these two fields in my class:
protected final Object storageInitLock = new Object();
protected Storage storage;
First you will need a method to initialize a com.google.cloud.storage.Storage object, something like (set your project-id and path to json api key):
protected final Storage getStorage() {
synchronized (storageInitLock) {
if (null == storage) {
try {
storage = StorageOptions.newBuilder()
.setProjectId(PROJECTID)
.setCredentials(ServiceAccountCredentials.fromStream(new FileInputStream(pathToJsonKey)))
.build()
.getService();
} catch (IOException e) {
throw new MyCustomException("Error reading auth file " + pathToJsonKey, e);
} catch (StorageException e) {
throw new MyCustomException("Error initializing storage", e);
}
}
return storage;
}
}
to get all entries you could use something like:
protected final Iterator<Blob> getAllEntries() {
try {
return getStorage().list(bucketName).iterateAll();
} catch (StorageException e) {
throw new MyCustomException("error retrieving entries", e);
}
}
list files in a directory:
public final Optional<Page<Blob>> listFilesInDirectory(#NotNull String directory) {
try {
return Optional.ofNullable(getStorage().list(getBucketName(), Storage.BlobListOption.currentDirectory(),
Storage.BlobListOption.prefix(directory)));
} catch (Exception e) {
return Optional.empty();
}
}
get info about a file:
public final Optional<Blob> getFileInfo(#NotNull String bucketFilename) {
try {
return Optional.ofNullable(getStorage().get(BlobId.of(getBucketName(), bucketFilename)));
} catch (Exception e) {
return Optional.empty();
}
}
adding a file:
public final void addFile(#NotNull String localFilename, #NotNull String bucketFilename,
#Nullable ContentType contentType) {
final BlobInfo.Builder builder = BlobInfo.newBuilder(BlobId.of(bucketName, bucketFilename));
if (null != contentType) {
builder.setContentType(contentType.getsValue());
}
final BlobInfo blobInfo = builder.build();
try (final RandomAccessFile raf = new RandomAccessFile(localFilename, "r");
final FileChannel channel = raf.getChannel();
final WriteChannel writer = getStorage().writer(blobInfo)) {
writer.write(channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()));
} catch (Exception e) {
throw new MyCustomException(MessageFormat.format("Error storing {0} to {1}", localFilename,
bucketFilename), e);
}
}
I hope these code snippets and the referenced documentation will get you going, actulally it's not too hard.
I'm trying to post 2 fields, id and data, to a servlet using HttpClient.
The problem is that if the length of the data field is less than 1MB or so, the servlet will get what I posted. But if the length of the data field is larger than 1MB or so, the servlet will receive null for all fields. What am I missing here? Thanks.
Here's the sample data that I post to the servlet:
id=12312123123123
data=the content of a file that is base-64 encoded
Here's the method that I use to post data to the servlet.
private byte[] post(String aUrl,
Map<String,String> aParams,
String aCharsetEnc,
int aMaxWaitMs) throws Exception
{
PostMethod post = null;
try
{
HttpClient client = new HttpClient();
post = new PostMethod(aUrl);
post.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=" + aCharsetEnc);
for (String key : aParams.keySet())
{
post.addParameter(key, aParams.get(key));
}
final int code = client.executeMethod(post);
if (code == HttpStatus.SC_NO_CONTENT || code == HttpStatus.SC_NOT_FOUND)
{
return null;
}
else if (code != HttpStatus.SC_OK)
{
throw new HttpException("Error code " + code + " encountered.");
}
InputStream stream = post.getResponseBodyAsStream();
if (stream != null)
{
return BlobHelper.readBytes(stream);
}
return null;
}
finally
{
if (post != null)
{
post.releaseConnection();
}
}
}
Here's the method of the servlet.
public void doPost(HttpServletRequest aReq, HttpServletResponse aResp)
throws ServletException, IOException
{
setNoCache(aResp);
aResp.setContentType("text/plain");
try
{
final String id = aReq.getParameter(PARAM_ID);
final String dataStr = aReq.getParameter(PARAM_DATA);
if (log().isDebugEnabled())
{
log().debug("id=" + id);
log().debug("data=" + dataStr);
}
}
catch (Exception e)
{
}
}
Usually servlet containers have a maximum post size parameter.
For Tomcat you can follow the steps documented here(they should be similar for other appservers) -
Is there a max size for POST parameter content?