“Authorization has been denied for this request” when hosting Azure App Service Backend locally on IISAzure Active Directory B2C pricing clarification with refresh tokensHow to use certificate to sign id token in AAD B2CJWT Base64 Decode failed in Notepad++Does Cortana Skill support login with Azure AD B2C account?Getting email after logged in with Azure AD on Azure AD B2CRequest Access Token in Postman for Azure Function App protected by Azure AD B2CResponse from Azure AD B2C without Email?Signing API requests on Azure App Services using MSI Access TokenAzure App Service Easy Auth with Client Credentials Grant flow in AAD B2CHow to get valid AAD v2 token using MSAL.js for Azure DevOps
Can I cause damage to electrical appliances by unplugging them when they are turned on?
Why can't the Brexit deadlock in the UK parliament be solved with a plurality vote?
What does Apple's new App Store requirement mean
Is there a way to have vectors outlined in a Vector Plot?
"It doesn't matter" or "it won't matter"?
Were Persian-Median kings illiterate?
US tourist/student visa
How many arrows is an archer expected to fire by the end of the Tyranny of Dragons pair of adventures?
What is the highest possible scrabble score for placing a single tile
What are some good ways to treat frozen vegetables such that they behave like fresh vegetables when stir frying them?
Are Captain Marvel's powers affected by Thanos breaking the Tesseract and claiming the stone?
Does Doodling or Improvising on the Piano Have Any Benefits?
What fields between the rationals and the reals allow a good notion of 2D distance?
Can I say "fingers" when referring to toes?
What kind of floor tile is this?
Review your own paper in Mathematics
Does an advisor owe his/her student anything? Will an advisor keep a PhD student only out of pity?
Microchip documentation does not label CAN buss pins on micro controller pinout diagram
Is there any evidence that Cleopatra and Caesarion considered fleeing to India to escape the Romans?
Does the reader need to like the PoV character?
Non-trope happy ending?
Strong empirical falsification of quantum mechanics based on vacuum energy density?
How do you make your own symbol when Detexify fails?
Why do ¬, ∀ and ∃ have the same precedence?
“Authorization has been denied for this request” when hosting Azure App Service Backend locally on IIS
Azure Active Directory B2C pricing clarification with refresh tokensHow to use certificate to sign id token in AAD B2CJWT Base64 Decode failed in Notepad++Does Cortana Skill support login with Azure AD B2C account?Getting email after logged in with Azure AD on Azure AD B2CRequest Access Token in Postman for Azure Function App protected by Azure AD B2CResponse from Azure AD B2C without Email?Signing API requests on Azure App Services using MSI Access TokenAzure App Service Easy Auth with Client Credentials Grant flow in AAD B2CHow to get valid AAD v2 token using MSAL.js for Azure DevOps
In my Azure App Service .NET backend, I typically decorate my controllers with [authorize] so that they are protected against users who are not signed in. For uer authentication I set up an Azure Active Directory B2C (AADB2C) tenant, configured an application as well as some identity providers and everything works as expected as long as I am hosting my backend on Azure.
Now, I'd like to be able to run the backend locally so that I can easily debug the code and have it work against a local development database.
However, it does not work.
- I went to https://[myappservice].scm.azurewebsites.net/ and retrieved the WEBSITE_AUTH_SIGNING_KEY from the environment tab.
- I added the key to my backends' web.config as Signingkey under AppSettings
- I changed ValidAudience and ValidIssuer to the respective values (https://[myappservice].azurewebsites.net)
- So that I can bind the backend to an IP address or my hosts name rather than "localhost" (which would be the case with IIS Express), I configured the backend to run under IIS
- I only allowed anonymous access on my IIS Website and let it run under the DefaultAppPool which uses the integrated pipeline on the 4.0 CLR
My client code does not use MobileServiceClient but MSAL (PublicClientApplication). So the documentation about how to setup a local dev environment found here does not apply.
Because I have a RequestProvider class that creates the necessary HttpClient and adds the access token to the header, this shouldn't be a problem, because for authentication, the PublicClientApplication object uses the AADB2C tenant and the respective server flow policies for signing in and -up and for calling the backends' rest controller I can switch between the Azure hosted and the locally hosted backend.
However, while authentication keeps working like a charm and I am able to receive a working access token, the backend that is hosted locally does not accept it while the same backend code hosted on azure does.
So I started searching the net and found out about the website jwt.io. I pasted my access token into their decoder and was astonished about the result.
Some article mentioned that the values ValidIssuer and ValidAudience configured in the backends' web.config need to exactly reflect the values iss and aud contained within the access token.
The values in my access token however don't match the scheme which was part of the web.config template though (https://[myappservice].azurewebsites.net).
The iss field in my decoded token looked like this:
https://[myappservice].b2clogin.com/12345678-1234-1234-1234-123456789012/v2.0/
The aud field in my decoded token looked like this:
12345678-1234-1234-1234-123456789012
The isser value can be found in my AADb2C tenants' directory within the signin/-up policies' settings under Properties in "Token compatibility settings" as Issuer (iss) claim. Theres a combobox from which the following value is selected:
https://<domain>/12345678-1234-1234-1234-123456789012/v2.0/
The aud fields' guid equals the Client ID configured in the App Service on Azure.
However, even if I take these two values and enter them into the web.config as described above, I still get an "Authorization has been denied for this request" error.
I really don't know how to get this working...
access-token azure-ad-b2c msal
add a comment |
In my Azure App Service .NET backend, I typically decorate my controllers with [authorize] so that they are protected against users who are not signed in. For uer authentication I set up an Azure Active Directory B2C (AADB2C) tenant, configured an application as well as some identity providers and everything works as expected as long as I am hosting my backend on Azure.
Now, I'd like to be able to run the backend locally so that I can easily debug the code and have it work against a local development database.
However, it does not work.
- I went to https://[myappservice].scm.azurewebsites.net/ and retrieved the WEBSITE_AUTH_SIGNING_KEY from the environment tab.
- I added the key to my backends' web.config as Signingkey under AppSettings
- I changed ValidAudience and ValidIssuer to the respective values (https://[myappservice].azurewebsites.net)
- So that I can bind the backend to an IP address or my hosts name rather than "localhost" (which would be the case with IIS Express), I configured the backend to run under IIS
- I only allowed anonymous access on my IIS Website and let it run under the DefaultAppPool which uses the integrated pipeline on the 4.0 CLR
My client code does not use MobileServiceClient but MSAL (PublicClientApplication). So the documentation about how to setup a local dev environment found here does not apply.
Because I have a RequestProvider class that creates the necessary HttpClient and adds the access token to the header, this shouldn't be a problem, because for authentication, the PublicClientApplication object uses the AADB2C tenant and the respective server flow policies for signing in and -up and for calling the backends' rest controller I can switch between the Azure hosted and the locally hosted backend.
However, while authentication keeps working like a charm and I am able to receive a working access token, the backend that is hosted locally does not accept it while the same backend code hosted on azure does.
So I started searching the net and found out about the website jwt.io. I pasted my access token into their decoder and was astonished about the result.
Some article mentioned that the values ValidIssuer and ValidAudience configured in the backends' web.config need to exactly reflect the values iss and aud contained within the access token.
The values in my access token however don't match the scheme which was part of the web.config template though (https://[myappservice].azurewebsites.net).
The iss field in my decoded token looked like this:
https://[myappservice].b2clogin.com/12345678-1234-1234-1234-123456789012/v2.0/
The aud field in my decoded token looked like this:
12345678-1234-1234-1234-123456789012
The isser value can be found in my AADb2C tenants' directory within the signin/-up policies' settings under Properties in "Token compatibility settings" as Issuer (iss) claim. Theres a combobox from which the following value is selected:
https://<domain>/12345678-1234-1234-1234-123456789012/v2.0/
The aud fields' guid equals the Client ID configured in the App Service on Azure.
However, even if I take these two values and enter them into the web.config as described above, I still get an "Authorization has been denied for this request" error.
I really don't know how to get this working...
access-token azure-ad-b2c msal
add a comment |
In my Azure App Service .NET backend, I typically decorate my controllers with [authorize] so that they are protected against users who are not signed in. For uer authentication I set up an Azure Active Directory B2C (AADB2C) tenant, configured an application as well as some identity providers and everything works as expected as long as I am hosting my backend on Azure.
Now, I'd like to be able to run the backend locally so that I can easily debug the code and have it work against a local development database.
However, it does not work.
- I went to https://[myappservice].scm.azurewebsites.net/ and retrieved the WEBSITE_AUTH_SIGNING_KEY from the environment tab.
- I added the key to my backends' web.config as Signingkey under AppSettings
- I changed ValidAudience and ValidIssuer to the respective values (https://[myappservice].azurewebsites.net)
- So that I can bind the backend to an IP address or my hosts name rather than "localhost" (which would be the case with IIS Express), I configured the backend to run under IIS
- I only allowed anonymous access on my IIS Website and let it run under the DefaultAppPool which uses the integrated pipeline on the 4.0 CLR
My client code does not use MobileServiceClient but MSAL (PublicClientApplication). So the documentation about how to setup a local dev environment found here does not apply.
Because I have a RequestProvider class that creates the necessary HttpClient and adds the access token to the header, this shouldn't be a problem, because for authentication, the PublicClientApplication object uses the AADB2C tenant and the respective server flow policies for signing in and -up and for calling the backends' rest controller I can switch between the Azure hosted and the locally hosted backend.
However, while authentication keeps working like a charm and I am able to receive a working access token, the backend that is hosted locally does not accept it while the same backend code hosted on azure does.
So I started searching the net and found out about the website jwt.io. I pasted my access token into their decoder and was astonished about the result.
Some article mentioned that the values ValidIssuer and ValidAudience configured in the backends' web.config need to exactly reflect the values iss and aud contained within the access token.
The values in my access token however don't match the scheme which was part of the web.config template though (https://[myappservice].azurewebsites.net).
The iss field in my decoded token looked like this:
https://[myappservice].b2clogin.com/12345678-1234-1234-1234-123456789012/v2.0/
The aud field in my decoded token looked like this:
12345678-1234-1234-1234-123456789012
The isser value can be found in my AADb2C tenants' directory within the signin/-up policies' settings under Properties in "Token compatibility settings" as Issuer (iss) claim. Theres a combobox from which the following value is selected:
https://<domain>/12345678-1234-1234-1234-123456789012/v2.0/
The aud fields' guid equals the Client ID configured in the App Service on Azure.
However, even if I take these two values and enter them into the web.config as described above, I still get an "Authorization has been denied for this request" error.
I really don't know how to get this working...
access-token azure-ad-b2c msal
In my Azure App Service .NET backend, I typically decorate my controllers with [authorize] so that they are protected against users who are not signed in. For uer authentication I set up an Azure Active Directory B2C (AADB2C) tenant, configured an application as well as some identity providers and everything works as expected as long as I am hosting my backend on Azure.
Now, I'd like to be able to run the backend locally so that I can easily debug the code and have it work against a local development database.
However, it does not work.
- I went to https://[myappservice].scm.azurewebsites.net/ and retrieved the WEBSITE_AUTH_SIGNING_KEY from the environment tab.
- I added the key to my backends' web.config as Signingkey under AppSettings
- I changed ValidAudience and ValidIssuer to the respective values (https://[myappservice].azurewebsites.net)
- So that I can bind the backend to an IP address or my hosts name rather than "localhost" (which would be the case with IIS Express), I configured the backend to run under IIS
- I only allowed anonymous access on my IIS Website and let it run under the DefaultAppPool which uses the integrated pipeline on the 4.0 CLR
My client code does not use MobileServiceClient but MSAL (PublicClientApplication). So the documentation about how to setup a local dev environment found here does not apply.
Because I have a RequestProvider class that creates the necessary HttpClient and adds the access token to the header, this shouldn't be a problem, because for authentication, the PublicClientApplication object uses the AADB2C tenant and the respective server flow policies for signing in and -up and for calling the backends' rest controller I can switch between the Azure hosted and the locally hosted backend.
However, while authentication keeps working like a charm and I am able to receive a working access token, the backend that is hosted locally does not accept it while the same backend code hosted on azure does.
So I started searching the net and found out about the website jwt.io. I pasted my access token into their decoder and was astonished about the result.
Some article mentioned that the values ValidIssuer and ValidAudience configured in the backends' web.config need to exactly reflect the values iss and aud contained within the access token.
The values in my access token however don't match the scheme which was part of the web.config template though (https://[myappservice].azurewebsites.net).
The iss field in my decoded token looked like this:
https://[myappservice].b2clogin.com/12345678-1234-1234-1234-123456789012/v2.0/
The aud field in my decoded token looked like this:
12345678-1234-1234-1234-123456789012
The isser value can be found in my AADb2C tenants' directory within the signin/-up policies' settings under Properties in "Token compatibility settings" as Issuer (iss) claim. Theres a combobox from which the following value is selected:
https://<domain>/12345678-1234-1234-1234-123456789012/v2.0/
The aud fields' guid equals the Client ID configured in the App Service on Azure.
However, even if I take these two values and enter them into the web.config as described above, I still get an "Authorization has been denied for this request" error.
I really don't know how to get this working...
access-token azure-ad-b2c msal
access-token azure-ad-b2c msal
asked Mar 7 at 23:55
MephisztoeMephisztoe
1,52452545
1,52452545
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
I tried to reproduce your issue and it works well if in my environment. I was referring to active-directory-b2c-dotnet-desktop as native client and active-directory-b2c-dotnet-webapp-and-webapi (host the api project on IIS, web app project is not used) as backend api.
I also encountered the same issue several times when testing, and resolved it by the following steps:
No special configuration is required on IIS side. You don't need to specify "Signingkey" in web.congig because when validating the token, signing key will be fetched automatically from metedata endpoint (jwks_uri field):
https://TenantName.b2clogin.com/TenantName.onmicrosoft.com/v2.0/.well-known/openid-configuration?p=SignInPolicyName
In Azure Portal, make sure you have granted native client the access to api app.
For other basic configuration, refer to the instruction of samples above.
I also suggest you decode the access token and confirm the primary claims are correct:
- "iss" should be same as the AAD instance in API app
- "aud" should be client id
- "sub" or "oid" should be the object id of the logged in user.
- "tfp" should be the sign in policy name
- "scp" should be published scope of the API app
For other claims, please refer to Azure AD B2C: Token reference
Note, the official samples above are still using login.microsoftonline.com
as authority endpoint, intsead of b2clogin.com
. To use b2clogin, just update the endpoint accordingly.
The below is core code snippet and settings in my working sample:
Native client
public partial class App : Application
private static string TenantName = "<TenantName>";
private static string Tenant = "<TenantName>.onmicrosoft.com";
private static string ClientId = "<ClientID>";
public static string PolicySignUpSignIn = "B2C_1_signupsignin1";
public static string PolicyEditProfile = "b2c_1_edit";
public static string PolicyResetPassword = "b2c_1_reset";
public static string[] ApiScopes = "https://<TenantName>.onmicrosoft.com/demoapi/demo.read" ;
public static string ApiEndpoint = "http://<IISServerAddress>/taskservice/api/tasks";
private static string BaseAuthority = "https://login.microsoftonline.com/tfp/tenant/policy/oauth2/v2.0/authorize";
private static string BaseAuthorityForb2clogin = "https://TenantName.b2clogin.com/tfp/tenant/policy";
public static string Authority = BaseAuthorityForb2clogin.Replace("tenant", Tenant).Replace("policy", PolicySignUpSignIn).Replace("TenantName", TenantName);
public static PublicClientApplication PublicClientApp get; = new PublicClientApplication(ClientId, Authority, TokenCacheHelper.GetUserCache());
API app config:
<add key="ida:AadInstance" value="https://tomtestb2c.b2clogin.com/0/v2.0/.well-known/openid-configuration?p=1" />
<add key="ida:Tenant" value="TenantName.onmicrosoft.com" />
<add key="ida:ClientId" value="ClientId-ff8e-4ac2-a093-6c6e0f8e116c" />
<add key="ida:SignUpSignInPolicyId" value="B2C_1_signupsignin1" />
<!-- The following settings is used for requesting access tokens -->
<add key="api:ReadScope" value="read" />
<add key="api:WriteScope" value="write" />
Auth code:
public partial class Startup
// These values are pulled from web.config
public static string AadInstance = ConfigurationManager.AppSettings["ida:AadInstance"];
public static string Tenant = ConfigurationManager.AppSettings["ida:Tenant"];
public static string ClientId = ConfigurationManager.AppSettings["ida:ClientId"];
public static string SignUpSignInPolicy = ConfigurationManager.AppSettings["ida:SignUpSignInPolicyId"];
public static string DefaultPolicy = SignUpSignInPolicy;
/*
* Configure the authorization OWIN middleware
*/
public void ConfigureAuth(IAppBuilder app)
TokenValidationParameters tvps = new TokenValidationParameters
// Accept only those tokens where the audience of the token is equal to the client ID of this app
ValidAudience = ClientId,
AuthenticationType = Startup.DefaultPolicy
;
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
// This SecurityTokenProvider fetches the Azure AD B2C metadata & signing keys from the OpenIDConnect metadata endpoint
AccessTokenFormat = new JwtFormat(tvps, new OpenIdConnectCachingSecurityTokenProvider(String.Format(AadInstance, Tenant, DefaultPolicy)))
);
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55054705%2fauthorization-has-been-denied-for-this-request-when-hosting-azure-app-service%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I tried to reproduce your issue and it works well if in my environment. I was referring to active-directory-b2c-dotnet-desktop as native client and active-directory-b2c-dotnet-webapp-and-webapi (host the api project on IIS, web app project is not used) as backend api.
I also encountered the same issue several times when testing, and resolved it by the following steps:
No special configuration is required on IIS side. You don't need to specify "Signingkey" in web.congig because when validating the token, signing key will be fetched automatically from metedata endpoint (jwks_uri field):
https://TenantName.b2clogin.com/TenantName.onmicrosoft.com/v2.0/.well-known/openid-configuration?p=SignInPolicyName
In Azure Portal, make sure you have granted native client the access to api app.
For other basic configuration, refer to the instruction of samples above.
I also suggest you decode the access token and confirm the primary claims are correct:
- "iss" should be same as the AAD instance in API app
- "aud" should be client id
- "sub" or "oid" should be the object id of the logged in user.
- "tfp" should be the sign in policy name
- "scp" should be published scope of the API app
For other claims, please refer to Azure AD B2C: Token reference
Note, the official samples above are still using login.microsoftonline.com
as authority endpoint, intsead of b2clogin.com
. To use b2clogin, just update the endpoint accordingly.
The below is core code snippet and settings in my working sample:
Native client
public partial class App : Application
private static string TenantName = "<TenantName>";
private static string Tenant = "<TenantName>.onmicrosoft.com";
private static string ClientId = "<ClientID>";
public static string PolicySignUpSignIn = "B2C_1_signupsignin1";
public static string PolicyEditProfile = "b2c_1_edit";
public static string PolicyResetPassword = "b2c_1_reset";
public static string[] ApiScopes = "https://<TenantName>.onmicrosoft.com/demoapi/demo.read" ;
public static string ApiEndpoint = "http://<IISServerAddress>/taskservice/api/tasks";
private static string BaseAuthority = "https://login.microsoftonline.com/tfp/tenant/policy/oauth2/v2.0/authorize";
private static string BaseAuthorityForb2clogin = "https://TenantName.b2clogin.com/tfp/tenant/policy";
public static string Authority = BaseAuthorityForb2clogin.Replace("tenant", Tenant).Replace("policy", PolicySignUpSignIn).Replace("TenantName", TenantName);
public static PublicClientApplication PublicClientApp get; = new PublicClientApplication(ClientId, Authority, TokenCacheHelper.GetUserCache());
API app config:
<add key="ida:AadInstance" value="https://tomtestb2c.b2clogin.com/0/v2.0/.well-known/openid-configuration?p=1" />
<add key="ida:Tenant" value="TenantName.onmicrosoft.com" />
<add key="ida:ClientId" value="ClientId-ff8e-4ac2-a093-6c6e0f8e116c" />
<add key="ida:SignUpSignInPolicyId" value="B2C_1_signupsignin1" />
<!-- The following settings is used for requesting access tokens -->
<add key="api:ReadScope" value="read" />
<add key="api:WriteScope" value="write" />
Auth code:
public partial class Startup
// These values are pulled from web.config
public static string AadInstance = ConfigurationManager.AppSettings["ida:AadInstance"];
public static string Tenant = ConfigurationManager.AppSettings["ida:Tenant"];
public static string ClientId = ConfigurationManager.AppSettings["ida:ClientId"];
public static string SignUpSignInPolicy = ConfigurationManager.AppSettings["ida:SignUpSignInPolicyId"];
public static string DefaultPolicy = SignUpSignInPolicy;
/*
* Configure the authorization OWIN middleware
*/
public void ConfigureAuth(IAppBuilder app)
TokenValidationParameters tvps = new TokenValidationParameters
// Accept only those tokens where the audience of the token is equal to the client ID of this app
ValidAudience = ClientId,
AuthenticationType = Startup.DefaultPolicy
;
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
// This SecurityTokenProvider fetches the Azure AD B2C metadata & signing keys from the OpenIDConnect metadata endpoint
AccessTokenFormat = new JwtFormat(tvps, new OpenIdConnectCachingSecurityTokenProvider(String.Format(AadInstance, Tenant, DefaultPolicy)))
);
add a comment |
I tried to reproduce your issue and it works well if in my environment. I was referring to active-directory-b2c-dotnet-desktop as native client and active-directory-b2c-dotnet-webapp-and-webapi (host the api project on IIS, web app project is not used) as backend api.
I also encountered the same issue several times when testing, and resolved it by the following steps:
No special configuration is required on IIS side. You don't need to specify "Signingkey" in web.congig because when validating the token, signing key will be fetched automatically from metedata endpoint (jwks_uri field):
https://TenantName.b2clogin.com/TenantName.onmicrosoft.com/v2.0/.well-known/openid-configuration?p=SignInPolicyName
In Azure Portal, make sure you have granted native client the access to api app.
For other basic configuration, refer to the instruction of samples above.
I also suggest you decode the access token and confirm the primary claims are correct:
- "iss" should be same as the AAD instance in API app
- "aud" should be client id
- "sub" or "oid" should be the object id of the logged in user.
- "tfp" should be the sign in policy name
- "scp" should be published scope of the API app
For other claims, please refer to Azure AD B2C: Token reference
Note, the official samples above are still using login.microsoftonline.com
as authority endpoint, intsead of b2clogin.com
. To use b2clogin, just update the endpoint accordingly.
The below is core code snippet and settings in my working sample:
Native client
public partial class App : Application
private static string TenantName = "<TenantName>";
private static string Tenant = "<TenantName>.onmicrosoft.com";
private static string ClientId = "<ClientID>";
public static string PolicySignUpSignIn = "B2C_1_signupsignin1";
public static string PolicyEditProfile = "b2c_1_edit";
public static string PolicyResetPassword = "b2c_1_reset";
public static string[] ApiScopes = "https://<TenantName>.onmicrosoft.com/demoapi/demo.read" ;
public static string ApiEndpoint = "http://<IISServerAddress>/taskservice/api/tasks";
private static string BaseAuthority = "https://login.microsoftonline.com/tfp/tenant/policy/oauth2/v2.0/authorize";
private static string BaseAuthorityForb2clogin = "https://TenantName.b2clogin.com/tfp/tenant/policy";
public static string Authority = BaseAuthorityForb2clogin.Replace("tenant", Tenant).Replace("policy", PolicySignUpSignIn).Replace("TenantName", TenantName);
public static PublicClientApplication PublicClientApp get; = new PublicClientApplication(ClientId, Authority, TokenCacheHelper.GetUserCache());
API app config:
<add key="ida:AadInstance" value="https://tomtestb2c.b2clogin.com/0/v2.0/.well-known/openid-configuration?p=1" />
<add key="ida:Tenant" value="TenantName.onmicrosoft.com" />
<add key="ida:ClientId" value="ClientId-ff8e-4ac2-a093-6c6e0f8e116c" />
<add key="ida:SignUpSignInPolicyId" value="B2C_1_signupsignin1" />
<!-- The following settings is used for requesting access tokens -->
<add key="api:ReadScope" value="read" />
<add key="api:WriteScope" value="write" />
Auth code:
public partial class Startup
// These values are pulled from web.config
public static string AadInstance = ConfigurationManager.AppSettings["ida:AadInstance"];
public static string Tenant = ConfigurationManager.AppSettings["ida:Tenant"];
public static string ClientId = ConfigurationManager.AppSettings["ida:ClientId"];
public static string SignUpSignInPolicy = ConfigurationManager.AppSettings["ida:SignUpSignInPolicyId"];
public static string DefaultPolicy = SignUpSignInPolicy;
/*
* Configure the authorization OWIN middleware
*/
public void ConfigureAuth(IAppBuilder app)
TokenValidationParameters tvps = new TokenValidationParameters
// Accept only those tokens where the audience of the token is equal to the client ID of this app
ValidAudience = ClientId,
AuthenticationType = Startup.DefaultPolicy
;
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
// This SecurityTokenProvider fetches the Azure AD B2C metadata & signing keys from the OpenIDConnect metadata endpoint
AccessTokenFormat = new JwtFormat(tvps, new OpenIdConnectCachingSecurityTokenProvider(String.Format(AadInstance, Tenant, DefaultPolicy)))
);
add a comment |
I tried to reproduce your issue and it works well if in my environment. I was referring to active-directory-b2c-dotnet-desktop as native client and active-directory-b2c-dotnet-webapp-and-webapi (host the api project on IIS, web app project is not used) as backend api.
I also encountered the same issue several times when testing, and resolved it by the following steps:
No special configuration is required on IIS side. You don't need to specify "Signingkey" in web.congig because when validating the token, signing key will be fetched automatically from metedata endpoint (jwks_uri field):
https://TenantName.b2clogin.com/TenantName.onmicrosoft.com/v2.0/.well-known/openid-configuration?p=SignInPolicyName
In Azure Portal, make sure you have granted native client the access to api app.
For other basic configuration, refer to the instruction of samples above.
I also suggest you decode the access token and confirm the primary claims are correct:
- "iss" should be same as the AAD instance in API app
- "aud" should be client id
- "sub" or "oid" should be the object id of the logged in user.
- "tfp" should be the sign in policy name
- "scp" should be published scope of the API app
For other claims, please refer to Azure AD B2C: Token reference
Note, the official samples above are still using login.microsoftonline.com
as authority endpoint, intsead of b2clogin.com
. To use b2clogin, just update the endpoint accordingly.
The below is core code snippet and settings in my working sample:
Native client
public partial class App : Application
private static string TenantName = "<TenantName>";
private static string Tenant = "<TenantName>.onmicrosoft.com";
private static string ClientId = "<ClientID>";
public static string PolicySignUpSignIn = "B2C_1_signupsignin1";
public static string PolicyEditProfile = "b2c_1_edit";
public static string PolicyResetPassword = "b2c_1_reset";
public static string[] ApiScopes = "https://<TenantName>.onmicrosoft.com/demoapi/demo.read" ;
public static string ApiEndpoint = "http://<IISServerAddress>/taskservice/api/tasks";
private static string BaseAuthority = "https://login.microsoftonline.com/tfp/tenant/policy/oauth2/v2.0/authorize";
private static string BaseAuthorityForb2clogin = "https://TenantName.b2clogin.com/tfp/tenant/policy";
public static string Authority = BaseAuthorityForb2clogin.Replace("tenant", Tenant).Replace("policy", PolicySignUpSignIn).Replace("TenantName", TenantName);
public static PublicClientApplication PublicClientApp get; = new PublicClientApplication(ClientId, Authority, TokenCacheHelper.GetUserCache());
API app config:
<add key="ida:AadInstance" value="https://tomtestb2c.b2clogin.com/0/v2.0/.well-known/openid-configuration?p=1" />
<add key="ida:Tenant" value="TenantName.onmicrosoft.com" />
<add key="ida:ClientId" value="ClientId-ff8e-4ac2-a093-6c6e0f8e116c" />
<add key="ida:SignUpSignInPolicyId" value="B2C_1_signupsignin1" />
<!-- The following settings is used for requesting access tokens -->
<add key="api:ReadScope" value="read" />
<add key="api:WriteScope" value="write" />
Auth code:
public partial class Startup
// These values are pulled from web.config
public static string AadInstance = ConfigurationManager.AppSettings["ida:AadInstance"];
public static string Tenant = ConfigurationManager.AppSettings["ida:Tenant"];
public static string ClientId = ConfigurationManager.AppSettings["ida:ClientId"];
public static string SignUpSignInPolicy = ConfigurationManager.AppSettings["ida:SignUpSignInPolicyId"];
public static string DefaultPolicy = SignUpSignInPolicy;
/*
* Configure the authorization OWIN middleware
*/
public void ConfigureAuth(IAppBuilder app)
TokenValidationParameters tvps = new TokenValidationParameters
// Accept only those tokens where the audience of the token is equal to the client ID of this app
ValidAudience = ClientId,
AuthenticationType = Startup.DefaultPolicy
;
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
// This SecurityTokenProvider fetches the Azure AD B2C metadata & signing keys from the OpenIDConnect metadata endpoint
AccessTokenFormat = new JwtFormat(tvps, new OpenIdConnectCachingSecurityTokenProvider(String.Format(AadInstance, Tenant, DefaultPolicy)))
);
I tried to reproduce your issue and it works well if in my environment. I was referring to active-directory-b2c-dotnet-desktop as native client and active-directory-b2c-dotnet-webapp-and-webapi (host the api project on IIS, web app project is not used) as backend api.
I also encountered the same issue several times when testing, and resolved it by the following steps:
No special configuration is required on IIS side. You don't need to specify "Signingkey" in web.congig because when validating the token, signing key will be fetched automatically from metedata endpoint (jwks_uri field):
https://TenantName.b2clogin.com/TenantName.onmicrosoft.com/v2.0/.well-known/openid-configuration?p=SignInPolicyName
In Azure Portal, make sure you have granted native client the access to api app.
For other basic configuration, refer to the instruction of samples above.
I also suggest you decode the access token and confirm the primary claims are correct:
- "iss" should be same as the AAD instance in API app
- "aud" should be client id
- "sub" or "oid" should be the object id of the logged in user.
- "tfp" should be the sign in policy name
- "scp" should be published scope of the API app
For other claims, please refer to Azure AD B2C: Token reference
Note, the official samples above are still using login.microsoftonline.com
as authority endpoint, intsead of b2clogin.com
. To use b2clogin, just update the endpoint accordingly.
The below is core code snippet and settings in my working sample:
Native client
public partial class App : Application
private static string TenantName = "<TenantName>";
private static string Tenant = "<TenantName>.onmicrosoft.com";
private static string ClientId = "<ClientID>";
public static string PolicySignUpSignIn = "B2C_1_signupsignin1";
public static string PolicyEditProfile = "b2c_1_edit";
public static string PolicyResetPassword = "b2c_1_reset";
public static string[] ApiScopes = "https://<TenantName>.onmicrosoft.com/demoapi/demo.read" ;
public static string ApiEndpoint = "http://<IISServerAddress>/taskservice/api/tasks";
private static string BaseAuthority = "https://login.microsoftonline.com/tfp/tenant/policy/oauth2/v2.0/authorize";
private static string BaseAuthorityForb2clogin = "https://TenantName.b2clogin.com/tfp/tenant/policy";
public static string Authority = BaseAuthorityForb2clogin.Replace("tenant", Tenant).Replace("policy", PolicySignUpSignIn).Replace("TenantName", TenantName);
public static PublicClientApplication PublicClientApp get; = new PublicClientApplication(ClientId, Authority, TokenCacheHelper.GetUserCache());
API app config:
<add key="ida:AadInstance" value="https://tomtestb2c.b2clogin.com/0/v2.0/.well-known/openid-configuration?p=1" />
<add key="ida:Tenant" value="TenantName.onmicrosoft.com" />
<add key="ida:ClientId" value="ClientId-ff8e-4ac2-a093-6c6e0f8e116c" />
<add key="ida:SignUpSignInPolicyId" value="B2C_1_signupsignin1" />
<!-- The following settings is used for requesting access tokens -->
<add key="api:ReadScope" value="read" />
<add key="api:WriteScope" value="write" />
Auth code:
public partial class Startup
// These values are pulled from web.config
public static string AadInstance = ConfigurationManager.AppSettings["ida:AadInstance"];
public static string Tenant = ConfigurationManager.AppSettings["ida:Tenant"];
public static string ClientId = ConfigurationManager.AppSettings["ida:ClientId"];
public static string SignUpSignInPolicy = ConfigurationManager.AppSettings["ida:SignUpSignInPolicyId"];
public static string DefaultPolicy = SignUpSignInPolicy;
/*
* Configure the authorization OWIN middleware
*/
public void ConfigureAuth(IAppBuilder app)
TokenValidationParameters tvps = new TokenValidationParameters
// Accept only those tokens where the audience of the token is equal to the client ID of this app
ValidAudience = ClientId,
AuthenticationType = Startup.DefaultPolicy
;
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
// This SecurityTokenProvider fetches the Azure AD B2C metadata & signing keys from the OpenIDConnect metadata endpoint
AccessTokenFormat = new JwtFormat(tvps, new OpenIdConnectCachingSecurityTokenProvider(String.Format(AadInstance, Tenant, DefaultPolicy)))
);
answered Mar 14 at 5:06
axfdaxfd
1595
1595
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55054705%2fauthorization-has-been-denied-for-this-request-when-hosting-azure-app-service%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown