<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Invalid request - Invalid PKCE code_challenge_verifier when using oauth2/token in ArcGIS REST APIs and Services Questions</title>
    <link>https://community.esri.com/t5/arcgis-rest-apis-and-services-questions/invalid-request-invalid-pkce-code-challenge/m-p/1197635#M4226</link>
    <description>&lt;P&gt;Hi,&lt;/P&gt;&lt;P&gt;I am trying to get a token using OAuth2 from a web app.&amp;nbsp; I am able to do it using the /authorize endpoint if using response_type=token.&amp;nbsp; However, this returns the token in plan text in the redirect url which I find a bit low security.&amp;nbsp; I guess it is in the user's own browser, so perhaps not that big a deal.&lt;/P&gt;&lt;P&gt;I thought I would try to use the approach of getting an authorization code and then use the /token endpoint to get the token.&amp;nbsp; However, I am unable to retrieve this successfully.&lt;/P&gt;&lt;P&gt;Initially I send the /authorize request&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="cpp"&gt;string authorizeUrl = "https://www.arcgis.com/sharing/rest/oauth2/authorize";
string clientId = "my-client-id";
string redirectUrl = "https://localhost:7109/counter";
string responseType = "code";


string codeChallenge = "12345";
string codeChallengeMethod = "plain";

Console.WriteLine($"Index Challenge: {codeChallenge}");

$"{authorizeUrl}?client_id={clientId}&amp;amp;redirect_uri={redirectUrl}&amp;amp;response_type={responseType}&amp;amp;code_challenge={codeChallenge}&amp;amp;code_challenge_method={codeChallengeMethod}";

UriBuilder builder = new UriBuilder(authorizeUrl)
{
	Query = $"client_id={clientId}&amp;amp;redirect_uri={redirectUrl}&amp;amp;response_type={responseType}&amp;amp;code_challenge={codeChallenge}&amp;amp;code_challenge_method={codeChallengeMethod}"
};

string oAuthUrl = builder.ToString();
NavigationManager.NavigateTo(oAuthUrl);&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;This works perfect and takes me to the login page and when I login I am then redirected correctly to redirect page and the code is attached.&lt;/P&gt;&lt;P&gt;So then a post request is made to get the /token endpoint&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="csharp"&gt;//this gets the returned code, I have validated that it matches when is in the redirect Url
string code =  Navigation.Uri.Substring(Navigation.Uri.IndexOf("=", StringComparison.Ordinal) + 1);

string tokenUrl = "https://www.arcgis.com/sharing/rest/oauth2/token";
string clientId = "my-client-id";
string redirectUrl = "https://localhost:7109/counter";
//string codeChallenge = CreateSHA256Challenge();
string codeChallenge = "12345";

var dictionary = new Dictionary&amp;lt;string, string&amp;gt;
{
	{"client_id", clientId},
	{"grant_type", "authorization_code"},
	{"code", code!},
	{"code_verifier", codeChallenge},
	{"redirect_uri", redirectUrl}
};

FormUrlEncodedContent content = new FormUrlEncodedContent(dictionary);

