Azure ADB2C redirecting to wrong domain - azure

I have following situation:
I'm trying to integrate ADB2C with my SPA app in backend:
IdentityModelEventSource.ShowPII = true;
services.AddSession();
services.AddAuthentication(AzureADB2CDefaults.AuthenticationScheme)
.AddAzureADB2C(options => configuration.Bind("AzureAd", options))
.AddApiKeySupport(options => { });
services.AddOptions<OpenIdConnectOptions>(AzureADB2CDefaults.OpenIdScheme).Configure<IGraphServiceClient, ILogRepository>((options, graphClient, logRepo) =>
{
var oldPostValidate = options.Events.OnTokenValidated;
options.Events.OnTokenValidated = async (context) =>
{
await new AzureADB2CHelper(graphClient).OnTokenValidated(context);
await oldPostValidate(context);
};
});
Also I set configuration:
"AzureAd": {
"Instance": "https://rqrar.b2clogin.com/",
"Domain": "rqrar.onmicrosoft.com",
"TenantId": "guid",
"ClientId": "guid",
"CallbackPath": "/api/response-oidc",
"SignUpSignInPolicyId": "B2C_1_SIGN_IN",
"ResetPasswordPolicyId": "B2C_1_PASSWORD_RESET",
}
In app registration I have application with redirect uri: https://custom-domain.com/api/response-oidc
And now if user will correctly login I'm expecting he will be redirected to https://custom-domain.com/api/response-oidc instead of this ADB2C is trying redirect user to https://default-generated-url-by-azure.azurewebsites.net/api/response-oidc
Have anyone idea what can I missing ?

Related

Swagger authenticate Azure AD B2C redirect url

I could authenticate swagger on Azure AD B2C. It works fine on http://localhost:5078/ . But as soon as I push my website to azure I can not authenticate swagger. It still uses localhost:5078 as redirect URL and not azure website URL.
My code:
builder.Services.AddSwaggerGen(c => {
var OATH2 = "oauth2";
// Enabled OAuth security in Swagger. From here: https://stackoverflow.com/questions/66894523/swagger-not-able-to-authenticate-to-azure-ad-b2c
c.AddSecurityRequirement(new OpenApiSecurityRequirement() {
{
new OpenApiSecurityScheme {
Reference = new OpenApiReference {
Type = ReferenceType.SecurityScheme,
Id = OATH2
}
},
new List<string>()
}
});
c.AddSecurityDefinition(OATH2, new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows
{
Implicit = new OpenApiOAuthFlow()
{
AuthorizationUrl = new Uri($"{builder.Configuration["AzureAdB2C:Instance"]}/{builder.Configuration["AzureAdB2C:Domain"]}/{builder.Configuration["AzureAdB2C:SignUpSignInPolicyId"]}/oauth2/v2.0/authorize"),
TokenUrl = new Uri($"{builder.Configuration["AzureAdB2C:Instance"]}/{builder.Configuration["AzureAdB2C:Domain"]}/{builder.Configuration["AzureAdB2C:SignUpSignInPolicyId"]}/oauth2/v2.0/token"),
Scopes = new Dictionary<string, string>() { { builder.Configuration["AzureAdB2C:Scope"], "backend all" } }
}
}
});
});
....
app.UseSwagger();
app.UseSwaggerUI(c => {
c.OAuthClientId(builder.Configuration["AzureAdB2C:SwaggerClientId"]);
c.OAuthScopes(builder.Configuration["AzureAdB2C:Scope"]);
c.OAuthUsePkce();
});
OK on localhost:
Not OK on azure:
https://anna-carat-auth-test.azurewebsites.net/swagger/index.html
Both redirect URLs are registered in app:
How to set a proper redirect URL for swagger?
Created a sample Web Api application.
In Visual Studio click on connected services and add a dependency of Microsoft Identity platform as shown in below snippet.
Once the dependencies are added then in Program.cs file is updated with Azure AD related settings.
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
// It added the Authentication and Authorization methods.
app.UseAuthentication();
app.UseAuthorization();
In Program.cs file made the code changes as shown below.
builder.Services.AddSwaggerGen(
x =>
{
x.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo
{
Title = "Swagger Azure AD Demo",
Version = "v1"
});
x.AddSecurityDefinition("oauth2", new Microsoft.OpenApi.Models.OpenApiSecurityScheme
{
Description = "Oauth2.0 which uses AuthorizationCode flow",
Name = "oauth2.0",
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows
{
AuthorizationCode = new OpenApiOAuthFlow
{
AuthorizationUrl = new Uri(builder.Configuration["SwaggerAzureAD:AuthorizationUrl"]),
TokenUrl = new Uri(builder.Configuration["SwaggerAzureAD:TokenUrl"]),
Scopes = new Dictionary<string, string>
{
{builder.Configuration["SwaggerAzureAD:Scope"], "Access API as User" }
}
}
}
});
x.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference= new OpenApiReference{Type=ReferenceType.SecurityScheme,Id="oauth2"}
},
new[]{builder.Configuration["SwaggerAzureAD:Scope"]}
}
});
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(x=>
{
x.OAuthClientId(builder.Configuration["SwaggerAzureAD:ClientId"]);
x.OAuthUsePkce();
});
}
And the AppSettings.Json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "Something.onmicrosoft.com",
"TenantId": "TenantID",
"ClientId": "ClientID",
"CallbackPath": "/signin-oidc",
"Scopes": "access_as_user"
},
// These values need to be copied from App registartion
"SwaggerAzureAD": {
"AuthorizationUrl": "",
"TokenUrl": "",
"ClientId": "",
"Scope": ""
}
}
Expose API from App registration.
API Permissions need to be given in the App registrations of Azure.
And has to be copied the value and need to use in the scope attribute of AppSettings.json
And redirection urls to be mentioned and to be used in AppSettings.json form App registration -> Authentication as shown in below snippet.
And able to get the response without any issues.
Response:

