Getting Token (generateTorken) in C# from Windows Authenticated Enterprise

1394
2
Jump to solution
12-23-2020 01:45 PM
JoeHershman
MVP Regular Contributor

I am trying to use the generateToken endpoint with a installation that uses Windows Authentication.  In Runtime or in Python API in this case you would send the username and password as empty strings.  However, doing so in a standalone C# program calling into the generateToken endpoint returns an error 401 unauthorized access.

I have tried to do this a couple ways one of which follows

HttpRequestMessage msg = new HttpRequestMessage(HttpMethod.Post, "https://PORTALSERVER/portal/sharing/rest/generateToken") { Content = TokenRequestContent() };
using HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Referrer = new Uri("https://PORTALSERVER/portal");

var t = await httpClient.SendAsync(msg);
var s = await t.Content.ReadAsStringAsync();

private FormUrlEncodedContent TokenRequestContent()
{
	var parameters = new Dictionary<string, string>
	{
		{"username", ""},
		{"password", ""},
		{"client", "requestip" },
		{"expiration", "1440" },
		{"f", "pjson" },
	};

	var content = new FormUrlEncodedContent(parameters);
	return content;
}

Which fails

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>401 - Unauthorized: Access is denied due to invalid credentials.</title>

If I use the web browser to just make the call and send empty username and password I get the token as expected.

If I change and use the same code but to request from AGOL is works:

HttpRequestMessage msg = new HttpRequestMessage(HttpMethod.Post, "https://arcgis.com/sharing/rest/generateToken") { Content = TokenRequestContent() };
using HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Referrer = new Uri("https://arcgis.com");

var t = await httpClient.SendAsync(msg);
var s = await t.Content.ReadAsStringAsync();

private FormUrlEncodedContent TokenRequestContent()
{
	var parameters = new Dictionary<string, string>
	{
		{"username", "AGOLUSER"},
		{"password", "AGOLPASSWORD"},
		{"client", "requestip" },
		{"expiration", "1440" },
		{"f", "pjson" },
	};

	var content = new FormUrlEncodedContent(parameters);
	return content;
}

I will get a valid token returned in json as expected.

I have compared the Fiddler message for the request sent to the local portal both from my code and what is sent from the request done from the Web UI and both seem the same. 

Why would sending the same request with HttpClient not behave like the request if sent from a browser?

1 Solution

Accepted Solutions
JoeHershman
MVP Regular Contributor

Would seem you need to tell the HttpClient to use DefaultCredentials

using HttpClient httpClient = new HttpClient(new HttpClientHandler{UseDefaultCredentials = true});

 

View solution in original post

0 Kudos
2 Replies
JoeHershman
MVP Regular Contributor

Would seem you need to tell the HttpClient to use DefaultCredentials

using HttpClient httpClient = new HttpClient(new HttpClientHandler{UseDefaultCredentials = true});

 

0 Kudos
KirkKuykendall1
Occasional Contributor III

Did you compare headers with what the browser is sending?

0 Kudos