I want to fetch the roles stored as claim in JWT. I am using following code to do that:
DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC512(SecurityConstants.SECRET.getBytes()))
.build()
.verify(token.replace(SecurityConstants.TOKEN_PREFIX, ""));
String user = decodedJWT.getSubject();
Claim claims = decodedJWT.getClaims();
String roles = claims.get("roles").toString();
But this ends up giving object code:
(Value of roles)JSONNodeClaim#10091
I debugged the code and found claims like this:
How can i extract the "ROLE_ADMIN" ?
You can cast the claim to the Claim class and call the .asString() method to return it as a string:
String claims = ((Claim) decodedJWT.getClaim("roles")).asString();
You can use the chain method call to get the below:
String claims = decodedJWT.getClaim("roles").as(TextNode.class).asText();
The roles are always multiple, hence need to call with extraction as a collection
List<SimpleGrantedAuthority> simpleGrantedAuthorities = decodedJWT.getClaim("role").asList(SimpleGrantedAuthority.class);
Related
I tried to get product from API with some parameters. I used WooCommerce API Java Wrapper. REST API with OAuth 1.0. Simple getAll method return list of one page (10 products). To get all i must set how much products must be in one page and use offset. To get third page must send this parameters: "per_page=10&offset=20". I test with query in get&post programm - all work. In Java, when i added parameters - i got error (401)- "Invalid signature - the provided signature did not match".
I changed WooCommerceAPI class:
private static final String API_URL_FORMAT = "%s/wp-json/wc/v2/%s";
private static final String API_URL_ONE_ENTITY_FORMAT = "%s/wp-json/wc/v2/%s/%d";
private HttpClient client;
private OAuthConfig config;
public List getAll(String endpointBase) {
String url = String.format(API_URL_FORMAT, config.getUrl(), endpointBase) + "?per_page=10&offset=20";
String signature = OAuthSignature.getAsQueryString(config, url, HttpMethod.GET);
String securedUrl = String.format("%s&%s", url, signature);
System.out.println("url="+url);
System.out.println("securedUrl="+securedUrl);
return client.getAll(securedUrl);
}
But I have got the same error.
I've just released a new version of wc-api-java library (version 1.2) and now you can use the method getAll with params argument where you can put additional request parameters. For example:
// Get all with request parameters
Map<String, String> params = new HashMap<>();
params.put("per_page","100");
params.put("offset","0");
List products = wooCommerce.getAll(EndpointBaseType.PRODUCTS.getValue(), params);
System.out.println(products.size());
As you noticed, you changed URL_SECURED_FORMAT from "%s?%s" to "%s&%s", as soon as you added query params. But problem is that signature is generated based on all query params, not only oauth_*, and your params offset and per_page are ignored while generating signature (as soon as lib author did not expect additional params).
Think that you need to modify this lib to support signature based on all params.
The docs for cognito user pools can be found here:
http://docs.aws.amazon.com/cognito/latest/developerguide/how-to-manage-user-accounts.html
In this they do not say whether you can query users by the automatically generated sub attribute, which is a uuid. It explicitly says you can't search for users by custom attributes, but sub/uuid is not a custom attribute. Weirdly though, in the list of searchable attributes sub/uuid is not one of them. Surely though you can look up users by their UUID, how would this be done though??
You know, I have used COgnito but never needed to look up via sub (or other params other than the username). I looked into it because surely you can, but it is not very clear (like a lot of their documentation). Here is what I saw that you could try... hope it helps man.
// the imported ListUsersResult is...
import com.amazonaws.services.cognitoidp.model.ListUsersRequest;
import com.amazonaws.services.cognitoidp.model.ListUsersResult;
// class var
protected final AWSCognitoIdentityProviderClient identityUserPoolProviderClient;
// omitted stuff...
// initialize the Cognito Provider client. This is used to talk to the user pool
identityUserPoolProviderClient = new AWSCognitoIdentityProviderClient(new BasicAWSCredentials(AWS_ACCESS_KEY, AWS_SECRET_KEY)); // creds are loaded via variables that are supplied to my program dynamically
identityUserPoolProviderClient.setRegion(RegionUtils.getRegion(USER_POOL_REGION)); // var loaded
// ...some code omitted
ListUsersRequest listUsersRequest = new ListUsersRequest();
listUsersRequest.withUserPoolId(USER_POOL_ID); // id of the userpool, look this up in Cognito console
listUsersRequest.withFilter("sub=xyz"); // i THINK this is how the Filter works... the documentation is terribad
// get the results
ListUsersResult result = identityUserPoolProviderClient.listUsers(listUsersRequest);
List<UserType> userTypeList = result.getUsers();
// loop through them
for (UserType userType : userTypeList) {
List<AttributeType> attributeList = userType.getAttributes();
for (AttributeType attribute : attributeList) {
String attName = attribute.getName();
String attValue = attribute.getValue();
System.out.println(attName + ": " + attValue);
}
}
If you have the username you could get the user like this
// build the request
AdminGetUserRequest idRequest = new AdminGetUserRequest();
idRequest.withUserPoolId(USER_POOL_ID);
idRequest.withUsername(username);
// call cognito for the result
AdminGetUserResult result = identityUserPoolProviderClient.adminGetUser(idRequest);
// loop through results
I am working on "Forgot Password". I am trying to create a reset token with email + current_time. email is user login whilst code will check if time >= 5 minutes then this link will not work. Here is my code:
// preparing token email + time
Date now = new Date();
String prepareToken = "?email="+email+"&tokenTime="+now.getTime();
// encrypt prepareToken value
Encryptor enc = new Encryptor();
resetToken = enc.encrypt(resetToken);
The token will be sent as for example as http://domainname.com/ForgotPassword?resetToken=adj23498ljj238809802340823
Problem:
When user click it then I got as request parameter and obviously decrypt this parameter but how can I get email in one String + time as another String
Please advise
If your issue is simply parsing the decoded String to get some sort of Map of your parameters, I'd suggest you to read Parse a URI String into Name-Value Collection .
Hope it helps.
EDIT :
Assuming you have the splitQuery(URL url) method from the previous link and that you successfully decoded the token :
public String getEmailFromToken(String decodedToken) {
// if you decoded your token it will looks like the prepareToken String
String stubUrl = "http://localhost"+decodedToken;
Map<String,String> map = splitQuery(new URL(stubUrl));
return map.get("timeToken");
}
I created a properly formed URL to respect the URL syntax.
With little tweak, you should be able to implement splitQuery for a String. I hope you can manage that.
Which annotation from Jax-RS api was used to retrieve the cookie value?
I tried with the below code
public String getCookieValue(#Context HttpHeaders headers){
headers.getCookies()
}
above code snippet gives a Map. how to retrieve a specific cookie value from it..!
Thanks
According to javadoc, headers.getCookies() call retrieves you "a read-only map of cookie name (String) to Cookie".
Map<String, Cookie> cookies = hh.getCookies();
Cookie myCookie = cookies.get("your cookie name");
I believe you're looking for #CookieParam
Since you have mentioned to return String and you are returning a map object, it must not be working.
Try this:
public String getCookieValue(#Context HttpHeaders headers){
return headers.getCookies().toString;
}
H!I am having a very hard time with Yahoo Oauth right now.
So here's the problem, I am using scribe 3.1.5 and followed Yahoo's documentations(apparently they use Oauth1.0), I've been able to get the request token, then trade for the access token with the verifier. The problem emerges when I try to get user's GUID from URL http://social.yahooapis.com/v1/me/guid?format=json with the access token.
now, what's interesting is that, yahoo would sometimes give me the GUID back, and sometimes give me a "invalid signature" error. Sometimes I get 5 invalid signatures in a row, sometimes I get 15 successful calls in a row, most of the time it is like 40% invalid signatures and 60% success. What is even weirder is that sometimes I get a success when fetching GUID, but when i try to fetch user's profile IMMEDIATELY after the success with the identical access token and GUID, it gives me an invalid sigature...(wtf)
so here's the code I use:
Redirecting User:
Token requestToken = yahooService.getRequestToken();
getSession().setAttribute("yahooRequestToken", requestToken);
String authenticationUrl = yahooService.getAuthorizationUrl(requestToken);
redirect(authenticationUrl);
Getting callback:
#GET #Path("/oauthcallback/yahoo")
public Response yahooCallback(#QueryParam("oauth_token") String oAuthToken, #QueryParam("oauth_verifier") String oAuthVerifier) {
Token requestToken = (Token)getSession().getAttribute("yahooRequestToken");
Token accessToken = yahooService.getAccessToken(requestToken, oAuthVerifier);
UserProfile user = userService.findUserById(getUserId());
try{
//TODO occasioanlly yahoo returns invalid_signature, this is inconsistent and I have no idea why
String guid = yahooService.getGuid(accessToken);
String email = yahooService.getUserEmail(guid, accessToken);
.....
YahooService::Getting Access Token:
[the service object is protected final OAuthService service; in parent class]
#Override
public Token getAccessToken(Token requestToken, String oAuthVerifier) {
Verifier verifier = new Verifier(oAuthVerifier);
return service.getAccessToken(requestToken, verifier);
}
YahooService::Getting GUID:
#Override
public String getGuid(Token accessToken){
OAuthRequest requestA = new OAuthRequest(Verb.GET, GET_YAHOO);
service.signRequest(accessToken, requestA);
Response responseA = requestA.send();
JsonParser parser = new JsonParser();
//sometimes the response body is a invalid signature error message
JsonObject json = (JsonObject)parser.parse(responseA.getBody());
return json.getAsJsonObject("guid").get("value").getAsString();
}
YahooService::Getting User Email:
#Override
public String getUserEmail(String guid, Token accessToken) {
String profileCallUrl = GET_YAHOO_PROFILE.replaceAll("GUID", guid);
OAuthRequest requestB = new OAuthRequest(Verb.GET, profileCallUrl);
service.signRequest(accessToken, requestB);
requestB.addHeader("realm", "yahooapis.com");
Response responseB = requestB.send();
JsonParser parser = new JsonParser();
//sometimes the response body is a invalid signature error message
JsonObject jsonProfile = (JsonObject)parser.parse(responseB.getBody());
...processing code, error free
}
I know YahooAPI class in Scribe 3.1.5 in maven distribution is like 2 years old, but I doubt it would lead to such inconsistent behavior. Scribe's built in support for Google and Live oauth is basically useless, unfortunately, unlike Google or Hotmail which both have awesome doc so that I could basically figure out everything myself, Yahoo's doc stops at getting the access token, I can not find useful explanation on why I would get an invalid signature SOMETIMES with my access token
Please help! Thanks in advance
Its looks like Yahoo issue, I have same error message since few days :
http://developer.yahoo.com/forum/OAuth-General-Discussion-YDN-SDKs/signature-invalid-when-making-calls-to-the/1385735171123-8a38d8cf-815b-43ac-9d77-5bd2f2f60796
There is no need to ask for GUID to yahoo as yahoo returns GUID of the currently logged in user at the time of giving you the access token so if you have a access token you also have a GUID in the response.
Refer this