I have created a database in the Parse.com cloud. I now need to write a Servlet in my Google App Engine application to call the REST services on Parse. The REST services require
user authentication which is the Parse app id and the Javascript key.
...
URL url = new URL("https://api.parse.com/1/classes/OBJECT");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Content-Type", "application/json");
Base64 enc = new Base64();
String userpassword = "{PARSE_APP_ID}" + ":" + "javascript-key={PARSE_JS_KEY}";
String encodedAuthorization = enc.encodeBase64String(userpassword.getBytes());
connection.setRequestProperty("Authorization", "Basic " + encodedAuthorization);
connection.setRequestMethod("GET");
...
I use org.apache.commons.codec.binary.Base64 for encoding to get REST call authenticated.
The Parse.com REST API recommends using the following request format to make a HTTP call:
https://myAppID:javascript-key=myJavaScriptKey#api.parse.com/1/classes/GameScore/Ed1nuqPvcm
The problem is that I kept getting
{"error":"unauthorized"}
Is there anyone having the experience with working with calling a authenticated REST service? Thanks!
EDIT.
URL url = new URL("https://api.parse.com/1/classes/OBJECT");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("X-Parse-Application-Id", "{APP_ID}");
connection.setRequestProperty("X-Parse-REST-API-Key", "REST_ID");
connection.setRequestProperty("Content-Type", "application/json");
I still got the same error while the responseCode was "200".
Cheers,
Use the header version of authentication instead:
connection.setRequestProperty("X-Parse-Application-Id", "app id here");
connection.setRequestProperty("X-Parse-REST-API-Key", "rest key here");
Related
I've successfully implemented this tutorial and have a client + server working locally.
However, the front-end application that I'm building is an Angular app - this means that it isn't possible to store a client secret in it..
Relevant code:
ConfidentialClientApplication cca = new ConfidentialClientApplication(Startup.ClientId, Startup.Authority, Startup.RedirectUri, new ClientCredential(Startup.ClientSecret), userTokenCache, null);
var user = cca.Users.FirstOrDefault();
AuthenticationResult result = await cca.AcquireTokenSilentAsync(scope, user, Startup.Authority, false);
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, apiEndpoint);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
How can I set my frontend up securely to work without having a client secret, based on the tutorial mentioned?
I'm currently using this angular library .
You can achieve this by using implicit grant flow
You can seamlessly integrate into any SPA application.
Follow https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-reference-spa, this article helps you.
There is an SPA sample already available in GitHub, you can try https://github.com/Azure-Samples/active-directory-b2c-javascript-hellojs-singlepageapp
you can use oidc-client library instead hello.js in above sample, both are very similar and easy to implement.
I need to form a POST to publish a Google PubSub message. I can't use the client libraries because they use gRPC which is incompatible with Google App Engine. I can form the critical POST request, but I'm not sure how to authenticate it using OAuth2.
This link shows what I'm doing, but it obscures the authentication part.
https://cloud.google.com/pubsub/docs/reference/rest/v1/projects.topics/publish
(If GAE standard environment would support gRPC this would not matter.)
JSONObject obj = new JSONObject();
JSONArray attr = new JSONArray();
obj.put("script_name","foo_script.py");
obj.put("script_args","arg1");
attr.put(obj);
JSONObject jsontop = new JSONObject();
jsontop.put("messages",attr);
URL url = new URL("https://pubsub.googleapis.com/v1/projects/{my-URL}/topics/topic_run_script:publish");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
This code comes back "401 : UNAUTHENTICATED". How do I authenticate it?
App Engine has an API to fetch an access token that you can use to when calling Google services. For documentation and an example, see https://cloud.google.com/appengine/docs/standard/java/appidentity/#asserting_identity_to_google_apis
You might also be able to use the pubsub client library on GAE Std if you switch to the Java 8 environment. This doc implies that it should work.
After successful AD authentication from my MVC web app, I set the token in the header so that client side scripts can make use of it to access the web api.
OnAuthorizationCodeReceived() after a successful login
private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedNotification context)
{
var code = context.Code;
ClientCredential credential = new ClientCredential(clientId, appKey);
string userObjectID = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
AuthenticationContext authContext = new AuthenticationContext(Authority, new NaiveSessionCache(userObjectID));
Uri uri = new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path));
AuthenticationResult result = await authContext.AcquireTokenByAuthorizationCodeAsync(code, uri, credential, graphResourceId);
HttpContext.Current.Request.Headers.Add("Authorization", "Bearer " + result.AccessToken);
}
In the last line I set the "Authorization" header. However I can't seem to make use of that from my AngularJS end to make api calls! What am I missing here? Requirement is that I don't have to use ADAL to authenticate from the AngularJS since web app already authenticates the user and have passed me the valid tokens.
You could try to save the access token in cookie :
HttpCookie tokenCookies = new HttpCookie("token");
tokenCookies.Value = result.AccessToken;
tokenCookies.Expires = DateTime.Now.AddHours(1);
HttpContext.Current.Response.Cookies.Add(tokenCookies);
Then making ajax call with access token from cookie on client side .
I have just started to learn the Watson analytics from IBM Watson Analytics I have uploaded a csv file and used EXPLORE, PREDICT features. Is there anyway can I use these features using REST API? in Java. Is there any REST API available for this.? I don't know how to start exactly.
The REST APIs for Watson Analytics use OAuth2 for Authentication once you have a token you can upload data and navigate the folders. There isn't a way to create Explorations and Predictions currently. Below is a code snip from the Java sample showing how you would get the user's profile information in Java.
String apiURL = "https://" + WATSON_ANALYTICS_API_URL + WATSON_ANALYTICS_API_BASE_PATH + "/accounts/v1/me";
HttpGet apiRequest = new HttpGet(apiURL);
apiRequest.addHeader("X-IBM-Client-Id","client_id");
apiRequest.addHeader("X-IBM-Client-Secret", "client_secret");
apiRequest.addHeader("Authorization", "Bearer " + ACCESS_TOKENS);
try {
HttpClient httpClient = new DefaultHttpClient();
HttpResponse apiResponse = httpClient.execute( apiRequest );
ByteArrayOutputStream stream = new ByteArrayOutputStream();
apiResponse.getEntity().writeTo( stream );
response.getWriter().write(stream.toString());
stream.close();
} catch (Exception e) {
System.err.println(e.getLocalizedMessage());
}
I am trying to call Directory APIs from my GAE application in JSP. The application is already running on AppSpot. I'd like to retrieve all organizational units that a user belong to. Unfortunately I get 404 code while making the request and I have no idea why.
ArrayList<String> scopes = new ArrayList<String>();
scopes.add("https://www.googleapis.com/auth/admin.directory.user");
AppIdentityService appIdentity = AppIdentityServiceFactory.getAppIdentityService();
AppIdentityService.GetAccessTokenResult accessToken = appIdentity.getAccessToken(scopes);
URL url = new URL("https://www.googleapis.com/admin/directory/v1/users/myuser#mygoogleappsdomain.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.addRequestProperty("Content-Type", "application/json");
connection.addRequestProperty("Authorization", "OAuth " + accessToken.getAccessToken());
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
out.print("OK");
}
else {
out.print(connection.getResponseCode());
}
As you can imagine this code snippet prints 404. Basically I am following an example that is available on the GAE documentation. What am i doing wrong? Thank you.
EDIT: If I just call one of the following URLs I get a 403 status code. Is there anything wrong with my OAuth authentication?
https://www.googleapis.com/admin/directory/v1/users?domain=mydomain
https://www.googleapis.com/admin/directory/v1/users
Your code only provides app identity. You will also need to get authorisation from user to get access to their directory info.
If you follow the link you provided you get to the point that states: All requests to the Directory API must be authorized by an authenticated user.
So you will need to send your users through a OAuth 2 authentication + authorization procedure, where you will ask them for Directory API access. If you only need a read-only access to list of users then you will need to request a https://www.googleapis.com/auth/admin.directory.user.readonly scope.