I created a spa
application owned by my organization only, but there was a problem when I requested code. How can I resolve it?

- 27,717
- 28
- 128
- 190

- 609
- 1
- 5
- 6
-
4Try to change the platform configuration from `SPA` to `Web`. What is the result? – Carl Zhao Nov 05 '20 at 07:30
-
1This likely depends heavily on the type of application architecture you are using (not mentioned in the question). I received this error as well trying to use the AzureADProvider in Next-Auth (v4) for a NextJs app (standard NextJs server config - not custom server) with Azure configuration set to the SPA platform. However when I switched to using `@azure/msal-browser` and `@azure/msal-react` I had to switch my Azure app platform back to SPA for the authentication to succeed. – w. Patrick Gale Nov 12 '21 at 20:26
4 Answers
I can reproduce your problem, you have to add the redirect URL under the web (not single page application). After that, you will be able to use the auth code flow to get the code.

- 8,543
- 2
- 11
- 19
-
3Thank you, this and the Fiddler advice (here: https://learn.microsoft.com/en-us/answers/questions/270056/aadsts50011-the-reply-url-specified-in-the-request-17.html) which exposed the fact that, regardless of what I had configured in azure for the site registration redirect uri, ms login was sending my redirect setting suffixed with "./.auth/login/aad/callback". Matching that in a "Web" registration profile got it working. Btw, I have a SPA, use MSAL2 and set redirectUri to "location.origin" which works for both local and published. – Rodney Oct 22 '21 at 16:06
-
-
13now I get an "Cross-origin token redemption is permitted only for the 'Single-Page Application' client-type" THIS IS A CERTIFIED MICROSOFT MOMENT – oren revenge May 10 '22 at 07:40
-
-
1@norgie Yes, you _do_ keep both: for `Web` you enter `https://
.azurewebsites.net/.auth/login/aad/callback` & for `SPA` you simply enter `https://skywalk.azurewebsites.net` - However, after publishing a default Blazor WASM app, I now do see its `Index` page, but no style is applied. WTF?! – Yoda Nov 23 '22 at 15:40
There is a problem with the accepted answer: The question was for SPA WEB, but the proposed solution was to change it to SSR WEB
For ssr webs, the flow used is called OAuth 2.0 authorization code flow in which a code is sent from microsoft after the success login (302 redirect) and the this code is exchanged for a new access_token (microsoft internal apis).
For spa webs, in which sometimes there is no a programmable backend server serving the web files (index.html, js, css) able to receive the code and exchange it for an access_token. The flow used is called OAuth 2.0 implicit grant flow in which ID tokens or access tokens are returned directly from microsoft after the success login (302 redirect)
Note: Implicit grant flow is being deprecated in some IAM platforms
If you are developing a spa web with pure react, angular,vue, etc instead of ssr web with java, c#, php, etc or hybrids like nuxt, next, etc and you need the access_token instead the auth code (ssr) you should follow these steps:
Step 1
Register your app as admin or a simple user
https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade
Step 2
add a web platform type SPA with the redirect to your spa
Step 3
Check the access token checkbox
Step 4
In this step, you should be able to obtain the classic values (google, facebook, microsoft, etc) for this kind of login: clientid, clientsecret, reduirect_uri, tenant, etc
Step 5
At the spa source code layer, change the response_type=code to response_type=token in your authorize url
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&response_type=token
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&scope=openid
&response_mode=query
Additional
If everything works, all of your final users will be prompted with something like this at the login step:
Yes, this is another "Azure feature". Anyway who told you to use Microsoft tools ??
To avoid that, with the admin help, approve it or follow these infinite steps to mark your app as verified
References:
- https://developer.okta.com/blog/2018/04/10/oauth-authorization-code-grant-type
- https://developer.okta.com/blog/2018/05/24/what-is-the-oauth2-implicit-grant-type
- https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-implicit-grant-flow
- https://learn.microsoft.com/en-us/power-apps/developer/data-platform/walkthrough-register-app-azure-active-directory

- 14,356
- 6
- 59
- 94
Don't know if I am late but I've had the same issue in my React SPA Application and the solutions wasn't to change my app to Web in Portal, it was solving the actual problem which was there was no proof key in my request. I've solved it by my making helper functions and adding this in url where I send users to authenticate:
function buildAuthorizationUrl(codeChallenge) {
const clientId = "YOUR_CLIENT_ID":
const redirectUri = encodeURIComponent("http://localhost:5173/auth/");
// Change to url you need
const responseType = "code";
const scope = encodeURIComponent("openid profile offline_access User.Read");
const state = encodeURIComponent("my_custom_state");
return `https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=${clientId}&response_type=${responseType}&redirect_uri=${redirectUri}&scope=${scope}&state=${state}&code_challenge=${codeChallenge}&code_challenge_method=S256`;
}
async function generateCodeVerifier() {
const array = new Uint8Array(32);
crypto.getRandomValues(array);
return Array.from(array)
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
}
async function generateCodeChallenge(codeVerifier) {
const encoder = new TextEncoder();
const data = encoder.encode(codeVerifier);
const digest = await crypto.subtle.digest("SHA-256", data);
const base64Url = (arrayBuffer) => {
const base64 = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
return base64.replace("+", "-").replace("/", "_").replace(/=+$/, "");
};
return base64Url(digest);
}
And then when user clicks the button for logging I've added this logic:
const handleClick = async () => {
const codeVerifier = await generateCodeVerifier();
const codeChallenge = await generateCodeChallenge(codeVerifier);
sessionStorage.setItem("code_verifier", codeVerifier);
const authUrl = buildAuthorizationUrl(codeChallenge);
window.location.href = authUrl;
};
Of course, if you are not dealing with common tenant, that should also be changed in buildAuthorizationUrl function.

- 41
- 2
I have created same spa application in my organization and created same redirect uri for SPA, since it is inside organization so i did not have access to change configuration for the existing app. It may not be ideal for some cases. I have solved it by sending PKCE information for auth and token request as described in OAuth .
First generate code_verifier
from random string then generate code_challenge
using code_verifier
.
You need to Add code_challenge
in your request for authorization_code
along with code_challenge_method:S256
(SHA256).
For token code_verifier
needs to be sent for token request.
Curl Request sample is given below,
Authorization
curl --location --request GET 'https://login.microsoftonline.com/<tenat_id>/oauth2/v2.0/authorize?client_id=<client_id>&redirect_uri=<redirect_uri>&scope=<scope>&response_type=code&response_mode=query&sate=demo&code_challenge=<code_challenge>&code_challenge_method=S256'
Token
curl --location --request POST 'https://login.microsoftonline.com/<tenat_id>/oauth2/v2.0/token --form 'code_verifier=<code_verifier>

- 344
- 2
- 8