GoogleIdTokenVerifier.verify always returns null - google-oauth

I am trying to validate a JWT Token sent by Google to my application . I am using the below code to validate the JWT token but verifier.verify(token) always returns null even if the token is valid. I have tested the token in another NodeJS code i have and it works fine in NodeJS but in the below java code i am not able to validate the token . Any help in letting me know why verifier.verify(token) returns null is appreciated.
public static boolean isRequestFromGoogle(String audience, String token) {
//HttpTransport httpTransport = checkNotNull(Utils.getDefaultTransport());
//JsonFactory jsonFactory = checkNotNull(Utils.getDefaultJsonFactory());
HttpTransport httpTransport = new NetHttpTransport();
JsonFactory jsonFactory = new JacksonFactory();
GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(httpTransport,
jsonFactory).setAudience(Collections.singletonList(audience)).build();
try {
System.out.println("token is " + token);
System.out.println("verifier is " + verifier.toString());
GoogleIdToken idToken = verifier.verify(token);
if (idToken == null) {
System.out.println("idToken is null");
return false;
}
Payload payload = idToken.getPayload();
String issuer = (String) payload.get("iss");
String proj = (String) payload.get("aud");
System.out.println("Issuer is" + issuer);
System.out.println("Project is" + proj);
return issuer.equals("https://accounts.google.com");
} catch (GeneralSecurityException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
return false;
}

Related

API Chorus Pro Oauth2 authentication in Java

I created an account on https://developer.aife.economie.gouv.fr/ website and I want to try API on the sandbox. For this an application has been generated
For this application, I obtain API key and OAuth2 Credentials. Here are my previous API keys.
By reading the documentation, I have the following entry points for authentication
My objective is to get authenticated and get an auth token in order to consume this API. Here is my code:
package com.oauth.app;
import org.apache.oltu.oauth2.client.OAuthClient;
import org.apache.oltu.oauth2.client.URLConnectionClient;
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse;
import org.apache.oltu.oauth2.common.OAuth;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.types.GrantType;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
public class OAuthApp {
/**
* URL for requesting OAuth access tokens.
*/
private static final String TOKEN_REQUEST_URL =
"https://sandbox-oauth.aife.economie.gouv.fr/api/oauth/token";
/**
* Client ID of your client credential. Change this to match whatever credential you have created.
*/
private static final String CLIENT_ID =
"1f80aa43-e12f-4e1c-ad42-87ec16baf060";
/**
* Client secret of your client credential. Change this to match whatever credential you have created.
*/
private static final String CLIENT_SECRET =
"a232af0e-513e-4a64-9977-410d237dc421";
/**
* Account on which you want to request a resource. Change this to match the account you want to
* retrieve resources on.
*/
private static final String ACCOUNT_ID =
"a232af0e-513e-4a64-9977-410d237dc421";
/**
* Request a fresh access token using the given client ID, client secret, and token request URL,
* then request the resource at the given resource URL using that access token, and get the resource
* content. If an exception is thrown, print the stack trace instead.
*
* #param args Command line arguments are ignored.
*/
public static void main(String[] args) {
try {
OAuthClient client = new OAuthClient(new URLConnectionClient());
System.out.println("OAuthClient " + client.toString());
OAuthClientRequest request =
OAuthClientRequest.tokenLocation(TOKEN_REQUEST_URL)
.setGrantType(GrantType.CLIENT_CREDENTIALS)
.setClientId(CLIENT_ID)
.setClientSecret(CLIENT_SECRET)
// .setScope() here if you want to set the token scope
.buildQueryMessage();
request.addHeader("Accept", "application/json");
// request.addHeader("Content-Type", "application/json");
// request.addHeader("Authorization", base64EncodedBasicAuthentication());
System.out.println("OAuthClientRequest body\n\t " + request.getBody());
System.out.println("OAuthClientRequest headers\n\t " + request.getHeaders());
System.out.println("OAuthClientRequest locationUri\n\t " + request.getLocationUri());
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}};
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
e.printStackTrace();
}
String token = client.accessToken(
request,
OAuth.HttpMethod.GET,
OAuthJSONAccessTokenResponse.class).getAccessToken();
} catch (OAuthSystemException | OAuthProblemException e) {
e.printStackTrace();
}
}
}
I obtain this in my console:
OAuthClient org.apache.oltu.oauth2.client.OAuthClient#7e0ea639
OAuthClientRequest body
null
OAuthClientRequest headers
{Accept=application/json, Content-Type=application/json}
OAuthClientRequest locationUri
https://sandbox-oauth.aife.economie.gouv.fr/api/oauth/token?grant_type=client_credentials&client_secret=a232af0e-513e-4a64-9977-410d237dc421&client_id=42b214ec-7eaf-4f37-aeb5-ae91057a0e27
OAuthProblemException{error='unsupported_response_type', description='Invalid response! Response body is not application/json encoded', uri='null', state='null', scope='null', redirectUri='null', responseStatus=0, parameters={}}
at org.apache.oltu.oauth2.common.exception.OAuthProblemException.error(OAuthProblemException.java:63)
at org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse.setBody(OAuthJSONAccessTokenResponse.java:76)
at org.apache.oltu.oauth2.client.response.OAuthClientResponse.init(OAuthClientResponse.java:92)
at org.apache.oltu.oauth2.client.response.OAuthAccessTokenResponse.init(OAuthAccessTokenResponse.java:65)
at org.apache.oltu.oauth2.client.response.OAuthClientResponse.init(OAuthClientResponse.java:101)
at org.apache.oltu.oauth2.client.response.OAuthAccessTokenResponse.init(OAuthAccessTokenResponse.java:60)
at org.apache.oltu.oauth2.client.response.OAuthClientResponse.init(OAuthClientResponse.java:120)
at org.apache.oltu.oauth2.client.response.OAuthClientResponseFactory.createCustomResponse(OAuthClientResponseFactory.java:82)
at org.apache.oltu.oauth2.client.URLConnectionClient.execute(URLConnectionClient.java:111)
at org.apache.oltu.oauth2.client.OAuthClient.accessToken(OAuthClient.java:65)
at com.oauth.app.OAuthApp.main(OAuthApp.java:101)
I obtain this error message:
OAuthProblemException{error='unsupported_response_type', description='Invalid response! Response body is not application/json encoded'
I also tried to use a curl call to the API :
curl –k –H "content-type :application/x-www-form-urlencoded" –d "grant_type=client_credentials&client_id=42b214ec-7eaf-4f37-aeb5-ae91057a0e27&client_secret=a232af0e-513e-4a64-9977-410d237dc421&scope=openid" –X POST https://sandbox-oauth.aife.finances.rie.gouv.fr/api/oauth/token
curl: (6) Could not resolve host: -k
curl: (6) Could not resolve host: -H
curl: (3) Port number ended with 'a'
curl: (6) Could not resolve host: -d
curl: (6) Could not resolve host: grant_type=client_credentials&client_id=42b214ec-7eaf-4f37-aeb5-ae91057a0e27&client_secret=a232af0e-513e-4a64-9977-410d237dc421&scope=openid
curl: (6) Could not resolve host: -X
curl: (6) Could not resolve host: POST
curl: (6) Could not resolve host: sandbox-oauth.aife.finances.rie.gouv.fr
Ok i finally solved my own issue. There was no need to use OAuth stuff.
It's divided onto 2 classes. This code is just for testing purpose.
public class OAuthApp {
private static final String TOKEN_REQUEST_URL = "https://sandbox-oauth.aife.economie.gouv.fr/api/oauth/token";
private static final String CLIENT_ID = "xxxxxx";
private static final String CLIENT_SECRET = "xxxxxx";
private static final String GRANT_TYPE = "client_credentials";
private static final String SCOPE = "openid";
public static void main(String[] args) throws IOException {
try {
Map<String, String> headers = new HashMap<>();
HttpsPostForm httpsPostForm = new HttpsPostForm(TOKEN_REQUEST_URL, "utf-8", headers);
httpsPostForm.addFormField("grant_type", GRANT_TYPE);
httpsPostForm.addFormField("client_id", CLIENT_ID);
httpsPostForm.addFormField("client_secret", CLIENT_SECRET);
httpsPostForm.addFormField("scope", SCOPE);
// Result
String response = httpsPostForm.finish();
System.out.println(response);
} catch (IOException e) {
e.printStackTrace();
}
}
}
My second class is just building the HTTPS request and set the headers elements. The empty trust manager helps to avoid error messages.
public class HttpsPostForm {
private HttpsURLConnection conn;
private Map<String, Object> queryParams;
private String charset;
public HttpsPostForm(String requestURL, String charset, Map<String, String> headers, Map<String, Object> queryParams) throws IOException {
this.charset = charset;
if (queryParams == null) {
this.queryParams = new HashMap<>();
} else {
this.queryParams = queryParams;
}
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}};
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
e.printStackTrace();
}
URL url = new URL(requestURL);
conn = (HttpsURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setDoOutput(true); // indicates POST method
conn.setDoInput(true);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
if (headers != null && headers.size() > 0) {
Iterator<String> it = headers.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
String value = headers.get(key);
conn.setRequestProperty(key, value);
}
}
}
public HttpsPostForm(String requestURL, String charset, Map<String, String> headers) throws IOException {
this(requestURL, charset, headers, null);
}
public HttpsPostForm(String requestURL, String charset) throws IOException {
this(requestURL, charset, null, null);
}
public void addFormField(String name, Object value) {
queryParams.put(name, value);
}
public void addHeader(String key, String value) {
conn.setRequestProperty(key, value);
}
private byte[] getParamsByte(Map<String, Object> params) {
byte[] result = null;
StringBuilder postData = new StringBuilder();
for (Map.Entry<String, Object> param : params.entrySet()) {
if (postData.length() != 0) {
postData.append('&');
}
postData.append(this.encodeParam(param.getKey()));
postData.append('=');
postData.append(this.encodeParam(String.valueOf(param.getValue())));
}
try {
result = postData.toString().getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
private String encodeParam(String data) {
String result = "";
result = URLEncoder.encode(data, StandardCharsets.UTF_8);
return result;
}
public String finish() throws IOException {
String response = "";
byte[] postDataBytes = this.getParamsByte(queryParams);
conn.getOutputStream().write(postDataBytes);
// Check the http status
int status = conn.getResponseCode();
if (status == HttpsURLConnection.HTTP_OK) {
ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = conn.getInputStream().read(buffer)) != -1) {
result.write(buffer, 0, length);
}
response = result.toString(this.charset);
conn.disconnect();
} else {
throw new IOException("Server returned non-OK status: " + status);
}
return response;
}
}
Finally I can print my Json string :
{
"access_token":"Js1NYJvtQREj0I0Dz5b0qrMh8gjJBlltJAit2Yx6BGJDloixPv2JwB",
"token_type":"Bearer",
"expires_in":3600,
"scope":"openid resource.READ"
}
I also had some difficulties with Chorus API but I achieve to get the tokenKey with that with the same method but buildBodyMessage() at the end.
// Création requête pour obtenir le token Oauth2 API CHORUS
request = OAuthClientRequest
.tokenLocation(urlToken)
.setGrantType(GrantType.CLIENT_CREDENTIALS)
.setClientId(clientid)
.setClientSecret(clientsecret)
.setScope(OidcScopes.OPENID)
.buildBodyMessage();
// Ajout du Cpro-account
request.addHeader("cpro-account", cproAccount);
tokenChorus = client.accessToken(request, OAuth.HttpMethod.POST, OAuthJSONAccessTokenResponse.class)
.getAccessToken();
that create token formated in String. And afterthat you must create HttpUrlConnection with this token with headers like that
HttpURLConnection connexion = null;
try {
URL url = new URL(currentUrl);
connexion = (HttpURLConnection) url.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
connexion.setRequestProperty("Content-type", "application/json");
connexion.setRequestProperty("Authorization", "Bearer " + tokenChorus);
connexion.setRequestProperty("cpro-account", cproAccount);
try {
connexion.setRequestMethod("POST");
} catch (ProtocolException e) {
e.printStackTrace();
}
connexion.setDoInput(true);
connexion.setDoOutput(true);
return connexion;

javax.net.ssl.sslpeerunverifiedexception no peer certificate Error In lifelogApi

We are getting SSL peer unverified error while fetching the access token from Lifelog api. I am able to get the authcode, but when i am trying to get access token, it is giving me SSL peer error. It works fine with few device, but most of the device it is giving SSL error.
private void getAccessToken(final String authCode)
{
final String finalUrl = String.format("https://platform.lifelog.sonymobile.com/oauth/2/token?client_id=%s&client_secret=%s&code=%s",CLIENT_ID,CLIENT_SECRET,authCode);
Thread networkThread = new Thread(new Runnable() {
public void run() {
try {
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(finalUrl);
// Add your data
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(4);
nameValuePairs.add(new BasicNameValuePair("client_id", CLIENT_ID));
nameValuePairs.add(new BasicNameValuePair("client_secret", CLIENT_SECRET));
nameValuePairs.add(new BasicNameValuePair("grant_type", "authorization_code"));
nameValuePairs.add(new BasicNameValuePair("code", authCode));
AbstractHttpEntity ent=new UrlEncodedFormEntity(nameValuePairs, HTTP.UTF_8);
ent.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
post.setEntity(ent);
// Execute HTTP Post Request
HttpResponse response =null;
try {
response = client.execute(post);
Log.d("Response:" , response.toString());
} catch (IOException e) {
e.printStackTrace();
}
String dataObject = response.toString();
JSONObject obj;
if(dataObject != null) {
obj = null;
try {
String json_string = EntityUtils.toString(response.getEntity());
// displayToast(json_string);
obj = new JSONObject(json_string);
SharedPreferences prefs =getSharedPreferences("Myprefs", Context.MODE_PRIVATE);
prefs.edit().putString("Access_token", obj.getString("access_token"));
// prefs.edit().putString(AUTH_REFRESH_TOKEN, obj.getString(AUTH_REFRESH_TOKEN));
} catch (JSONException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
}
}
});
networkThread.start(); }
The problem may be with your use of HttpClient. It looks like Google has removed support for this call in Android 6.0.
http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-apache-http-client
You should be able to use HttpsURLConnection instead of Httpclient to access the Lifelog Web Service.
I'm using google-oauth-client, I was able to use on Android 5.x with this initialization for
import com.google.api.client.http.HttpTransport;
private void initializeSocketFactory() {
if (Build.VERSION.SDK_INT >= 23) {
HTTP_TRANSPORT = new NetHttpTransport();
} else {
//Android 5 and bellow needs this SSL Socket factory initialization
try {
SSLContext sslContext = SSLContext.getInstance("TLSv1");
sslContext.init(null, null, null);
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
NetHttpTransport.Builder netTransportBuilder = new NetHttpTransport.Builder();
netTransportBuilder.setSslSocketFactory(socketFactory);
HTTP_TRANSPORT = netTransportBuilder.build();
} catch (NoSuchAlgorithmException | KeyManagementException e) {
Log.e(LOG_TAG, "Problem instantiating cipher for ssl socket", e);
}
}
}
You use HTTP_TRANSPORT to instantiate:
import com.google.api.client.auth.oauth2.AuthorizationCodeFlow;

google sign on web application but in authentication it is giving SSL exception error

I am developing google sign in on my web application. I have send ID token on my server and then I want to verify the integrity of token but in authentication it is giving SSL exception error in GoogleIdTokenVerifier.How can I solve it ?
public class VerifyController {
public static final String CLIENT_ID = "";
private static final String APPLICATION_NAME = "";
public static GoogleIdTokenVerifier verifier ;
public static GoogleIdToken token;
private static NetHttpTransport transport;
private static JsonFactory mJFactory;
public Result validate(#PathParam("id") String idtoken) {
try{
// TODO Auto-generated method stub
System.out.println("IN validate");
System.out.println(idtoken);
transport = new NetHttpTransport();
mJFactory = new GsonFactory();
verifier = new GoogleIdTokenVerifier.Builder(transport, mJFactory)
.setAudience(Arrays.asList(CLIENT_ID))
.build();
token = GoogleIdToken.parse(mJFactory, idtoken);
GoogleIdToken token = GoogleIdToken.parse(mJFactory, idtoken);
if (verifier.verify(token)) {
Payload payload = token.getPayload();
System.out.println(payload);
if (payload.getHostedDomain().equals(APPLICATION_NAME)
// If multiple clients access the backend server:
{
System.out.println("User ID: " + payload.getSubject());
} else {
System.out.println("Invalid Domain.");
}
} else {
System.out.println("null ID token.");
}
return null;
}catch(Exception e) {
e.printStackTrace();
}
return null;
}
}
You need to setIssuer while creating object of GoogleIdTokenVerifier
verifier = new GoogleIdTokenVerifier.Builder(transport, mJFactory)
.setAudience(Arrays.asList(CLIENT_ID))
.build(); //instead of this use below code
verifier = new GoogleIdTokenVerifier.Builder(transport, mJFactory)
.setAudience(Arrays.asList(CLIENT_ID))
.setIssuer("accounts.google.com")
.build();

Setting socket buffer size in Apache HttpClient

How do you set the socket buffer size in Apache HttpClient version 4.3.3?
HttpClient client = new DefaultHttpClient();
client.getParams().setParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 128 * 1024);
HttpPost post = new HttpPost(url);
String res = null;
try
{
post.addHeader("Connection", "Keep-Alive");
post.addHeader("Content-Name", selectedFile.getName());
post.setEntity(new ByteArrayEntity(fileBytes));
HttpResponse response = client.execute(post);
res = EntityUtils.toString(response.getEntity());
}
catch (Exception e)
{
e.printStackTrace();
}
You create a custom ConnectionConfig object with your desired buffer size and pass it as a parameter when creating your HttpClient object. For example:
ConnectionConfig connConfig = ConnectionConfig.custom()
.setBufferSize(DESIRED_BUFFER_SIZE)
.build();
try (CloseableHttpClient client = HttpClients.custom()
.setDefaultConnectionConfig(connConfig)
.build()) {
HttpGet get = new HttpGet("http://google.com");
try (CloseableHttpResponse response = client.execute(get)) {
// Do something with the response
} catch (IOException e) {
System.err.println("Error transferring file: " + e.getLocalizedMessage());
}
} catch (IOException e) {
System.err.println("Error connecting to server: " + e.getLocalizedMessage());
}
There are lots of other configurable options available, checkout the API for the full list.

why pwcb.getPassword is null in this code

I try to add the rampart security to my axis2 web service using rampart module.
So here is what I have made:
I have stored in a database the hashed value of "bobWWW" password and the salt
In my PWCBHandler.java class
•I select the stored in the database password and hash
•I try to hash with same algorithm pwcb.getPassword() with the same stored salt
•check if this new hashed password is equal to the stored password
But I constantly was receiving nullpointerexception so I decide to check and wrote this code
if(pwcb.getPassword()==null)
{
try {
throw new Exception ("passwordget pass null" +pwcb.getPassword());
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
And I see that pwcb.getPassword() is empty. So here is the code of PWCBHandler.java
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
{
for (int i = 0; i < callbacks.length; i++)
{
WSPasswordCallback pwcb = (WSPasswordCallback)callbacks[i];
try {
pasandsalt = getdataforChecking();
if(pwcb.getPassword()==null)
{
try {
throw new Exception ("passwordget pass null" +pwcb.getPassword());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
passwordforchecking = hash(pwcb.getPassword(),Base64.decodeBase64(pasandsalt[1]));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if((pwcb.getIdentifier().equals("bob")) && (passwordforchecking.equals(pasandsalt[0])) )
{
return;
}
}
And here is my soaprequest with the sequeiry header
var sr =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soapenv:Envelope " +
"xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" " +
"xmlns:nilo=\"http://nilo\">"+
"<soapenv:Header>"+
'<wsse:Security xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" soapenv:mustUnderstand="1">'+
'<wsse:UsernameToken xmlns:wsu="http://docs.oasisopen.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="123">'+
'<wsse:Username>bob</wsse:Username>'+
'<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">bobWWW</wsse:Password>'+
'</wsse:UsernameToken>'+
'</wsse:Security>'+
"</soapenv:Header>"+
"<soapenv:Body>" +
"<nilo:getdataForChecking>" +
'<nilo:data>'+tranXml+'</nilo:data>' +
' </nilo:getdataForChecking>'+
'</soapenv:Body>' +
'</soapenv:Envelope>';
According to your soap headers i can see you are using a Plain text password instead of Password Digest. You might need to change the rampart configuration
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">bobWWW</wsse:Password>
this might be helpful to you. http://wso2.com/library/240/