Retreiveing Encoded Value from URL - java

I have passes a encoded SSO token in URL...so the URL looks like
http://127.0.0.1:7101/CRMOD_UCM-Sankalp-context-root/BrowseFile.jsp?token=%246%24zhxjx%2fpz6dVucl9cgG43ii2Tr4qVnNbeqJg8jCy6Jj7vRvXN4%3d%3b%246%24GlRGp%2fxfEM308NZGmY%2fhjHav2yjHSvbww1l0%2fCcCtcVjzl%2bCQFlQPdBRKO0t1XUmF0I6xLmfQ%2fnb7VgJeSYnvrAb9YUQQ3tvr%2fBZ%2bIRZiBAGU2%2fZg%3d
but when i retreive the value of variable and print it using
out.println("SSO Token:"+request.getParameter("token"));
it prints
$6$zhxjx/pz6dVucl9cgG43ii2Tr4qVnNbeqJg8jCy6Jj7vRvXN4=;$6$GlRGp/xfEM308NZGmY/hjHav2yjHSvbww1l0/CcCtcVjzl+CQFlQPdBRKO0t1XUmF0I6xLmfQ/nb7VgJeSYnvrAb9YUQQ3tvr/BZ+IRZiBAGU2/Zg=
The correct token is which is present in the URL, WHY i am getting such a different value in my print...
Kindly help......

request.getParameter("token") decodes the parameter value, so the value that gets printed is the decoded version of the parameter value in the URL.
See Java EE, accent in url, request.getParameter wrong value for more information.

In the URL, the token is URL encoded. This is necessary because some characters have special meanings in an URL.
By URL encoding the value, those special characters are replaced by %nn codes where nn is the character code of the special character.
Java automatically decodes it for you, so that you get the actual value when you call request.getParameter("token") instead of the URL-encoded value.

You are getting encoded value if you want decode then use following code. By default system decode for us but in your case it is not decoded and you must explicitly decode value of request.getParameter("token").
String token = request.getParameter("token").toString();
// To decode url
String decodedtoken = URLDecoder.decode(token , "UTF-8");
System.out.println("Decoded token value "+ decodedtoken);
// To encode url
String encodedtoken = URLEncoder.encode(token , "UTF-8");
System.out.println("Encoded token value "+ encodedtoken);

Related

encode some key's value of String URL for HTTP Get Request

I need to encode only parameters of the string url.
my string url is like: http://127.0.0.1:8070/app/api/fetchData?channel=abc&param=status:new|addr:null|roomId:Default&group=iPh&reqtype=p1&serialNo=123890&codeId=A1_8uh&type=p
I want to encode value of param(key).I am working on spring boot project.
Please suggest some solution.
If you're making the request from Java, you can encode a string using base64 like this[1]:
String originalInput = "test input";
String encodedString = Base64.getEncoder().encodeToString(originalInput.getBytes());
I guess my first thought would be to encode the parameters that you want this way and then concatenate the whole thing together. What value are you trying to get out of encoding the parameters?
[1] https://www.baeldung.com/java-base64-encode-and-decode

Token encode/decode issue - Spring

I have problem using UrlEncoder and UrlDecoder.
It looks like this:
Example of token:
3vv3XIvofg3KIoMjLwU07329C6dsk8HJceuDT2F5jOwox2hyqAnL+03TPej/lW4TCeFWRadRkPKgW0aGxq+9B1VZLMvoevyFfaVXhvzIyLF8AN3NDCqk0hoqb51wlGtb4hUvOYKq5b63wuW2pfssr9O0dgCEK4VZz8QZ4jRpxZw=
I set token on Customer in my Spring Application. Then I encode token to use it in url:
String token = // generated by mechanism
String encodedToken = UrlEncoder.encode(token, "UTF-8");
String url = "https://myapp.url?token=" + encodedToken;
I receive token as a #RequestParam. Then the token is decoded by UrlDecoder
String decodedToken = UrlDecoder.decode(token, "UTF-8");
The problem is as follows:
Sometimes it works correctly and I am able to find user by token, but sometimes I have error, because decoded token is invalid, and it looks different than token. What is the problem? It is strange because sometimes it works, sometimes not
Your token will already be decoded by Spring because of the #RequestParam annotation.
If the token contains a +, the second decoding will replace the + with a (white space).
I am assuming you are using java.net.URLEncoder and java.net.URLDecoder? As the Javadoc of the encode(String, String) and decode(String, String) methods describes, they encode to and decode from the application/x-www-form-urlencoded format. In this format, the + is a special character replacing a space.
So a + will be encoded to %2B and decoded to . Because Spring will already have taken care of the decoding, the %2B will be a + again. Your second decoding translates it to a and the tokens won't match anymore.