Blazor server authorized downstream API call with Azure AD B2C

I’m trying to use Microsoft.Identity.Web to call an API from my .NET 6 Blazor server app. I can successfully login to authorized pages in my Blazor app but when I try to make an API call using CallWebApiForUserAsync I get an inner exception of “No account or login hint was passed to the AcquireTokenSilent call”.
The couple of posts here on Stack Overflow and the MS documentation look to me like I have it configured correctly. What am I missing?
appsettings.json:
"AzureAd": {
"Authority": "https://hivercom.b2clogin.com/XXXXXX.onmicrosoft.com/B2C_1_SignUpSignIn",
"Instance": "https://XXXXXX.b2clogin.com",
"TenantId": "XXXXXX-XXXXXX-XXXXXX-XXXXXX-XXXXXX",
"ClientId": "XXXXXX-XXXXXX-XXXXXX-XXXXXX-XXXXXX",
"CallbackPath": "/signin-oidc",
"Domain": "XXXXXX.onmicrosoft.com",
"SignedOutCallbackPath": "/signout/B2C_1_susi",
"SignUpSignInPolicyId": "B2C_1_SignUpSignIn",
"ResetPasswordPolicyId": "B2C_1_PasswordReset",
"EditProfilePolicyId": "B2C_1_EditProfile",
"ClientSecret": "XXXXXXXXXXXXXXXXXX"
},
"HiverAPI": {
"BaseUrl": "https://localhost:7075",
"Scopes": "https://XXXXXX.onmicrosoft.com/XXXXXX-XXXXXX-XXXXXX-XXXXXX-XXXXXX/all"
},
Program.cs
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.UI;
using BlazorB2C.Data;
using Microsoft.Identity.Web.TokenCacheProviders.InMemory;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Authorization;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpClient();
builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi(new string[] { "https://XXXXXX.onmicrosoft.com/XXXXXX-XXXXXX-XXXXXX-XXXXXX-XXXXXX/all" })
.AddDownstreamWebApi("HiverService", builder.Configuration.GetSection("HiverAPI"))
.AddInMemoryTokenCaches();
builder.Services.AddAuthorization(options =>
{
options.FallbackPolicy = options.DefaultPolicy;
});
builder.Services.AddRazorPages().AddMvcOptions(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
}).AddMicrosoftIdentityUI();
builder.Services.AddServerSideBlazor()
.AddMicrosoftIdentityConsentHandler();
builder.Services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.Events.OnSignedOutCallbackRedirect = context =>
{
context.HttpContext.Response.Redirect(context.Options.SignedOutRedirectUri);
context.HandleResponse();
return Task.CompletedTask;
};
});
builder.Services.AddSingleton<WeatherForecastService>();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.Run();
Level.razor:
#page "/level"
#using Microsoft.Identity.Web
#inject IHttpClientFactory HttpClientFactory
#inject Microsoft.Identity.Web.ITokenAcquisition TokenAcquisitionService
#inject Microsoft.Identity.Web.IDownstreamWebApi DownstreamWebApi
#inject MicrosoftIdentityConsentAndConditionalAccessHandler ConsentHandler
#attribute [Authorize]
#attribute [AuthorizeForScopes(ScopeKeySection = "HiverAPI:Scopes")]
<PageTitle>Level</PageTitle>
Log out
<h3>Level</h3>
#code {
private const string ServiceName = "HiverService";
protected override async Task OnInitializedAsync()
{
try
{
error >> string token = await TokenAcquisitionService.GetAccessTokenForUserAsync(new string[] { "https://XXXXXX.onmicrosoft.com/XXXXXX-XXXXXX-XXXXXX-XXXXXX-XXXXXX/all" });
error >> var value = await DownstreamWebApi.CallWebApiForUserAsync(
ServiceName,
options =>
{
options.RelativePath = $"HiverUser";
});
}
catch (Exception ex)
{
var message = ex.Message;
ConsentHandler.HandleException(ex);
}
try
{
error >> await DownstreamWebApi.CallWebApiForUserAsync(
ServiceName,
options =>
{
options.HttpMethod = HttpMethod.Put;
options.RelativePath = $"HiverUser/0fd30e94-a116-4ef0-b222-4125546b8561";
});
}
catch (Exception ex)
{
var message = ex.Message;
ConsentHandler.HandleException(ex);
}
}
}
Azure configuration for client app:
Azure configuration for API
CallWebApiForAppAsync uses the on-behalf flow, which is not available for Azure AD B2C.
https://github.com/AzureAD/microsoft-identity-web/wiki/b2c-limitations
You cannot use ITokenAcquisition.GetTokenForAppAsync or IDownstreamApi.CallWebApiForAppAsync in Azure AD B2C web apps.
https://learn.microsoft.com/en-us/azure/active-directory-b2c/access-tokens
As an alternative, you can request access tokens for downstream APIs(Hiver.API in your case) using GetAccessTokenForUserAsync. The resulting access token can be used to call the API. You'll need to use a standard HttpClient instead of IDownstreamWebApi. Full example can be found here:
https://github.com/Azure-Samples/ms-identity-blazor-server/blob/main/WebApp-your-API/B2C/README-Incremental.md
Relevant code from Github:
private async Task PrepareAuthenticatedClient()
{
var accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(new[] { _TodoListScope });
Debug.WriteLine($"access token-{accessToken}");
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}