using HttpClient client = new HttpClient();
var response = await client.PostAsync(tokenUrl, content);
var json = await response.Content.ReadAsStringAsync();&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;However, this fails and returns&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;{
	"error": {
		"code": 400,
		"error": "invalid_request",
		"error_description": "Invalid PKCE code_challenge_verifier",
		"message": "Invalid PKCE code_challenge_verifier",
		"details": []
	}
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The example I am just using a very simple challenge in plain text to make this as easy as possible to validate.&lt;/P&gt;&lt;P&gt;Is there something I am missing in the /token request?&amp;nbsp; One thing I find odd is you do not need to specify if is plain or S256 in the /token request.&amp;nbsp; The /token post call is within milliseconds of the initial /authorize request so nothing could have expired.&lt;/P&gt;&lt;P&gt;Does anyone has thoughts on what I am missing?&lt;/P&gt;&lt;P&gt;Thanks - Joe&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Fri, 29 Jul 2022 21:50:05 GMT</pubDate>
    <dc:creator>JoeHershman</dc:creator>
    <dc:date>2022-07-29T21:50:05Z</dc:date>
    <item>
      <title>Invalid request - Invalid PKCE code_challenge_verifier when using oauth2/token</title>
      <link>https://community.esri.com/t5/arcgis-rest-apis-and-services-questions/invalid-request-invalid-pkce-code-challenge/m-p/1197635#M4226</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;&lt;P&gt;I am trying to get a token using OAuth2 from a web app.&amp;nbsp; I am able to do it using the /authorize endpoint if using response_type=token.&amp;nbsp; However, this returns the token in plan text in the redirect url which I find a bit low security.&amp;nbsp; I guess it is in the user's own browser, so perhaps not that big a deal.&lt;/P&gt;&lt;P&gt;I thought I would try to use the approach of getting an authorization code and then use the /token endpoint to get the token.&amp;nbsp; However, I am unable to retrieve this successfully.&lt;/P&gt;&lt;P&gt;Initially I send the /authorize request&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="cpp"&gt;string authorizeUrl = "https://www.arcgis.com/sharing/rest/oauth2/authorize";
string clientId = "my-client-id";
string redirectUrl = "https://localhost:7109/counter";
string responseType = "code";


string codeChallenge = "12345";
string codeChallengeMethod = "plain";

Console.WriteLine($"Index Challenge: {codeChallenge}");

$"{authorizeUrl}?client_id={clientId}&amp;amp;redirect_uri={redirectUrl}&amp;amp;response_type={responseType}&amp;amp;code_challenge={codeChallenge}&amp;amp;code_challenge_method={codeChallengeMethod}";

UriBuilder builder = new UriBuilder(authorizeUrl)
{
	Query = $"client_id={clientId}&amp;amp;redirect_uri={redirectUrl}&amp;amp;response_type={responseType}&amp;amp;code_challenge={codeChallenge}&amp;amp;code_challenge_method={codeChallengeMethod}"
};

string oAuthUrl = builder.ToString();
NavigationManager.NavigateTo(oAuthUrl);&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;This works perfect and takes me to the login page and when I login I am then redirected correctly to redirect page and the code is attached.&lt;/P&gt;&lt;P&gt;So then a post request is made to get the /token endpoint&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="csharp"&gt;//this gets the returned code, I have validated that it matches when is in the redirect Url
string code =  Navigation.Uri.Substring(Navigation.Uri.IndexOf("=", StringComparison.Ordinal) + 1);

string tokenUrl = "https://www.arcgis.com/sharing/rest/oauth2/token";
string clientId = "my-client-id";
string redirectUrl = "https://localhost:7109/counter";
//string codeChallenge = CreateSHA256Challenge();
string codeChallenge = "12345";

var dictionary = new Dictionary&amp;lt;string, string&amp;gt;
{
	{"client_id", clientId},
	{"grant_type", "authorization_code"},
	{"code", code!},
	{"code_verifier", codeChallenge},
	{"redirect_uri", redirectUrl}
};

FormUrlEncodedContent content = new FormUrlEncodedContent(dictionary);

using HttpClient client = new HttpClient();
var response = await client.PostAsync(tokenUrl, content);
var json = await response.Content.ReadAsStringAsync();&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;However, this fails and returns&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;{
	"error": {
		"code": 400,
		"error": "invalid_request",
		"error_description": "Invalid PKCE code_challenge_verifier",
		"message": "Invalid PKCE code_challenge_verifier",
		"details": []
	}
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The example I am just using a very simple challenge in plain text to make this as easy as possible to validate.&lt;/P&gt;&lt;P&gt;Is there something I am missing in the /token request?&amp;nbsp; One thing I find odd is you do not need to specify if is plain or S256 in the /token request.&amp;nbsp; The /token post call is within milliseconds of the initial /authorize request so nothing could have expired.&lt;/P&gt;&lt;P&gt;Does anyone has thoughts on what I am missing?&lt;/P&gt;&lt;P&gt;Thanks - Joe&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 29 Jul 2022 21:50:05 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-rest-apis-and-services-questions/invalid-request-invalid-pkce-code-challenge/m-p/1197635#M4226</guid>
      <dc:creator>JoeHershman</dc:creator>
      <dc:date>2022-07-29T21:50:05Z</dc:date>
    </item>
    <item>
      <title>Re: Invalid request - Invalid PKCE code_challenge_verifier when using oauth2/token</title>
      <link>https://community.esri.com/t5/arcgis-rest-apis-and-services-questions/invalid-request-invalid-pkce-code-challenge/m-p/1198430#M4230</link>
      <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://community.esri.com/t5/user/viewprofilepage/user-id/7529"&gt;@JoeHershman&lt;/a&gt;&amp;nbsp;,&lt;/P&gt;&lt;P&gt;This is the first time I try this, but I made it work. You can see the &lt;A href="https://www.postman.com/arcgis-developer/workspace/authentication-in-arcgis/folder/15786767-23fd7db6-804a-465b-9c21-fa52cc063486?ctx=documentation" target="_self"&gt;postman collection I used here&lt;/A&gt;&lt;/P&gt;&lt;P&gt;The first time I tried I got the same error as you got:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;{
	"error": {
		"code": 400,
		"error": "invalid_request",
		"error_description": "Invalid PKCE code_challenge_verifier",
		"message": "Invalid PKCE code_challenge_verifier",
		"details": []
	}
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;It was because I was sending the in the "&lt;SPAN&gt;code_verifier" parameter "12345". Reading again &lt;A href="https://developers.arcgis.com/rest/users-groups-and-items/authentication.htm#ESRI_SECTION3_72BB056056CB4F35A1A17EF1D3BEBEA6" target="_self"&gt;the doc&lt;/A&gt;&amp;nbsp;again I noticed:&lt;/SPAN&gt;&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;P&gt;&lt;SPAN&gt;The first step in the PKCE modified workflow is having the application create a code verifier. The code verifier is a cryptographical string using alphanumeric characters (A-Z, a-z, 0-9) and punctuation characters (hyphen, period, underscore, and tilde). &lt;U&gt;&lt;STRONG&gt;A code verifier string should be between 43 to 128 characters long&lt;/STRONG&gt;&lt;/U&gt;.&lt;/SPAN&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;So I encoded 12345 with &lt;A href="https://emn178.github.io/online-tools/sha256.html" target="_self"&gt;this online tool&lt;/A&gt; getting the following hash: "5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5"&lt;/P&gt;&lt;P&gt;Then I tried again and it worked:&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Screenshot 2022-08-02 at 13.00.28.png" style="width: 400px;"&gt;&lt;img src="https://community.esri.com/t5/image/serverpage/image-id/47546i180095BD349A83B2/image-size/medium?v=v2&amp;amp;px=400" role="button" title="Screenshot 2022-08-02 at 13.00.28.png" alt="Screenshot 2022-08-02 at 13.00.28.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;I prefer to use Postman to get familiar with any APIs before I start writing code. But I hope this helps.&lt;/P&gt;&lt;P&gt;Cheers!&lt;/P&gt;</description>
      <pubDate>Tue, 25 Oct 2022 12:05:47 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-rest-apis-and-services-questions/invalid-request-invalid-pkce-code-challenge/m-p/1198430#M4230</guid>
      <dc:creator>Raul_Jimenez</dc:creator>
      <dc:date>2022-10-25T12:05:47Z</dc:date>
    </item>
    <item>
      <title>Re: Invalid request - Invalid PKCE code_challenge_verifier when using oauth2/token</title>
      <link>https://community.esri.com/t5/arcgis-rest-apis-and-services-questions/invalid-request-invalid-pkce-code-challenge/m-p/1198642#M4231</link>
      <description>&lt;P&gt;I'll check again, I had not noticed that.&amp;nbsp; The 12345 was just trying to simplify it to get working.&amp;nbsp;&lt;/P&gt;&lt;P&gt;My original attempts used an SHA256 string created by my app.&amp;nbsp; I'll look at your example and see if I see anything different from what I did&lt;/P&gt;</description>
      <pubDate>Tue, 02 Aug 2022 17:04:13 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-rest-apis-and-services-questions/invalid-request-invalid-pkce-code-challenge/m-p/1198642#M4231</guid>
      <dc:creator>JoeHershman</dc:creator>
      <dc:date>2022-08-02T17:04:13Z</dc:date>
    </item>
    <item>
      <title>Re: Invalid request - Invalid PKCE code_challenge_verifier when using oauth2/token</title>
      <link>https://community.esri.com/t5/arcgis-rest-apis-and-services-questions/invalid-request-invalid-pkce-code-challenge/m-p/1198700#M4232</link>
      <description>&lt;P&gt;My issue was that I was putting S256 not plain when I was generating the authorization code.&amp;nbsp; I guess I misunderstand what one needs to do for using the S256 setting.&amp;nbsp; My initial challenge was created with an SH256 encryption (as yours was), but I guess am supposed to encrypt something being sent back when defining as S256&lt;/P&gt;&lt;P&gt;Thanks - Joe&lt;/P&gt;</description>
      <pubDate>Tue, 02 Aug 2022 19:24:29 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-rest-apis-and-services-questions/invalid-request-invalid-pkce-code-challenge/m-p/1198700#M4232</guid>
      <dc:creator>JoeHershman</dc:creator>
      <dc:date>2022-08-02T19:24:29Z</dc:date>
    </item>
    <item>
      <title>Re: Invalid request - Invalid PKCE code_challenge_verifier when using oauth2/token</title>
      <link>https://community.esri.com/t5/arcgis-rest-apis-and-services-questions/invalid-request-invalid-pkce-code-challenge/m-p/1225093#M4313</link>
      <description>&lt;P&gt;Sorry&amp;nbsp;&lt;a href="https://community.esri.com/t5/user/viewprofilepage/user-id/7529"&gt;@JoeHershman&lt;/a&gt;&amp;nbsp;I'm a little bit late, but I'm taking the opportunity that I'm preparing a session about authentication in ArcGIS for the DevSummit Europe next month and I have solved this using PKCE and SHA256.&lt;/P&gt;&lt;P&gt;This is the right way to generate the &lt;STRONG&gt;code_verifier&lt;/STRONG&gt; and the &lt;STRONG&gt;code_challenge&lt;/STRONG&gt; (Node.js code):&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;let crypto;
try {
  crypto = require("crypto");
} catch (err) {
  console.log('Run $npm install first!');
}

function base64URLEncode(str) {
  return str.toString('base64')
      .replace(/\+/g, '-')
      .replace(/\//g, '_')
      .replace(/=/g, '');
}
const verifier = base64URLEncode(crypto.randomBytes(32));
console.log("Code verifier: ", verifier);

function sha256(buffer) {
  return crypto.createHash('sha256').update(buffer).digest();
}
const challenge = base64URLEncode(sha256(verifier));
console.log("Code challenge: ", challenge);&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;An example running this would return something like this:&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;P&gt;$ node index.js&lt;BR /&gt;Code verifier: CMBya5LFXGJktdlm5OL8bIIpVa4LtUAl4ihYCFalQNc&lt;BR /&gt;Code challenge: qaXuju2sX8lKLvErIKHfdrg0h7DLvSeLuErfsfMJFj4&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;This will work. I have created a &lt;A href="https://github.com/hhkaos/arcgis-oauth-pkce" target="_self"&gt;GitHub repo&lt;/A&gt;&amp;nbsp;plus a &lt;A href="https://www.postman.com/arcgis-developer/workspace/authentication-in-arcgis/request/15786767-e649ea40-8bbd-48bd-a1d7-7c8b6514dc94" target="_self"&gt;Postman collection&lt;/A&gt;&amp;nbsp;with a flow example (+ sample responses to help anyone implement this workflow):&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="2022-10-25_11-36-38.png" style="width: 999px;"&gt;&lt;img src="https://community.esri.com/t5/image/serverpage/image-id/54339iAAA01A3B71C27E25/image-size/large?v=v2&amp;amp;px=999" role="button" title="2022-10-25_11-36-38.png" alt="2022-10-25_11-36-38.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I know this comes late to help you but hopefully it is not late for someone else or at least it is interesting to learn something new&amp;nbsp;&amp;nbsp;(it has been for me!&lt;span class="lia-unicode-emoji" title=":beaming_face_with_smiling_eyes:"&gt;😁&lt;/span&gt;)&lt;/P&gt;&lt;P&gt;Best,&lt;BR /&gt;Raul&lt;/P&gt;</description>
      <pubDate>Tue, 25 Oct 2022 09:43:15 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-rest-apis-and-services-questions/invalid-request-invalid-pkce-code-challenge/m-p/1225093#M4313</guid>
      <dc:creator>Raul_Jimenez</dc:creator>
      <dc:date>2022-10-25T09:43:15Z</dc:date>
    </item>
  </channel>
</rss>