Extract parameters from URL

I have problems with the character +(and maybe others) at the URIBuilder is suppose to get a decoded url but when I extract the query the + is replaced
String decodedUrl = "www.foo.com?sign=AZrhQaTRSiys5GZtlwZ+H3qUyIY=&more=boo";
URIBuilder builder = new URIBuilder(decodedUrl);
List<NameValuePair> params = builder.getQueryParams();
String sign = params.get(0).getValue();
the value of sing is AZrhQaTRSiys5GZtlwZ H3qUyIY= with a space instead +. How can I extract the correct value?
other way is:
URI uri = new URI(decodedUrl);
String query = uri.getQuery();
the value of query is sign=AZrhQaTRSiys5GZtlwZ+H3qUyIY=&more=boo in this case is correct, but I have to strip it. Is there another way to do that?
Use it differently:
String decodedUrl = "www.foo.com";
URIBuilder builder = new URIBuilder(decodedUrl);
builder.addParameter("sign", "AZrhQaTRSiys5GZtlwZ+H3qUyIY=");
builder.addParameter("more", "boo");
List<NameValuePair> params = builder.getQueryParams();
String sign = params.get(0).getValue();
addParameter method is responsible for adding parameters as to the builder. The constructor of the builder should include the base URL only.
If this URL is given to you as is, then the + is already decoded and stands for the space character. If you are the one who generates this URL, you probably skipped the URL encoding step (which can be done using the code snipped above).
Read a bit about URL encoding: http://en.wikipedia.org/wiki/Query_string#URL_encoding
That is because if you send space as parameter in url it is encoded as +. This happens because there are some rules which characters are valid in URL. See URL RFC.
It is necessary to encode any characters disallowed in a URL, including spaces and other binary data not in the allowed character set, using the standard convention of the "%" character followed by two hexadecimal digits.
If you want to have + as symbol in url you need to encode it into %2B. For example 2+2 is encoded as 2%2B2 and i am as i+am. So in your case I believe you have to correct result as AZrhQaTRSiys5GZtlwZ+H3qUyIY decodes into AZrhQaTRSiys5GZtlwZ H3qUyIY.

URL encoding + sign

I have an application with + sign in its name (eg. DB+JSP.jws).
I get an error when trying to create connection as java encodes url + with spaces and hence cannot add the connection to DB JSP/../META-INF/connection.xml (File not found exception).
Any way to circumvent this only by using URLEncoder.encode() and URLDecoder.decode() methods?
You need to encode the URL correctly since '+' is a reserved character in a URL and can only be used in the correct context otherwise needs to be encoded with %2B.
Your URL string would encoded as "DB%2BJSP.jws".
So if you defined the following:
String url = URLEncoder.encode("DB+JSP.jws");
System.out.println(url);
The output would be the same:
DB%2BJSP.jws
You can prepend "http://localhost/" to the encoded URL as you need to.

How to find out if string has already been URL encoded?