Azure AD C2C/Next.Js/ASP.NET Core 6: How to use PKCE auth code flow access tokens to access Web API?

I need help, I got stuck for a few days trying to protect a Web API (ASP.NET Core 6) by sending access token from users (Azure Ad B2C with google provider/local account) signed in with authentication code flow (PKCE).
This generates a (401) unauthorized error. What is going wrong?
The Next.js Application: (helloworld.webapp)
Azure Ad B2C settings
Manage -> Authentication
Single-page-application with redirect uri: http://localhost:3000
Manage -> API permissions
helloworld.api
access_as_user | admin consent required: yes | status: ✅ Granted for helloworld
Microsoft Graph
offline_access | admin consent required: yes | status: ✅ Granted for helloworld
openid | admin consent required: yes | status: ✅ Granted for helloworld
(unchecked)
🔲 Access tokens (used for implicit flows)
🔲 ID tokens (used for implicit and hybrid flows)
This is how you log in.
const login = (event: React.MouseEvent<HTMLButtonElement>) => {
console.log("only logs in browser console")
instance.loginRedirect({
scopes: [
"openid",
"offline_access",
// ✅ checked for typo
"https://helloworld.onmicrosoft.com/8a1bc000-2000-4000-a000-d3156a663000/access_as_user",
]
})
}
In the following snippet you can see how I get my accessToken.
const postData = (event: React.MouseEvent<HTMLButtonElement>) => {
event.preventDefault();
// to prevent ssr mismatch errors.
if (!data && inProgress === InteractionStatus.None) {
instance
.acquireTokenSilent({
scopes: [
"openid",
"offline_access",
// ✅ checked for typo
"https://helloworld.onmicrosoft.com/8a1bc000-2000-4000-a000-d3156a663000/access_as_user",
]
})
.then((accessTokenResponse) => {
let accesstoken = accessTokenResponse.accessToken;
console.log(accesstoken); // 👍only logs in browser console.
// // ✅ weatherforecast endpoint checked. Maps to http://localhost:5015/api/:path*
fetch("/api/net/weatherforecast", {
method: "GET",
headers: {
Authorization: `Bearer ${JSON.stringify(accesstoken)}`,
},
})
.then((res) => console.log(res))
.catch((err) => console.log(err));
});
}
};
I have the following rule in next.config.js
async rewrites() {
return {
fallback: [
{
source: "/api/net/:path*",
destination: "http://localhost:5015/api/:path*",
},
],
};
},
ASP.NET Core 6 application: (helloworld.api)
manage -> expose API
scopes ✅ all checked for typo
https://helloworld.onmicrosoft.com/8a1bc000-2000-4000-a000-d3156a663000/access_as_user
Who can consent: Admins only
State: Enabled
The appsettings.json
"AzureAdB2C": {
"Instance": "https://helloworld.b2clogin.com/",
"ClientId": "8a1bc000-2000-4000-a000-d3156a663000",
"Domain": "helloworld.onmicrosoft.com",
"Scopes": "access_as_user",
"SignUpSignInPolicyId": "B2C_1_authflow"
},
The Program.cs generated with dotnet new webapi -au IndividualB2C with added cors.
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAdB2C"));
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddCors(o => o.AddPolicy("default", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
}));
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI();
}
else
{
app.UseHttpsRedirection();
}
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
The WeatherForecastController
[Authorize]
[ApiController]
[Route("api/[controller]")]
[RequiredScope(RequiredScopesConfigurationKey = "AzureAd:Scopes")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
And lastly, the user flow
User Flow (B2C_1_authflow)
Possible causes?:
no https as this gave a net::ERR_CERT_AUTHORITY_INVALID
else
{
app.UseHttpsRedirection();
}
Some problem because next.js is a full-stack application? I believe it acts as SPA as I delay the acquiring accessToken untill InteractionStatus.None?
Please check if you need to modify the way of provisioning scope in app settings. Try giving complete scope https://<tenant>/api/<scope>.
{
"AzureAdB2C": {
"Instance": "https://<your-tenant-name>.b2clogin.com",
"ClientId": "<web-app-application-id>",
"Domain": "<your-b2c-domain>",
"SignUpSignInPolicyId": "<your-sign-up-in-policy>"
// "SignedOutCallbackPath": "/signout/<your-sign-up-in-policy>",
},
"TodoList": {
"TodoListScope": "https://contoso.onmicrosoft.com/api/access_as_user openid offline_access",
"TodoListBaseAddress": "https://localhost:44332"
}
}
Also check if app.UseHttpsRedirection(); is to be used after if loop
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
Also please make sure to recheck and give proper redirect url , which has to be same in portal and authorization request. It has to be valid url
Reference:
Configure authentication in a sample web application that calls a web API by using Azure Active Directory B2C | Microsoft Docs

Azure Static Web App Role Functions Not Working

I've made an attempt to get Azure Static Web Apps with customized Roles function to work in my environment just as specified by: https://learn.microsoft.com/en-us/azure/static-web-apps/assign-roles-microsoft-graph
Everything seems to work as expected but when visiting the page restricted by a specific role the API doesn't seem to be assigning the expected role.
I've modified the API and removed all the logic to assign a role to everyone logging in and still doesn't work. Here's the modified code:
const fetch = require('node-fetch').default;
module.exports = async function (context, req) {
const user = req.body || {};
const roles = [];
roles.push('superuser');
context.res.json({
roles
});
}
Here's my staticwebapp.config.json file:
{
"auth": {
"rolesSource": "/api/GetRoles",
"identityProviders": {
"azureActiveDirectory": {
"userDetailsClaim": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",
"registration": {
"openIdIssuer": "https://login.microsoftonline.com/44263d43-a2f0-45a8-8f55-9b100ecfb4dc",
"clientIdSettingName": "AAD_CLIENT_ID",
"clientSecretSettingName": "AAD_CLIENT_SECRET"
},
"login": {
"loginParameters": ["resource=https://graph.microsoft.com"]
}
}
}
},
"routes": [
{
"route": "/secured/*",
"allowedRoles": ["superuser"]
},
{
"route": "/admin/*",
"allowedRoles": ["administrator"]
},
{
"route": "/contributors/*",
"allowedRoles": ["contributor", "Contributor"]
}
],
"responseOverrides": {
"401": {
"redirect": "/.auth/login/aad?post_login_redirect_uri=.referrer",
"statusCode": 302
}
}
}
I've tried changing the order of the config file. My last attempt before posting was to remove all logic and just assign everyone the 'superuser' role.
Everyone can login successfully & pre-defined roles work like a charm but no one ever gets the 'superuser' role.
I'm trying to figure out what I'm doing wrong or has Azure Static Web Apps changed so that this code just won't work like it did a year ago?
Thank you help in advance.

Integrating Sign In with Azure Active Directory in .Net Core

I am trying to integrate sign in option through Azure Active Directory with .net core application. I have been through Microsoft's blogs and I have been to the steps where user can login with Microsoft's account. But the ISSUE is
"It is always redirecting me to the login action method again." which loops me back to sign in screen.
Image for redirect URLS:
My Startup Class
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie()
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
options.Authority = options.Authority + "/v2.0/";
options.TokenValidationParameters.ValidateIssuer = false;
});
My Login account controller
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> Login(string returnUrl)
{
if (User.Identity.IsAuthenticated)
return RedirectToAction("Index", "Search");
var domainInfo = await _subdomainProvider.GetDomainInfoAsync(Request.Host.Value);
if (domainInfo.LoginMethod == LoginMethod.AzureAD)
{
var redirectUrl = Url.Action("Index", "Search");
var properties = _signInManager
.ConfigureExternalAuthenticationProperties(LoginMethod.AzureAD.ToString(), redirectUrl);
return new ChallengeResult(LoginMethod.AzureAD.ToString(), properties);
}
else
{
ViewBag.ReturnUrl = returnUrl;
ViewBag.Background = await GetRandomBackgroundAsync(domainInfo.LoginBackgrounds);
}
return View(new LoginModel
{
Language = GetLanguage(),
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList()
});
}
Login View
<form method="post" asp-controller="Account" asp-action="SignIn" asp-route-returnUrl="#Model.ReturnUrl">
<h2>#AccountStrings.Login_ExternalLogin_Title</h2>
<div>
#foreach (var provider in Model.ExternalLogins)
{
<button type="submit" class="btn login-provider #provider.DisplayName"
name="provider" value="#provider.Name"
title="Log in using your #provider.DisplayName account">
#provider.DisplayName
</button>
}
</div>
</form>
Even added the redirection URL on azure portal to be redirected to action method i-e dashboard.but still didn't work.
Any help would be appreciated. Thank you.
According to my understanding, you want to integrate Azure AD with your .net core web application. If so, please refer to the document and the article
appsettings.json file
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "<you tenant doamin>",
"TenantId": "<>",
"ClientId": "<>",
"CallbackPath": "/signin-oidc"
Add the following code to the startup.cs
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
//services.Configure<AzureADOptions>(options => Configuration.Bind("AzureAd", options));
services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
options.Authority = options.Authority + "/v2.0/";
options.TokenValidationParameters.ValidateIssuer = false;
});
That seems you are using ASP.NET Core Identity with Azure AD login . If that is your scenario , you can set CookieSchemeName to Identity.External so that asp.net core identity can get the external user profile from external identity provider :
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
options.Authority = options.Authority + "/v2.0/";
options.TokenValidationParameters.ValidateIssuer = false;
});
Azure AD application setting :
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "xxx.onmicrosoft.com",
"TenantId": "xxxxxx-xxxxx-4f08-b544-b1eb456f228d",
"ClientId": "xxxxx-xxxxx-4717-9821-e4f718fbece4",
"CallbackPath": "/signin-oidc",
"CookieSchemeName": "Identity.External"
},

Resources