jwt Signature exception while decoding - jwt

I am facing Signature exception while adding security to my Spring Rest services. Please help.
io.jsonwebtoken.SignatureException: JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted.
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:354)
//Make Token
String token = Jwts.builder()
.setSubject(((User) auth.getPrincipal()).getUsername())
.signWith(SignatureAlgorithm.HS512, SECRET.getBytes("UTF-8"))
.compact();
res.addHeader(HEADER_STRING, TOKEN_PREFIX + token);
// Decoding token
String token = request.getHeader(HEADER_STRING);
if (token != null) {
// parse the token.
String jwt = token.replace(TOKEN_PREFIX, "");
try {
Claims claims = Jwts.parser()
.setSigningKey(SECRET.getBytes("UTF-8"))
.parseClaimsJws(jwt)
.getBody();
if (claims.getSubject() != null) {
return new UsernamePasswordAuthenticationToken(claims.getSubject(), null, getAuthorities());
}
}
When I am printing both, I am getting the below text. One is having extra space. This is happening only when I am hitting the service using Rest client. Test classes are working fine.
makeToken= eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJza3AifQ.XUEsUFF3qm6fOeCG8xDLuRWjyd4kOh4g01olU_BsRyfqyI66MRhqmK-mxrAWsD17Ylmj-fZRRZUTRqxCQixxXQ
decodeToken=
eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJza3AifQ.XUEsUFF3qm6fOeCG8xDLuRWjyd4kOh4g01olU_BsRyfqyI66MRhqmK-mxrAWsD17Ylmj-fZRR ZUTRqxCQixxXQ

It's late but worth If someone is facing the same issue while decoding JWT token.
Library GitHub link:
https://github.com/auth0/JWTDecode.Android
Implementation:
implementation ('com.auth0.android:jwtdecode:1.2.0'){
exclude group: 'com.android.support', module: 'appcompat-v7'
}
Code:
// token: eyJ0eXAiOiJKV1QiLCJhbxxxxxxx9.eyJpZC*********************UEFUSUVOVCIsImV4cCI6MTU2NTY5MzU5MCwib3JpZ0lhdCI6MTU2NTA4ODc5MH0.ZhPpZSFZL6EY-Mwrw0F*********MYmbw
private void getExpDate(String token) {
JWT jwt = new JWT(token);
Log.e(TAG,"Claim - id:"+jwt.getClaim("id").asString()+" - username:"+jwt.getClaim("username").asString()+" - role:"+jwt.getClaim("role").asString()+" - exp:"+jwt.getClaim("exp").asString());
}
Logcat Result:
E/PatientLogin: Claim - id:cd5dbe61-xxxx-xxxx-xxxx-xxxxxx - username:xxxx#gmail.com - role:PATIENT - exp:1565693590
Test JWT Token:
If you want to check your JWT token then use below link.
https://jwt.io/
OR
Here is another method which might work for you as well. This will help to avoid using a third-party library.
Reference: Orignal post
decoded(token);
public static String decoded(String JWTEncoded) {
String[] split = JWTEncoded.split("\\.");
Log.e(TAG, "Header: " + getJson(split[0]));
Log.e(TAG, "Body: " + getJson(split[1]));
return getJson(split[1]);
}
private static String getJson(String strEncoded){
String str_dec = "";
try {
byte[] decodedBytes = Base64.decode(strEncoded, Base64.URL_SAFE);
str_dec = new String(decodedBytes, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return str_dec;
}

Related

How can I get "Amazon.Extensions.CognitoAuthentication.CognitoUserSession.IDToken" From AWSCredentials?

I want get "Amazon.Extensions.CognitoAuthentication.CognitoUserSession.IDToken" From AWSCredentials.
I have AWSCredentials From Oauth Google Login.
public AWSCredentials GetAWSCredentials_Google(string token)
{
CognitoAWSCredentials credentials = new CognitoAWSCredentials(FED_POOL_ID, regionTable[REGION]);
credentials.AddLogin("accounts.google.com", token);
return credentials;
}
And, I use EC2 Instance and my ubuntu server is in there. Also, I was originally using a method of accessing the server by receiving a membership from Cognito User Pool, so I was using the following code.
private IEnumerator sendPostUser()
{
string uri = rootUrl + "/user";
string json = "{ ... }";
byte[] jsonData = System.Text.Encoding.UTF8.GetBytes(json);
using (UnityWebRequest request = UnityWebRequest.Post(uri, json))
{
if (request.uploadHandler != null)
request.uploadHandler.Dispose();
request.disposeUploadHandlerOnDispose = true;
request.disposeDownloadHandlerOnDispose = true;
request.uploadHandler = new UploadHandlerRaw(jsonData);
/* Header */
request.SetRequestHeader("Content-Type", "application/json");
request.SetRequestHeader("token", cloud_acess.GetComponent<ControlCloud>().cognitoUser.SessionTokens.IdToken);
/* Send Message */
yield return request.SendWebRequest();
...
}
By the way, there was a problem with this code "request.SetRequestHeader("token", cloud_acess.GetComponent().cognitoUser.SessionTokens.IdToken);".
This cognitouser means Amazon.Extensions.CognitoAuthentication.CognitoUser.
My Project get CognitoUser using user's ID and PW, and get AWSCredentials using this Cognitouser. But Google Login doesn't this process and just get credentials.
So, I can't get "cognitoUser.SessionTokens.IdToken". It makes me cannot to request anything from ec2 server.
How Can i get this? What should I do if the premise of this problem itself is wrong?
I tried to put all the tokens I received when I logged in to Google and the tokens I received as credentials in the header.But I failed.

How To set and get content of Payload in JWT Token

I have created a JWT Token in Spring Boot for storing User Details. When I use Jwttokenutil.getUsernameFromToken(authToken) [ authToken is the token passed ] method I get the data set to Subject. Similarly I want to get the data set to Payload which contains other User Details. But I am not able to get it.
======= Below is my token generation method / code : ========
public String generateToken(HashMap<String, Object> userData,String subject)
{
String jwtToken="";
System.out.println("in generate token method : " + subject);
jwtToken = Jwts.builder()
.setSubject(subject) // subject is dbname
.claim("userDetails", userData)
.setPayload(userData.toString())
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 60*60*5*1000))
.signWith(SignatureAlgorithm.HS256, "secretkey")
.compact();
System.out.println("userData " + userData);
return jwtToken;
}
======= Below is the method I have created to get the Payload data ======
public Object getPayloadFromToken(String token)
{
Claims body= Jwts.parser()
.setSigningKey("secretkey")
.parseClaimsJws(token)
.getBody();
System.out.println("userdet==========> " + body.get("userDetails") );
return body.get("userDetails");
}
=== But I am getting this error ===
java.lang.IllegalStateException: Both 'payload' and 'claims' cannot both be specified. Choose either one.
Late but I hope it serves someone.
.setPayload (...) is used to create a payload defined by us, the error that you get with claims is because .setPayload (...) should not be used with any of the following
.setSubject (...)
.claim (...)
.setIssuedAt (....)
.setExpiration (...)
Hi Sorry for late Answer. Actually you can't add both claims and payload. You can user either only one method in that. Payload method accepts only string, So add values to the token you can use the method add claims. Follow the below code structure. It will generates proper JWT token using details.
public String generateToken(Authentication authentication) {
Details user = (Details) authentication.getPrincipal();
Map<String, Object> claims = new HashMap<>();
claims.put("name", user.getName());
claims.put("email", user.getEmail());
return Jwts.builder().setSubject(user.getUsername()).addClaims(claims)
.setIssuedAt(new Date())
.setExpiration(new Date((new Date()).getTime() + tokenExpirationTime))
.signWith(SignatureAlgorithm.HS512, secretKey).compact();
}
Follow this method need any updates and changes. Please comment below....

eBay REST API Get Offers Authetication Error

I am attempting to get eBay product IDs using the GetOffers request by sending it a product SKU.
My code is below, the problem I am currently having is that when I try to test this code is returns a 401 unauthorized. It's not returning any specific error code or anything descriptive.
I know my access token is valid I can't find any good examples on how to use this request.
public string getEbayOffers(string sku)
{
HttpResponseMessage response;
string accessToken = "tokenhere";
string param = Convert.ToBase64String(Encoding.ASCII.GetBytes(accessToken));
string url = $"sell/inventory/v1/offer?sku={sku}";
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://api.ebay.com/");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", param);
response = client.GetAsync(url).Result;
}
if (response.IsSuccessStatusCode)
{
return response.Content.ReadAsStringAsync().Result;
}
return null;
}
No need to convert your token to base64. The correct format should be "Bearer YOUR_USER_TOKEN". Replace YOUR_USER_TOKEN with your own token string.
Access token should be enough for getting offers but maybe you can try to use user token if above doesn't work.

REST Application - I don't receive the error from server in case of insucess - the output displays only if the request is successfull

I have the next problem: I've made a simple application which retrieves information from a server (GET Method). The application works fine as long as the information is retrieved successfully.
In case of insuccess, I don't receive the error from the server (ex: 401 - Unauthorized, 403 - Forbidden - when the authentication token is incorrect for example).
How can I fix this so that my application will return the error from server ? I've done also a POST method and there it's working, I received all erorrs froem server in case of insuccess.
What i'm doing wrong with this code ? Why i don't receive an error in case of insuccess?
The only error I receive in output is 400 in all scenarios and this isn't enough.
For example, if the authorization token is incorrect, I should receive from server 401 - Unauthorized. I know this because i'm doing test with other REST application (like POSTMAN). Can it be fixed to show the errors related to that scenarios ?
void example2() {
// GET METHOD !
try {
String webPage = "https://www.clients.ro";
String name = "user";
String password = "pass";
String authString = name + ":" + password;
System.out.println("Decoded authorization token" + authString);
//byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
//String authStringEnc = new String(authEncBytes);
byte[] authEncBytes = authString.getBytes(StandardCharsets.UTF_8);
String authStringEnc = DatatypeConverter.printBase64Binary(authEncBytes);
System.out.println("Token encoded in Base64 " + authStringEnc);
URL url = new URL(webPage);
URLConnection urlConnection = url.openConnection();
urlConnection.setRequestProperty("Authorization", "Basic " + authStringEnc);
InputStream is = urlConnection.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
int numCharsRead;
char[] charArray = new char[1024];
StringBuffer sb = new StringBuffer();
while ((numCharsRead = isr.read(charArray)) > 0) {
sb.append(charArray, 0, numCharsRead);
}
String result = sb.toString();
System.out.println(result);
System.out.println();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

Restful URL custom authentication failing in java

This code is for getting the text from some URL which is having custom authentication as specified below.Tried with even ajax and Jquery as dataType:"jsonp" but it is also showing 401 error.
URL u;
HttpURLConnection con;
InputStream is = null;
DataInputStream dis;
String s;
try {
// u = new URL("http://q.addthis.com/feeds/1.0/trending.json?pubid=atblog");
u = new URL("http://m2mportal.connectm.com/EMS/rest/device");
is = u.openStream();
con=(HttpURLConnection) u.openConnection();
con.connect();
con.setDoOutput(true);
con.setRequestMethod("GET");
con.setRequestProperty("Accept","application/json");
con.setRequestProperty("Authorization","authenticate\":{\"userName\":\"admin01\",\"password\":\"admin01$\",\"appId\":\"123\"}");
con.setRequestProperty("userName","admin01");
con.setRequestProperty("password","admin01$");
con.setRequestProperty("appId","123");
dis = new DataInputStream(new BufferedInputStream(is));
while ((s = dis.readLine()) != null)
{
System.out.println(s);
}
}
catch (MalformedURLException mue)
{
System.out.println("Ouch - a MalformedURLException happened.");
mue.printStackTrace();
System.exit(1);
}
catch (IOException ioe)
{
System.out.println("Oops- an IOException happened.");
ioe.printStackTrace();
System.exit(1);
}
catch(IllegalStateException ise)
{
System.out.println("In IllegalState Exception........");
ise.printStackTrace();
}
When tried to authenticate against a url which is having some custom authentication as shown in the code it is returning 401 error
Oops- an IOException happened.
java.io.IOException: Server returned HTTP response code: 401 for URL: some url
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1625)
at java.net.URL.openStream(URL.java:1037)
at com.techm.JavaGetUrl.main(JavaGetUrl.java:16)
Java Result: 1
Actually problem here is Authorization property that you passed is not encoded.
You need to pass it to Base64 encoder so that http Authorization mechanism will use it.
Base64 encoding is commonly used when there is a need to encode / decode binary data stored and transferred over network.
Add encoding to your code . change your code to :
you need to use
Base64.encodeToString()
to perform encoding.
Following link will help you more:
http://www.javatips.net/blog/2011/08/how-to-encode-and-decode-in-base64-using-java