How could I check if string has already been encoded?
For example, if I encode TEST==, I get TEST%3D%3D. If I again encode last string, I get TEST%253D%253D, I would have to know before doing that if it is already encoded...
I have encoded parameters saved, and I need to search for them. I don't know for input parameters, what will they be - encoded or not, so I have to know if I have to encode or decode them before search.
Decode, compare to original. If it does differ, original is encoded. If it doesn't differ, original isn't encoded. But still it says nothing about whether the newly decoded version isn't still encoded. A good task for recursion.
I hope one can't write a quine in urlencode, or this algorithm would get stuck.
Exception: When a string contains "+" character url decoder replaces it with a space even though the string is not url encoded
Use regexp to check if your string contains illegal characters (i.e. characters which cannot be found in URL-encoded string, like whitespace).
Try decoding the url. If the resulting string is shorter than the original then the original URL was already encoded, else you can safely encode it (either it is not encoded, or even post encoding the url stays as is, so encoding again will not result in a wrong url). Below is sample pseudo (inspired by ruby) code:
# Returns encoded URL for any given URL after determining whether it is already encoded or not
def escape(url)
unescaped_url = URI.unescape(url)
if (unescaped_url.length < url.length)
return url
else
return URI.escape(url)
end
end
You can't know for sure, unless your strings conform to a certain pattern, or you keep track of your strings. As you noted by yourself, a String that is encoded can also be encoded, so you can't be 100% sure by looking at the string itself.
Check your URL for suspicious characters[1].
List of candidates:
WHITE_SPACE ,", < , > , { , } , | , \ , ^ , ~ , [ , ] , . and `
I use:
private static boolean isAlreadyEncoded(String passedUrl) {
boolean isEncoded = true;
if (passedUrl.matches(".*[\\ \"\\<\\>\\{\\}|\\\\^~\\[\\]].*")) {
isEncoded = false;
}
return isEncoded;
}
For the actual encoding I proceed with:
https://stackoverflow.com/a/49796882/1485527
Note: Even if your URL doesn't contain unsafe characters you might want to apply, e.g. Punnycode encoding to the host name. So there is still much space for additional checks.
[1] A list of candidates can be found in the section "unsafe" of the URL spec at Page 2.
In my understanding '%' or '#' should be left out in the encoding check, since these characters can occur in encoded URLs as well.
Using Spring UriComponentsBuilder:
import java.net.URI;
import org.springframework.web.util.UriComponentsBuilder;
private URI getProperlyEncodedUri(String uriString) {
try {
return URI.create(uriString);
} catch (IllegalArgumentException e) {
return UriComponentsBuilder.fromUriString(uriString).build().toUri();
}
}
If you want to be sure that string is encoded correctly (if it needs to be encoded) - just decode and encode it once again.
metacode:
100%_correctly_encoded_string = encode(decode(input_string))
already encoded string will remain untouched. Unencoded string will be encoded. String with only url-allowed characters will remain untouched too.
According to the spec (https://www.rfc-editor.org/rfc/rfc3986) all URLs MUST start with a scheme followed by a :
Since colons are required as the delimiter between a scheme and the rest of the URI, any string that contains a colon is not encoded.
(This assumes you will not be given an incomplete URI with no scheme.)
So you can test if the string contains a colon, if not, urldecode it, and if that string contains a colon, the original string was url encoded, if not, check if the strings are different and if so, urldecode again and if not, it is not a valid URI.
You can make this loop simpler if you know what schemes you can expect.
Thanks to this answer I coded a function (JS Language) that encodes the URL just once with encodeURI so you can call it to make sure is encoded just once and you don't need to know if the URL is already encoded.
ES6:
var getUrlEncoded = sURL => {
if (decodeURI(sURL) === sURL) return encodeURI(sURL)
return getUrlEncoded(decodeURI(sURL))
}
Pre ES6:
var getUrlEncoded = function(sURL) {
if (decodeURI(sURL) === sURL) return encodeURI(sURL)
return getUrlEncoded(decodeURI(sURL))
}
Here are some tests so you can see the URL is only encoded once:
getUrlEncoded("https://example.com/media/Screenshot27 UI Home.jpg")
//"https://example.com/media/Screenshot27%20UI%20Home.jpg"
getUrlEncoded(encodeURI("https://example.com/media/Screenshot27 UI Home.jpg"))
//"https://example.com/media/Screenshot27%20UI%20Home.jpg"
getUrlEncoded(encodeURI(encodeURI("https://example.com/media/Screenshot27 UI Home.jpg")))
//"https://example.com/media/Screenshot27%20UI%20Home.jpg"
getUrlEncoded(decodeURI("https://example.com/media/Screenshot27 UI Home.jpg"))
//"https://example.com/media/Screenshot27%20UI%20Home.jpg"
getUrlEncoded(decodeURI(decodeURI("https://example.com/media/Screenshot27 UI Home.jpg")))
//"https://example.com/media/Screenshot27%20UI%20Home.jpg"

Categories