0
votes

I am trying to create an API on Google App Engine which can be called by a .NET client with authentication.

The .NET client authenticates the user using

            UserCredential credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
              new ClientSecrets
              {
                  ClientId = "<client id>",
                  ClientSecret = "<client secret"
              },
              new[] { "email", "profile", "https://www.googleapis.com/auth/devstorage.read_write" }, "user", CancellationToken.None);

and that works fine.

I have a servlet which is protected by

  <security-constraint>
    <web-resource-collection>
      <web-resource-name>servlet</web-resource-name>
      <url-pattern>/servlet/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>*</role-name>
    </auth-constraint>
  </security-constraint>

So it is only accessible to authenticated users, which is how I want it.

I want to be able to get the current user using

User currentUser = UserServiceFactory.getUserService().getCurrentUser();

but I can't get the .NET client to authenticate to the servlet.

I have tried

var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {credential.Token.AccessToken}");
httpClient.PutAsync("http://<my app>/servlet", content);

however this fails as the put returns a 302 redirect to a URL starting with https://www.google.com/accounts/ServiceLogin..., which the .NET HTTP client presumably follows, as it then ends up with a 405 method not allowed.

I've also tried

 Google.Apis.Http.HttpClientFactory httpClientFactory = new HttpClientFactory();
 Google.Apis.Http.CreateHttpClientArgs httpClientArgs = new CreateHttpClientArgs();
 Google.Apis.Http.ConfigurableHttpClient httpClient = httpClientFactory.CreateHttpClient(new CreateHttpClientArgs());
 credential.Initialize(httpClient);

(credential is the UserCredential gained above from GoogleWebAuthorizationBroker.AuthorizeAsync)

however that does the same thing - issues a redirect to google/accounts/ServiceLogin URl - which fails.

Is what I'm trying to do even possible? Surely there must be a way for a servlet to be able to authenticate users that are calling it programatically via an API rather than from the web?

1
I am not 100% sure i understand what you are trying to do. However the only way for you to authenticate a user is for you to display the web browser window to them on their machine. - DaImTo
I've displayed the web browser to them by calling GoogleWebAuthorizationBroker.AuthorizeAsync. This returns a UserCredential object which contains an access token. I then want to somehow use that token to call an AppEngine servlet of my own making, with a PUT or a POST, and for that servlet to know which user is calling it. The PUT or the POST come from a .NET client, not from a web page. - BenTaylor
similar to this question: stackoverflow.com/questions/14034043/… but instead of using "Google Apps Script", I am using App Engine. If this isn't possible with AppEngine, what is an alternative platform tha I could accomplish this with? - BenTaylor
appengine running .net? are you using the.net client library? - DaImTo
AppEngine doesn't run .net, no, appengine runs java. I am trying to call the AppEngine API using a .NET client - BenTaylor

1 Answers

0
votes

I will provide you a couple of links that might turn useful for you:

  1. There are three methods to authenticate in App Engine using the Java Client Library. Find their description here.
  2. Find here a pom.xml sample using Java Client Library and Oauth authentication method.

I expect that you will find an answer there. I don't want to be more specific since I don't really understand the pipeline you are using.