I have the code below in .Net which is a one for one conversion from the Python code provided in SDK. When I run the Python code it works fine. When I try the .Net version I get the following error. I have checked the URL and they are the same except the callback URL. I have created two application profiles with the unique CallbackUrl for each application also. Any assistance is greatly appreciated.
Your request resulted in an error. The ‘redirect_uri’ parameter must be a Login redirect URI in the client app settings:
https://dev-53901427-admin.okta.com/admin/app/oidc_client/instance/0oadaen2d0sJl7Nol5d7#tab-general
protected void Button1_Click(object sender, EventArgs e)
{
byte[] appStateBytes = new byte[64];
byte[] codeVerifierBytes = new byte[64];
byte[] hashedBytes = new byte[64];
string codeChallenge = "";
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(appStateBytes);
rng.GetBytes(codeVerifierBytes);
}
string appState = Convert.ToBase64String(appStateBytes).TrimEnd('=').Replace('+', '-').Replace('/', '_');
string codeVerifier = Convert.ToBase64String(codeVerifierBytes).TrimEnd('=').Replace('+', '-').Replace('/', '_');
Session["app_state"] = appState;
Session["code_verifier"] = codeVerifier;
using (SHA256 sha256 = SHA256.Create())
{
hashedBytes = sha256.ComputeHash(Encoding.ASCII.GetBytes(codeVerifier));
codeChallenge = Convert.ToBase64String(hashedBytes).TrimEnd('=').Replace('+', '-').Replace('/', '_');
}
// Get request params
var queryParams = new Dictionary<string, string>
{
["client_id"] = System.Configuration.ConfigurationManager.AppSettings["CLIENTID"],
["redirect_uri"] = System.Configuration.ConfigurationManager.AppSettings["CallbackUrl"],
["scope"] = "openid email profile",
["state"] = appState,
["code_challenge"] = codeChallenge,
["code_challenge_method"] = "S256",
["response_type"] = "code",
["response_mode"] = "query"
};
StringBuilder queryBuilder = new StringBuilder();
foreach (var param in queryParams)
{
if (queryBuilder.Length > 0)
queryBuilder.Append('&');
queryBuilder.Append(HttpUtility.UrlEncode(param.Key));
queryBuilder.Append('=');
queryBuilder.Append(HttpUtility.UrlEncode(param.Value));
}
string baseUrl = System.Configuration.ConfigurationManager.AppSettings["AuthorizeUrl"];
string requestUri = baseUrl + "?" + queryBuilder.ToString();
Response.Redirect(requestUri);
}
Here is the Python clogin code which works
@app.route("/login")
def login():
# store app state and code verifier in session
session['app_state'] = secrets.token_urlsafe(64)
session['code_verifier'] = secrets.token_urlsafe(64)
# calculate code challenge
hashed = hashlib.sha256(session['code_verifier'].encode('ascii')).digest()
encoded = base64.urlsafe_b64encode(hashed)
code_challenge = encoded.decode('ascii').strip('=')
# get request params
query_params = {'client_id': os.environ['CLIENT_ID'],
'redirect_uri': "http://localhost:5000/authorization-code/callback",
'scope': "openid email profile",
'state': session['app_state'],
'code_challenge': code_challenge,
'code_challenge_method': 'S256',
'response_type': 'code',
'response_mode': 'query'}
# build request_uri
request_uri = "{base_url}?{query_params}".format(
base_url=os.environ['ORG_URL'] + "oauth2/default/v1/authorize",
query_params=requests.compat.urlencode(query_params)
)
print(request_uri)
return redirect(request_uri)